Posts Tagged ‘API’

Samstag, 14. Oktober 2017

upc cablecoms Verfügbarkeitsabfrage ist äusserst geschwätzig

upc cablecom bietet auf ihrer Web-Site die Möglichkeit, eine Wohnadresse auf die Verfügbarkeit von upc-Produkten zu überprüfen:

Verfügbarkeit prüfen

Füllt man die erforderlichen Angaben in das Formular ein, erhält man eine rein binäre Antwort für jede der drei Produktkategorien Internet, TV und Festnetz:

image-7498

Im Hintergrund setzt dafür JavaScript eine Abfrage auf eine upc API ab. Die URL lautet für das vorliegende Beispiel:

https://www.upc.ch/aff-upc-cablecom-ch/aav/availability.json?streetName=Schl%C3%B6sslistrasse&streetNumber=39&postalCode=3008&_charset_=UTF-8&lang=de

Als Antwort erhält man eine Datei namens availability.json zurück. Nachfolgend das Beispiel für meine Wohnadresse:

{
    "addressResultState": "uniqueAddress",
    "addresses": [
        {
            "buildingNumber": 39,
            "buildingNumberAnnex": null,
            "buildingStatusId": 3,
            "buildingStatusName": "completed",
            "communeName": "Bern",
            "coordinateX": "599190",
            "coordinateY": "199475",
            "countryCodeA2": "CH",
            "idBuilding": 131767,
            "locationName1": "Bern",
            "locationName2": "Bern",
            "networkOperatorId": 0,
            "postCode": "3008",
            "postCodeAnnex": "00",
            "postOfficeName": "Bern",
            "stateName": "Bern/Berne",
            "stateShort": "BE",
            "streetName1": "Schl\u00f6sslistrasse"
        }
    ],
    "availability": {
        "accessProvider": null,
        "accessTechnology": null,
        "cablecomRegion": "Nord-West",
        "catv": {
            "available": true,
            "houseUpgradeNeeded": false,
            "packages": {
                "_package": [
                    "not available"
                ]
            },
            "partnerNetFlag": false
        },
        "dp": {
            "available": true,
            "availableFrom": {
                "day": 5,
                "fractionalSecond": 0.0,
                "hour": 0,
                "minute": 0,
                "month": 9,
                "second": 0,
                "timezone": 120,
                "year": 2000
            },
            "houseUpgradeNeeded": false,
            "packages": {
                "_package": [
                    "RVO_VSB01",
                    "RVO_VSB02",
                    "RVO_VSB03",
                    "RVO_VSB04",
                    "RVO_VSB05",
                    "RVO_FRC1",
                    "RVO_GBL1",
                    "RVO_FCG1",
                    "RVO_FRC2",
                    "RVO_GBL2",
                    "RVO_FCG2",
                    "RVO_FCE1",
                    "RVO_FCE2",
                    "RVO_FPW1",
                    "RVO_FPW2",
                    "RVO_FPS1",
                    "RVO_FPS2",
                    "RVO_FPP1",
                    "RVO_FPP2",
                    "RVO_BP1",
                    "RVO_BDS13",
                    "RVO_BDS14",
                    "RVO_BDS08",
                    "RVO_BDS11",
                    "RVO_BDS09",
                    "RVO_BDS12"
                ]
            },
            "partnerNetFlag": false
        },
        "dtv": {
            "available": true,
            "availableFrom": {
                "day": 1,
                "fractionalSecond": 0.0,
                "hour": 0,
                "minute": 0,
                "month": 1,
                "second": 0,
                "timezone": 60,
                "year": 1999
            },
            "houseUpgradeNeeded": false,
            "packages": {
                "_package": [
                    "",
                    "NR_SVD01",
                    "RDC_SFRSD",
                    "RDC_SFRS_M",
                    "RDI_CH01",
                    "RDI_CH04",
                    "RDI_CH05",
                    "RDI_CH06",
                    "RDI_CH07",
                    "RDI_CH08",
                    "RDI_CH09",
                    "RDI_CH09",
                    "RDI_CH10",
                    "RDI_CH11",
                    "RDI_CH17",
                    "RDI_CH17H",
                    "RDI_CH18",
                    "RDI_CH18H",
                    "RDI_CH19",
                    "RDI_CH19H",
                    "RDI_CH20",
                    "RDI_CH20H",
                    "RDI_CH21",
                    "RDI_CH21",
                    "RDI_CH21_M",
                    "RDI_CH21_M",
                    "RDI_CH22",
                    "RDI_CH22_M",
                    "RDI_CH24",
                    "RDI_CH24_M",
                    "RDI_CH25",
                    "RDI_CH25_M",
                    "RDI_CH26",
                    "RDI_CH26_M",
                    "RDI_CH27",
                    "RDI_CH27_M",
                    "RDI_CH28",
                    "RDI_CH28_M",
                    "RDI_CH30",
                    "RDI_CH31",
                    "RDI_CH32",
                    "RDI_CH33",
                    "RDI_CH40",
                    "RDI_CH40_M",
                    "RDI_CH41",
                    "RDI_CH41",
                    "RDI_CH42",
                    "RDI_CH44",
                    "RDI_CH47",
                    "RDI_CH47",
                    "RDI_CH48",
                    "RDI_CH49",
                    "RDI_CH50",
                    "RDI_CH51",
                    "RDI_CH52",
                    "RDI_CH53",
                    "RDI_CH54",
                    "RDI_CH55",
                    "RDI_CH56",
                    "RDI_CH57",
                    "RDI_CH59",
                    "RDI_CH60",
                    "RDI_CH61",
                    "RDI_CH62",
                    "RDI_CH65",
                    "RDI_CH66",
                    "RDI_CH67",
                    "RDI_CH68",
                    "RDI_CH72",
                    "RDI_CH73",
                    "RDI_CH74",
                    "RDI_CH81",
                    "RDI_CH93",
                    "RDI_CH97_M",
                    "RDI_D4A_97",
                    "RDI_DUMW",
                    "RDI_DWISR1",
                    "RDI_DWISS1",
                    "RDI_DWR1",
                    "RDI_DWS1",
                    "RDI_HCOD",
                    "RDI_HRZ06",
                    "RDI_HRZ11",
                    "RDI_HRZ17",
                    "RDI_HRZ17",
                    "RDI_CH81",
                    "RDI_HRZ17H",
                    "RDI_HRZ81",
                    "RDI_HRZ18",
                    "RDI_HRZ18H",
                    "RDI_HRZ19",
                    "RDI_HRZ19H",
                    "RDI_HRZ20",
                    "RDI_HRZ20H",
                    "RDI_HRZ21",
                    "RDI_HRZ21",
                    "RDI_HRZ22",
                    "RDI_HRZ24",
                    "RDI_HRZ25",
                    "RDI_HRZ26",
                    "RDI_HRZ27",
                    "RDI_HRZ28",
                    "RDI_HRZ40",
                    "RDI_HRZ52",
                    "RDI_HRZ53",
                    "RDI_HRZ83",
                    "RDI_HRZCL",
                    "RDI_HRZCO",
                    "RDI_HRZDS",
                    "RDI_HRZ_97",
                    "RDI_PREM1",
                    "RDI_PREM2",
                    "RDI_PREM_M",
                    "RDI_PRM",
                    "RDI_PRMM",
                    "RDI_SPTV",
                    "RDI_SPTV_M",
                    "RDI_SVD_51",
                    "RDI_SVD_51",
                    "RDI_SVD_51",
                    "RDI_SVD_52",
                    "RDI_SVD_52",
                    "RDI_SVD_52",
                    "RDI_SVD_59",
                    "RDI_SVD_60",
                    "RHZ_CLAS7",
                    "RHZ_CLAS8",
                    "RHZ_PREM1",
                    "RHZ_PREM2",
                    "RHZ_PRM",
                    "RHZ_SFRSH",
                    "RHZ_SPTV",
                    "RDI_CTDV",
                    "RDI_DUMS",
                    "RDI_DUMM"
                ]
            },
            "partnerNetFlag": false
        },
        "dtvActicationCode": "203",
        "dtvDistributionModel": "Vertriebsmodell Cablecom",
        "dtvSetupId": "01810000",
        "ftthBuildingStatus": null,
        "ftthSla": null,
        "hs": {
            "available": true,
            "availableFrom": {
                "day": 5,
                "fractionalSecond": 0.0,
                "hour": 0,
                "minute": 0,
                "month": 9,
                "second": 0,
                "timezone": 120,
                "year": 2000
            },
            "houseUpgradeNeeded": false,
            "packages": {
                "_package": [
                    "DHS_BSO",
                    "RHS_BDS06",
                    "RHS_BDS07",
                    "RHS_BDS08",
                    "RHS_BDS09",
                    "RHS_BDS10",
                    "RHS_BDS11",
                    "RHS_BDS12",
                    "RHS_BDS13",
                    "RHS_BDS14",
                    "RHS_BDS15",
                    "RHS_BDS16",
                    "RHS_BDS17",
                    "RHS_BDS18",
                    "RHS_BDS20",
                    "RHS_BDS21",
                    "RHS_HC256",
                    "RHS_HS02",
                    "RHS_HS05",
                    "RHS_HS06",
                    "RHS_HS08",
                    "RHS_HS09",
                    "RHS_HS11",
                    "RHS_HS12",
                    "RHS_HS13",
                    "RHS_HS14",
                    "RHS_HS15",
                    "RHS_HS16",
                    "RHS_HS17",
                    "RHS_HSED13",
                    "RHS_HSED21",
                    "RHS_HSED30",
                    "RHS_HSED32",
                    "RHS_NDH25",
                    "RHS_HSED10",
                    "RHS_HSED11",
                    "RHS_HSED12",
                    "RHS_HSED14",
                    "RHS_HSED15",
                    "RHS_HSED16",
                    "RHS_HSED17",
                    "RHS_HSED18",
                    "RHS_HSED19",
                    "RHS_HSED20",
                    "RHS_HSED22",
                    "RHS_HSED23",
                    "RHS_HSED24",
                    "RHS_HSED25",
                    "RHS_HSED26",
                    "RHS_HSED28",
                    "RHS_HSED29",
                    "RHS_WOO"
                ]
            },
            "partnerNetFlag": false
        },
        "idBuilding": 131767,
        "languageRegion": "DE",
        "longText": "An Ihrem Standort ist bereits alles vorbereitet. Melden Sie sich jetzt online an und schon in wenigen Tagen k\u00f6nnen Sie vom gew\u00fcnschten Produkt profitieren.",
        "mobile": {
            "available": true,
            "houseUpgradeNeeded": false,
            "packages": {
                "_package": [
                    "ALL"
                ]
            },
            "partnerNetFlag": false
        },
        "vod": {
            "available": true,
            "houseUpgradeNeeded": false,
            "packages": {
                "_package": [
                    "BM_VODKIT"
                ]
            },
            "partnerNetFlag": false
        }
    },
    "availabilityResultState": "availabilityFound"
}

