Entries tagged check

Quick and dirty redirect script for the fitting shipping provider

Posted on 2. März 2017 Comments

Another way to use the PHP library shipping-service-provider-check apart from fixing the shipping providers in the ERP Plentymarkets is a simple quick and dirty PHP script that redirects to the tracking page of a fitting shipping provider. You can find the whole sourcecode on GitHub.

Installation

If you don’t use some sort of MVC this is a quick way to do it. If you do, I suspect you’ll know how to alter this example to fit your system. Feel free to write me an e-mail or comment if you need help

  1. Log onto your server and create a folder
  2. Copy or git pull the files, including .htaccess
  3. Get Composer
  4. composer require repat/shipping-service-provider-check

Explanation of the code

The $trackingId variable is received via HTTP GET. This means the URL would be http://url.tld/trackingscriptfolder/script.php?tracking_id=123456 (or without the script.php in case of the .htaccess), where 123456 is the TrackingID. The rest is more or less just for debugging. The scripts returns a HTTP Code 422 and ends if there is no input given.

$trackingId = $_GET["tracking_id"];
if (empty($trackingId)) {
  $unprocessableEntity = 422;
  http_response_code($unprocessableEntity);
  echo "wrong input";
  return;
}

Next the URLs will be defined. The keys have to match the shipping providers so make sure the shipping providers are added at the library as well. The TrackingID will be added at the end of the URL, so make sure they have the right format.

$shippingProviderURLs = [
  "dhl" => 'https://nolp.dhl.de/nextt-online-public/set_identcodes.do?idc=',
...
];

Then follows the documented way of checking for the providers. It could technically be that at the same time a TrackingID is valid for more than one provider. To keep things simple, we’ll just use the first one (array_search instead of array_keys). In case there is none found, array_search returns false and the script continues. In case there is one found, the header() function is called to redirect the user to the correct provider page.

$checkedProvider = array_search(true, $result);
$urlOfCheckedProvider = $shippingProviderURLs[$checkedProvider];

if ($checkedProvider !== false) {
  header('location: ' . $urlOfCheckedProvider . $trackingId);
}

Now it’s up to you what you will do with the ones you can’t redirect. I decided to write a little skeleton.html file and include that with a simple message that the user could try the shipping providers where a check is not possible (no API, no website scraping, no regex). They are listed earlier:

$shippingProviderURLsNoCheck = [
  "DPD" => 'https://tracking.dpd.de/parcelstatus?query=',
...

Herausfinden zu welchem Versanddienstleister eine Tracking ID gehört

Posted on 29. Juli 2016 Comments

Wir hatten erst letztens das Problem, dass wir automatisiert Tracking IDs zugespielt bekommen, die von mehreren Versanddienstleistern stammen könnten. Dies ist z. B. beim ERP Plentymarkets der Fall, wenn man Pakete per FBA verschickt. Allerdings nur, wenn die Aufträge nicht von Amazon kommen, sondern ein sog. Multichannel Auftrag vorliegt, also Amazon nur als Logistiker benutzt wird. In der API Rückmeldung steht zwar m.E. der Versanddienstleister, allerdings implementiert Plentymarkets kein Mapping.

Um den richtigen Provider zu finden, ohne jedes mal alle Websites abzuklappern habe ich das PHP Paket shipping-service-providers-check geschrieben und über composer verfügbar gemacht. Es macht automatisiert genau das. Falls es nicht geht, weil z.B. die Flash oder JavaScript im Spiel sind oder es gar keine öffentliche Seite gibt (->Amazon Logistics), kann die Nummer auch anhand des Formats geprüft werden, also mit einem regulärem Ausdruck.

Theoretisch ist es möglich, dass die Tracking ID gleichzeitig bei mehreren Providern für unterschiedliche Sendungen gültig ist. Das ist zugegebenermaßen extrem unwahrscheinlich. Dennoch gibt mein Paket ein Array von Paketdienstleistern, jeweils mit einem Boolean (true/false), zurück.

Code Erklärung

Die Abhängigkeiten sind fabpot/goutte (ein Website scraper) und danielstjules/stringy (für Stringvergleiche). Da ich von PHPs use function Gebrauch mache, ist PHP Version 5.6 notwendig.

Die Klasse Check enthält neben dem Konstruktur, der die TrackingID erwartet, 3 weitere Methoden.

  • getProviders() – gibt alle Provider zurück
  • checkAll($extraProviders) – gibt das eben erwähnte Array zurück. Das hier ist die eigentlich wichtige öffentliche Methode
  • check() – private, wird in einer Schleife von checkAll() aufgerufen

In der Datei default_providers.php sind in einem Array alle implementierten Versanddienstleister aufgeführt. Hier können auch weitere hinzugefügt werden, bzw. in diesem Format an checkAll() übergeben werden. Jeder Dienstleister hat 3 Parameter:

  • base_url – URL, die goutte zusammen mit der tracking ID aufrufen wird
  • filter – HTML Tag auf der Seite, nach dem gesucht bzw. das durchsucht werden soll
  • search_string  – nach diesem String wird in dem HTML Tag gesucht

Der eigentlich wichtige Teil ist deswegen die Methode checkOnline()

$crawler = $this->client->request('GET', $parameters["base_url"] . $this->trackingId);

in dieser Zeile ruft goutte die vorher definierte base_url mit der Tracking ID auf. Die URL muss deshalb im Format http://example.com?tracking_id= vorliegen. Aus der Tracking ID 123456 lautet dann der Aufruf http://example.com?tracking_id=123456.

$crawler->filter($parameters["filter"])->each(function ($node) use ($parameters) {
            if (s($node->text())->contains($parameters["search_string"])) {
                return true;
            }
            return false;

In dem HTML Tag aus dem filter Parameter wird jetzt nach dem String search_string mittels stringys contains() gesucht. Sollte das der Fall sein, wird true zurückgegeben. Da die Funktion each ein Array zurückgibt und es möglich ist, dass das relevante HTML Tag mehrmals vorkommt, wird danach geguckt ob true in diesem array überhaupt vorkommt, auch wenn andere Einträge in diesem Array eben false sind.

return in_array(true, ...)

Dies wird in einer Schleife in checkAll() durchgegangen:

        foreach ($shippingProviders as $shippingProvider => $parameters) {
            $response[$shippingProvider] = $this->check($parameters);
        }

Außerdem ist es durch folgende Zeile möglich einen Versanddienstleister hinzuzufügen oder zu ersetzen (beides passiert durch array_merge())

  if (isset($shippingProviders)) {
            $shippingProviders = array_merge($defaultShippingProviders, $shippingProviders);
        } else {
            $shippingProviders = $defaultShippingProviders;
        }

Die Methode zum Überprüfen des regulärem Ausdrucks checkFormat() ist denkbar simpel:

  boolval(preg_match($parameters["regex"], $this->trackingId))

Da preg_match 1 zurückgibt, falls der Regex zutrifft, und 0 falls nicht (false wenn ein Fehler aufgetreten ist), muss um das Ergebnis noch boolval().

Die Anleitung zum Benutzen des Pakets ist auf GitHub bzw. Packagist. Zur Zeit des Verfassens dieses Artikels sind die folgenden Versanddienstleister implementiert:

  • DHL
  • GLS
  • UPS
  • Hermes
  • Amazon Logistics

Fedex, DPD und TNT gestalten sich schwierig, da diese Informationen per JavaScript nachladen und goutte das nicht beherrscht. Ggf. werde ich nochmal ein npm Paket mit zombie.js und/oder phantomjs schreiben.

Simple wget crawler for list of files

Posted on 6. August 2015 Comments

This script could be helpful to download a set of files from a webserver, that you don’t have (S)FTP access to. The input file consists of a list of filenames, one name each line.


#!/bin/bash
file=$1
WEBSERVER="http://webserver.tld/folder/"
while IFS= read -r line; do
FULLURL="$WEBSERVER$line"
wget -nc -R --spider $FULLURL
done < "$file"

At first, the first command line argument is saved into the variable file. Then the Webserver address is saved to the WEBSERVER variable. IFS stands for Internal Field Separator. It’s used to read line by line through the file in the while loop that ends in the last line. Inside of the loop, the read line is concatenated with the webserver address into FULLURL. Then, wget is used with the parameters -nc for checking if the file is not already present in the current folder, -R for downloading and –spider for checking the existence on the webserver.

You can find the script on GitHub.

Install ssl-cert-check plugin under SLES11 with Nagios 3.0.6

Posted on 26. Juli 2012 Comments

The guys at prefetch.net already wrote a script for checking if a SSL certificate is still valid: http://prefetch.net/code/ssl-cert-check

The only challenge now is to implement the script into the monitoring tool Nagios, in this case we used a SuSE Linux Enterprise Server 11 and Nagios version 3.0.6.

Nagios 1

To get the little boxes in Nagios green, yellow and red(=Nagios‘ return values) and to receive e-mails in case of an expiration you have to change these 2 parameters in the ssl-cert-check file:

NAGIOS=TRUE
ALARM=TRUE

To match the given form of Nagios plugins we renamed the file to check_ssl-cert and then moved it to /usr/lib/nagios/plugins, where the rest of the plugins are.

For Nagios to recognize the plugin it has to be defined in /etc/nagios/objects/commands.cfg (NOT /etc/nagios/commands.cfg):

define command {
command_name check_ssl-cert
command_line /usr/lib/nagios/plugins/check_ssl-cert -s $HOSTADDRESS$ -p 443 -e $ARG1$
}

The port is usually the same for the same service. If it’s not port 443 for every server, you can also define the port as the second parameter in the next step. Of course, instead of -p 443 it has to be -p $ARG2$.

You now have to add the configuration of the plugin in /etc/nagios/conf.d/services.cfg. In this case, the hostgroup „all“ is selected, but if you have different hostgroups, the admin who has to get the e-mail might be different. The parameters go after the exclamation mark, comments begin with the semicolon.

define service {
hostgroup_name all
service_description ssl-certs
check_command check_ssl-cert!mail@example.org
use generic-service
notification_interval 0 ; set > 0 if you want to be renotified
}

 

If an ssl-cert is expired, it looks like this:
Nagios 2
Credits go to the Alex and the other guys at the CentOS mailing list: