Ta strona używa ciasteczek (cookies), dzięki którym nasz serwis może działać lepiej. Dowiedz się więcej OK, rozumiem
WebHelp.pl Warsztat Artykuły Korzystanie z Goo.gl API

Warsztat / Artykuły i tutoriale

Korzystanie z Goo.gl API

Rafał Kukawski 15 stycznia 2011 komentarze ()

Od kilku miesięcy można korzystać ze skracacza adresów od Google. Do szczęścia niektórym brakowało tylko interfejsu programistycznego dla aplikacji. Google wysłuchał próśb i udostępnił testową wersję API do skracania adresów.

Pierwsza wersja API jest bardzo prosta. Udostępnia tylko 3 podstawowe funkcje - skracania URL, odpytywania pełnego adresu dla danego skrótu, listowania skrótów powiązanych z danym kontem.

Zachęcam do zapoznania się ze szczegółami.

Klucz

Aby móc swobodnie korzystać z API, Google wymaga od nas podania klucza (API key), w przeciwnym wypadku aplikacja będzie miała narzucone spore ograniczenia w korzystaniu z API.

Aby uzyskać klucz, należy przejść do Google APIs Console, utworzyć nowy projekt, aktywować API skracania linków i skopiować podany tam klucz.

Klucz dodajemy do każdego żądania jako parametr key w adresie, np. https://www.googleapis.com/urlshortener/v1/url?key=TUTAJ_WKLEJAMY_KLUCZ&shortUrl=http://goo.gl/vsxwi.

Skracanie adresów

Najważniejszą funkcją API jest oczywiście skracanie adresów. Aby utworzyć nowy skrót należy wykonać żądanie POST do adresu https://www.googleapis.com/urlshortener/v1/url.

Treścią żądania powinien być string w formacie JSON zawierający adres do skrócenia.

Kod: Zaznacz cały
{"longUrl": "http://blog.kukawski.pl"}

Ważne jest, żeby żądania zawierające dane w formacie JSON miały ustawiony nagłówek Content-Type: application/json

Przykładowy kod w PHP tworzący skrót może wyglądać następująco

Kod: Zaznacz cały
<?php
function createShortcut ($url) {
    $ch = curl_init();
    curl_setopt_array($ch, array(
        CURLOPT_URL => 'https://www.googleapis.com/urlshortener/v1/url', // URL usługi
        CURLOPT_RETURNTRANSFER => true,
        CURLOPT_POST => true, // ustawiamy typ żądania na POST
        CURLOPT_HEADER => false,
        CURLOPT_POSTFIELDS => json_encode(array('longUrl' => $url)), // dane wysyłane do usługi w formacie JSON
        CURLOPT_HTTPHEADER => array('Content-Type: application/json') // wymagane nagłówki
    ));

    $response = curl_exec($ch);
    $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
    $result = $response;
    curl_close($ch);
    
    return $result;
}
var_dump(createShortcut('http://blog.kukawski.pl'));
?>

Odpowiedź, którą powinniśmy otrzymać również będzie w formacie JSON i będzie zawierać utworzony skrót.

Kod: Zaznacz cały
string(102) "{
 "kind": "urlshortener#url",
 "id": "http://goo.gl/vsxwi",
 "longUrl": "http://blog.kukawski.pl/"
}
"

Wystarczy użyć funkcji json_decode, aby skonwertować odpowiedź do łatwiejszego w operowaniu typu danych.

Odszyfrowywanie skrótów

Gdy znany jest nam skrót adresu w usłudze Goo.gl, można w prosty sposób rozwinąć go do pełnego, oryginalnego adresu.

Gdy wyślemy zapytanie GET do adresu https://www.googleapis.com/urlshortener/v1/url?shortUrl=http://goo.gl/vsxwi w rezultacie otrzymamy JSON zawierający pełny adres.

Kod: Zaznacz cały
string(116) "{
 "kind": "urlshortener#url",
 "id": "http://goo.gl/vsxwi",
 "longUrl": "http://blog.kukawski.pl/",
 "status": "OK"
}
"

Pole status może mieć wartości OK, MALWARE, PHISHING lub REMOVED.

API definiuje dodatkowy parametr projection, który pozwoli uzyskać jeszcze więcej danych - szczególnie o charakterze statystycznym - na temat adresu, jeśli te są dostępne. Obsługiwanymi wartościami są FULL, ANALYTICS_CLICKS, ANALYTICS_TOP_STRINGS.

Przykładowe wywołanie

Kod: Zaznacz cały
file_get_contents('https://www.googleapis.com/urlshortener/v1/url?shortUrl=http://goo.gl/vsxwi&projection=FULL');

może zwrócić

Kod: Zaznacz cały
string(2045) "{
 "kind": "urlshortener#url",
 "id": "http://goo.gl/vsxwi",
 "longUrl": "http://blog.kukawski.pl/",
 "status": "OK",
 "created": "2011-01-11T20:49:46.160+00:00",
 "analytics": {
  "allTime": {
   "shortUrlClicks": "2",
   "longUrlClicks": "2",
   "referrers": [
    {
     "count": "2",
     "id": "Unknown/empty"
    }
   ],
   "countries": [
    {
     "count": "2",
     "id": "DE"
    }
   ],
   "browsers": [
    {
     "count": "2",
     "id": "Firefox"
    }
   ],
   "platforms": [
    {
     "count": "2",
     "id": "Windows"
    }
   ]
  },
  "month": {
   "shortUrlClicks": "2",
   "longUrlClicks": "2",
   "referrers": [
    {
     "count": "2",
     "id": "Unknown/empty"
    }
   ],
   "countries": [
    {
     "count": "2",
     "id": "DE"
    }
   ],
   "browsers": [
    {
     "count": "2",
     "id": "Firefox"
    }
   ],
   "platforms": [
    {
     "count": "2",
     "id": "Windows"
    }
   ]
  },
  "week": {
   "shortUrlClicks": "2",
   "longUrlClicks": "2",
   "referrers": [
    {
     "count": "2",
     "id": "Unknown/empty"
    }
   ],
   "countries": [
    {
     "count": "2",
     "id": "DE"
    }
   ],
   "browsers": [
    {
     "count": "2",
     "id": "Firefox"
    }
   ],
   "platforms": [
    {
     "count": "2",
     "id": "Windows"
    }
   ]
  },
  "day": {
   "shortUrlClicks": "2",
   "longUrlClicks": "2",
   "referrers": [
    {
     "count": "2",
     "id": "Unknown/empty"
    }
   ],
   "countries": [
    {
     "count": "2",
     "id": "DE"
    }
   ],
   "browsers": [
    {
     "count": "2",
     "id": "Firefox"
    }
   ],
   "platforms": [
    {
     "count": "2",
     "id": "Windows"
    }
   ]
  },
  "twoHours": {
   "shortUrlClicks": "2",
   "longUrlClicks": "2",
   "referrers": [
    {
     "count": "1",
     "id": "Unknown/empty"
    }
   ],
   "countries": [
    {
     "count": "1",
     "id": "DE"
    }
   ],
   "browsers": [
    {
     "count": "1",
     "id": "Firefox"
    }
   ],
   "platforms": [
    {
     "count": "1",
     "id": "Windows"
    }
   ]
  }
 }
}
"

Warto zauważyć, że data utworzenia skrótu jest zwracana wyłącznie w opcji FULL.

Listowanie adresów

Ostatnią z funkcji API jest możliwość wylistowania wszystkich skrótów powiązanych z kontem użytkownika (aplikacji). Aby móc odpytać serwer o tę listę należy być autoryzowanym do wykonania tej czynności.

W celu uzyskania listy adresów wykonujemy żądanie GET do https://www.googleapis.com/urlshortener/v1/url/history?start-token={startToken?}&projection={projection?}

Parametr projection może przyjąć wartość FULL lub ANALYTICS_CLICKS.

Parametr startToken służy do obsługi paginacji wyników. Aby otrzymać kolejną stronę wyników, należy w nowym żądaniu przekazać token otrzymany w poprzednim żądaniu.

Ciekawostka

Interfejs skracacza adresów zawiera w sobie pewną niespodziankę. Jeśli skrócony adres uzupełnimy o rozszerzenie .qr, zostanie dla nas wygenerowany kod QR z zakodowanym adresem.

Kod: Zaznacz cały
<img src="http://goo.gl/fbsS.qr"/>

Kod QR dla skrótu "fbsS"

Klasa do obsługi Goo.gl

Poniżej przedstawiam prostą klasę, która pozwoli tworzyć skróty i pobierać statystyki na ich temat.

Kod: Zaznacz cały
<?php

/**
 * Klasa do pracy z API usługi skracania adresów Goo.gl
 *
 * @author Rafał Kukawski <rafael@webhelp.pl>
 * @license http://kukawski.pl/mit-license.txt MIT License
 * @link http://webhelp.pl/artykuly/korzystanie-z-goo-gl-api/
 * @version 0.9
 */
class Googl {
    /**
     * Adres usługi Goo.gl
     *
     * @static
     */
    const GOOGL_URL = 'https://www.googleapis.com/urlshortener/v1/url';

    /**
     * Przekaż stałą do metody expandShortcut jeśli nie potrzebujesz statystyk
     *
     * @static
     * @see expandShortcut()
     */
    const ANALYTICS_NONE = '';

    /**
     * Przekaż stałą do metody expandShortcut jeśli interesują cię statystyki kliknięć
     *
     * @static
     * @see expandShortcut()
     */
    const ANALYTICS_CLICKS = 'ANALYTICS_CLICKS';

    /**
     * Przekaż stałą do metody expandShortcut jeśli interesują cię statystyki
     *  odnośnie refererów, przeglądarek i platform systemowych
     *
     * @static
     * @see expandShortcut()
     */
    const ANALYTICS_TOP_STRINGS = 'ANALYTICS_TOP_STRINGS';

    /**
     * Przekaż stałą do metody expandShortcut jeśli interesują cię
     *  wszystkie statystyki powiązane ze skrótem
     *
     * @static
     * @see expandShortcut()
     */
    const ANALYTICS_FULL = 'FULL';

    /**
     * Klucz API użytkownika powiązany z usługą Goo.gl
     * 
     * @var string
     */
    private $apiKey;

    public function  __construct ($apiKey = null) {
        if (is_string($apiKey)) {
            $this->apiKey = $apiKey;
        }
    }

    /**
     * Tworzy skrót dla podanego adresu
     * 
     * @param string $url Adres URL do skrócenia
     *
     * @return string Skrót adresu
     *
     * @throws InvalidArgumentException
     *      gdy parametr metody nie jest poprawnym adresem URL z protokołem HTTP lub HTTPS
     *
     * @throws GooglNetworkException
     *      gdy wystąpił problem z wykonaniem żądania
     * 
     * @throws GooglServiceException
     *      gdy usługa Goo.gl zwróciła błąd
     */
    public function createShortcut ($url) {
        if (!$this->isUrl($url)) {
            throw new InvalidArgumentException("Valid HTTP or HTTPS URL expected");
        }

        $googlUrl = self::GOOGL_URL;
        
        if ($this->apiKey !== null) {
            $googlUrl .= '?key=' . $this->apiKey;
        }
        
        $content = array('longUrl' => $url);
        $headers = array('Content-type: application/json', 'Accept: application/json');

        $result = $this->makeJsonRequest($googlUrl, 'POST', $content, $headers);

        return $result['id'];
    }

    /**
     * Pobiera pełny adres dla podanego skrótu oraz opcjonalnie pobiera statystyki powiązane ze skrótem
     *
     * @param string $url Skrót, który chcemy rozszyfrować
     * @param string $includeAnalytics Typ statystyk, które chcemy pobrać
     *
     * @return array Tablica zawierająca pełny adres oraz opcjonalnie statystyki
     *
     * @throws GooglNetworkException
     *      gdy wystąpił błąd podczas wysyłania żądania
     *
     * @throws GooglServiceException
     *      gdy usługa Goo.gl zwróciła błąd
     *
     * @see Googl::ANALYTICS_NONE
     * @see Googl::ANALYTICS_FULL
     * @see Googl::ANALYTICS_CLICKS
     * @see Googl::ANALYTICS_TOP_STRINGS
     */
    public function expandShortcut ($shortcut, $includeAnalytics = '') {
        if (!$this->isUrl($shortcut)) {
            throw new InvalidArgumentException("Valid HTTP or HTTPS URL expected");
        }
        
        $googlUrl = self::GOOGL_URL . '?shortUrl=' . urlencode($shortcut);

        if ($this->apiKey !== null) {
            $googlUrl .= '&key=' . $this->apiKey;
        }

        if (in_array($includeAnalytics, array(self::ANALYTICS_FULL, self::ANALYTICS_CLICKS, self::ANALYTICS_TOP_STRINGS))) {
            $googlUrl .= '&projection=' . $includeAnalytics;
        }

        $headers = array('Accept: application/json');

        $result = $this->makeJsonRequest($googlUrl, 'GET', null, $headers);

        return $result;
    }

    /**
     * Sprawdza czy podana wartość jest poprawnym URLem z protokołem HTTP lub HTTPS
     *
     * @param string $url URL do sprawdzenia
     *
     * @return bool
     */
    public function isUrl ($url) {
        // TODO: ulepszyć walidację, szczególnie zastąpić filter_var, która ma spore ograniczenia
        return filter_var($url, FILTER_VALIDATE_URL, FILTER_FLAG_SCHEME_REQUIRED) == $url && preg_match('/^https?$/i', parse_url($url, PHP_URL_SCHEME));
    }

    /**
     * Pobiera dane z usługi i je parsuje
     *
     * @param string $url URL zasobu do odpytania
     * @param string $method Metoda żądania - GET lub POST
     * @param mixed $content Treść, którą chcemy wysłać z żądaniem
     * @param array $headers Dodatkowe nagłówki HTTP do wysłania
     *
     * @return array
     *
     * @throws GooglNetworkException
     *          gdy odebrane dane nie są poprawnym JSONem
     *
     * @throws GooglServiceException
     *          gdy odpowiedź usługi Goo.gl zawiera klucz error
     * @see sendRequest()
     */
    protected function makeJsonRequest ($url, $method = 'GET', $content = null, $headers = null) {
        list($rawResponse, $httpCode) = $this->sendRequest($url, $method, json_encode($content), $headers);

        $data = json_decode($rawResponse, true);

        // gdy odpowiedź nie jest poprawnym JSONem przyjmujemy, że to problem sieciowy
        if ($data === null) {
            throw new GooglNetworkException();
        } else if (isset($data['error']) || $httpCode !== 200) {
            throw new GooglServiceException($data);
        } else {
            return $data;
        }
    }

    /**
     * Wykonuje zapytanie HTTP do podanego URL i pobiera wynik
     *
     * @param string $url URL do odpytania
     * @param string $method Metoda żądania HTTP. Obsługiwane są GET i POST.
     * @param mixed $body Treść, którą wysyłamy z żądaniem.
     *                      Może być tekstem bądź tablicą z parami klucz-wartość
     * @param array $headers Dodatkowe nagłówki do wysłania z żądaniem
     *                      np. array('Content-Type: application/json')
     * @return array
     *          Treść odpowiedzi i kod odpowiedzi
     * 
     * @throws GooglNetworkException
     *          gdy wykonanie żądania HTTP zawiodło
     */
    protected function sendRequest ($url, $method = 'GET', $body = null, $headers = null) {
        $ch = curl_init();
        $options = array(
            CURLOPT_URL => $url,
            CURLOPT_RETURNTRANSFER => true,
            CURLOPT_POST => $method === 'POST',
            CURLOPT_SSL_VERIFYPEER => false,
            CURLOPT_SSL_VERIFYHOST => 2,
            CURLOPT_SSLVERSION => 3,
            CURLOPT_HEADER => false
        );

        if (is_array($headers)) {
            $options[CURLOPT_HTTPHEADER] = $headers;
        }

        if ($options[CURLOPT_POST] && (is_string($body) || is_array($body))) {
            $options[CURLOPT_POSTFIELDS] = $body;
        }

        curl_setopt_array($ch, $options);

        $response = curl_exec($ch);
        $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
        $error = curl_error($ch);
        curl_close($ch);
        unset($ch);

        if ($response === false) {
            throw new GooglNetworkException($error);
        }

        return array($response, $httpCode);
    }
}

/**
 * Wyjątek wyrzucany, gdy usługa odpowie komunikatem o błędzie
 */
class GooglServiceException extends Exception {
    private $data;

    public function  __construct($data = null) {
        $this->data = $data;

        parent::__construct($data['error']['message']);
    }

    public function getData () {
        return $this->data;
    }
}

/**
 * Wyjątek wyrzucany, gdy nie uda się wykonać żądania HTTP
 */
class GooglNetworkException extends Exception {}
?>

Kilka przykładów, jak korzystać z klasy

Kod: Zaznacz cały
<?php
$g = new Googl();
try {
    $shortcut = $g->createShortcut('http://blog.kukawski.pl');
    echo $shortcut;
} catch (Exception $e) {}


try {    
    $details = $g->expandShortcut('http://goo.gl/vsxwi', Googl::ANALYTICS_FULL);
    echo $details['created'];
} catch (Exception $e) {}
?>

Masz pytania lub wątpliwości? Odwiedź nasze forum dyskusyjne.

Rafał Kukawski

Programista, webmaster. Szczególnie upodobał sobie JavaScript i technologie klienckie, choć strona serwera i bazy danych nie stanowią tajemnicy. Tworzy też aplikacje na urządzenia mobilne. kukawski.pl.


Komentarze


HTML CSS JavaScript PHP bazy danych MySQL Flash grafika framework hosting domeny pozycjonowanie wordpress Facebook