(Lesbar gemacht mit Google Chrome unter die Haube schauen (und JSON lesbar ausgeben))

Einige Erkenntnisse:

  • Diese API rechnet Strassenanschriften ins Schweizer Koordinatensystem um (600:200, irgendjemand?).
  • Das JSON sagt auch, wann das Gebäude an das cablecom-Netz angeschlossen wurde (Internet am 5. September 2000, Fernsehen am 1. Januar 1999 (wahrscheinlich ein Dummy-Wert, oder aber cablecom hat zu dem Stichtag das Berner Kabelnetz übernommen?)).
  • Benötigt mein Gebäude ein Upgrade? Aus meiner Sicht ein möglicher Hinweis auf Probleme in der Hausverkabelung und somit auf mögliche Geschwindigkeitseinbussen.
  • Es gibt drei Produktekategorien: dtv steht für Digital TV, hs steht für Highspeed (Internet) und dp wohl für Digital Phone.
  • Für jede Produktkategorie wird fein säuberlich aufgelistet, welche Packages verfügbar sind. Leider ist es mir nicht möglich, die Abkürzungen dieser Packages zu entziffern. Bei Digital TV vermute ich, dass einzelne Sender aufgelistet werden. Bei Highspeed Internet könnten es die effektiv verfügbaren Geschwindigkeiten sein.
  • Im JSON sind auch der Activation Code und die Setup ID aufgeführt, die man auf der Horizon-Box oder dem TV-Gerät für die Kanalsuche eingeben muss.
  • Schlussendlich sieht man auch, ob ein Gebäude an das (upc?) Glasfasernetz angeschlossen ist.

Tags: , , , , , ,
Labels: IT, Schweiz, Shopping

Keine Kommentare | neuen Kommentar verfassen

Donnerstag, 13. November 2014

Google Maps in eigene Web-Site integrieren

Damit man Google Maps-Karten in die eigene Web-Site integrieren kann, benötigt man ein Google-Konto und Zugriff auf die Google Developers Console.

Dort findet man im Menupunkt APIs & Auth in der Unterrubrik APIs die „Google Maps Embed API“, welche man dort auch gleich für die Verwendung aktiviert.

Um Missbrauch zu verhindern, sollte man zudem im Menupunkt Credentials unter Public API Access einen API Key für die Google Maps Embed API erstellen und bei Referers dann die Domainnamen erfassen, von welchen die Requests für Kartendaten kommen dürfen (Referer lassen sich selbstverständlich fälschen, aber ich gehe davon aus, dass Google Gegenmassnahmen in seinen serverseitigen Embed-Code eingebaut hat).

Auf der eigenen Web-Site fügt man dann das iFrame beispielsweise folgendermassen ein:

<iframe
  width="850"
  height="550"
  frameborder="0"
  style="border:0"
  class="map"
  src="https://www.google.com/maps/embed/v1/place?key=%ApiKey%&q=Bern+Switzerland&zoom=10">
</iframe>

Quelle: Google Maps Embed API

Tags: , , , , , ,
Labels: Web

Keine Kommentare | neuen Kommentar verfassen

Mittwoch, 18. Dezember 2013

Den Netatmo PHP API-Client mit weniger strikten SSL-Anforderungen patchen

Vor einigen Tagen hörte mein Raspberry Pi-Dashboard auf, die Werte meiner Netatmo NWS01 Wetterstation für Apple iPhone und Android anzuzeigen.

Auf meinem lokalen Mac funktionierte das Dashboard hingegen problemlos; d.h. ich konnte mittels dem Netatmo PHP API-Client die JSON-Datei mit den aktuellen Messwerten wie Temperatur, Luftdruck und -feuchtigkeit abrufen.

Die genaue Ursache hinter dem Problem kenne ich bis heute nicht, doch ich vermute mit dem jetzigen Wissensstand, dass die Cyon-Ingenieure an der Konfiguration ihrer Server herumgewerkelt haben und dabei unter anderem das Root-Zertifikat entfernt haben, welches der Netatmo API-Client zur HTTPS-verschlüsselten Kommunikation mit den Netatmo-Servern verwendet.

Nachdem ich nämlich die Exception mittels vardump() genauer betrachtete, welche NACurlErrorType zurücklieferte, war der Fall schnell sonnenklar:

...
[message:protected] => SSL peer certificate or SSH remote key was not OK
...

Nun … gut! Was macht man da? Ich habe die Datei NAApiClient.php gepatcht, indem ich cURL mit der auf false gesetzten Option CURLOPT_SSL_VERIFYHOST sage, unverifizierte SSL-Zertifikate kommentarlos zu akzeptieren:

...
        else 
        {
            $opts[CURLOPT_HTTPHEADER] = array('Expect:');
        }
        
        $opts[CURLOPT_SSL_VERIFYHOST] = false;
        
        curl_setopt_array($ch, $opts);
...

Bei einer API wie Netatmo ist diese manuell herbeigeführte Schwachstelle zu verantworten. Ginge es um Mailverkehr oder Online-Banking, würde ich eine solche Option definitiv nicht aktivieren.

Tags: , , , , , , , ,
Labels: Programmierung

Keine Kommentare | neuen Kommentar verfassen

Samstag, 22. Juni 2013

Auf Twitter API 1.1 wechseln

Am 11. Juni wurden die in meinem Dashboard eingebundenen Twitter-Feeds plötzlich still. Der Grund: Twitter hat an diesem Tag API 1.0 deaktiviert und macht es seither Entwicklern und Script-Kiddies schwer, mit wenigen Zeilen Code auf öffentliche Twitter-Feeds zuzugreifen.

Wer vor dem selben Problem wie ich steht, sei hier eine kurze Anleitung präsentiert, um die Grundfunktionalität wieder online zu schalten:

Ich habe mich für die PHP-Klasse Codebird entschieden, da ich keine Lust hatte, OAuth-Requests und sonstigen Firlefanz auf eigene Faust zu programmieren.

Zuerst eröffnet man über den offiziellen Entwicklungsbereich mit dem persönlichen Twitter-Konto eine neue Twitter-Applikation. Wichtig ist, dass man sich den Consumer Key und das Consumer Secret merkt, denn diese beiden Variablen werden von der Klasse zur Kommunikation mit Twitter benötigt — authentifizieren sie doch die Applikation gegenüber dem Kurznachrichtendienst.

Nachdem man codebird.php sowie — ganz wichtig — cacert.pem in einem Unterverzeichnis des Web-Roots abgelegt hat, integriert man die Klasse in die bestehen Infrastrukutur:

        function __construct() {
            parent::__construct();
            
            require_once(dirname(__FILE__) . '/twitter/codebird.php');
            \Codebird\Codebird::setConsumerKey('AAAAAAAAAAAAAAAAAAAAA', 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAA');
            $this->cb = \Codebird\Codebird::getInstance();
        }

Als nächstes benötigt man einen sog. Bearer Token. Einmal generiert kann dieser für jeden weiteren Request an die Twitter API wiederverwendet werden — sofern man den Token nicht manuell deaktiviert. Alternativ kann man diesen Token auch bei jedem Aufruf des PHP-Scripts neu von Twitters Server abholen, was aber nicht einer guten Entwicklungspraxis (Cacheing!) entspricht.

Den Bearer Token erhält man in etwa folgendermassen:

$reply = $this->cb->oauth2_token();
$bearerToken = $reply->access_token;
\Codebird\Codebird::setBearerToken($bearerToken);

Jetzt also ist man wie mit API 1.0 in der Lage, eine simple Abfrage abzusetzen — im vorliegenden Fall rufe ich die letzten Tweets von John Gruber ab:

$this->cb->setReturnFormat(CODEBIRD_RETURNFORMAT_JSON);
$jsonData = $this->cb->statuses_userTimeline(array('screen_name' => 'daringfireball','count' => 25),true); // 'true' is needed for app only auth

Damit die Kompatibilität von bestehendem Code mit der neuen Klasse gewahrt wird, nenne ich JSON explizit als Antwortformat. Ganz wichtig ist, dass die Codebird-Methode als zweiten Paramenter true übergeben erhält — dies weist die Klasse an, die Anfrage im Kontext einer Applikation und nicht eines bestimmten Benutzers abzusetzen.

Tags: , , , , , ,
Labels: Web

Keine Kommentare | neuen Kommentar verfassen