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 Facebook - tworzenie aplikacji: real-time updates

Warsztat / Artykuły i tutoriale

Facebook - tworzenie aplikacji: real-time updates

Bartosz Romanowski 19 lutego 2011 komentarze ()

Facebookowe Graph API udostępnia ciekawą funkcjonalność, dzięki której nasza aplikacja może być automatycznie powiadamiana o zmianie danych użytkownika lub strony, a także o odwołaniu któregoś z udzielonych wcześniej zezwoleń. Przyjrzyjmy się jak działają real-time updates i jak możemy z nich skorzystać.

Głównym celem udostępnienia tej funkcjonalności przez Facebooka było umożliwienie poprawy wydajności i czasu ładowania aplikacji poprzez trzymanie danych po stronie aplikacji i aktualizowanie ich tylko w momencie gdy się zmieniają, co owocuje mniejszą ilością odwołań do Graph API. Można oczywiście wykorzystać real-time updates do innych celów, na przykład do wykonywania jakiejś akcji w momencie gdy interesujące nas dane ulegną zmianie.

Aby Facebook wysyłał naszej aplikacji powiadomienia o zmianach danych musimy zgłosić chęć ich otrzymywania. Na chwilę obecną subskrybować można zmiany w obiektach user, permissions i page (tylko dane dostępne publicznie). Niestety, w przypadku obiektu user (dane użytkownika) nie mamy dostępu do wszystkich informacji - na dzień dzisiejszy możemy zasubskrybować zmiany w połączeniach feed (tablica użytkownika), friends (lista znajomych), activities (aktywność), interests (zainteresowania), music (muzyka), books (książki), movies (filmy), television (telewizja), likes (lubiane strony) i checkins (aktualnie niedostępne w Polsce). Ekipa Facebook obiecuje jednak, że lista dostępnych powiadomień będzie się powiększać, tak więc warto raz na jakiś czas zerknąć do dokumentacji.

Zacznijmy od zasubskrybowania powiadomień o zmianach danych użytkownika. Aby to zrobić musimy pobrać token OAuth dla naszej aplikacji, a następnie posługując się nim wysłać odpowiednie żądanie do Graph API. Może to wyglądać na przykład tak:

Kod: Zaznacz cały
require('fb/facebook.php');

$facebook = new Facebook(array(
  'appId'  => '_id_naszej_aplikacji_',
  'secret' => '_sekretny_kod_naszej_aplikacji_',
  'cookie' => true,
));

// pobieramy token OAuth dla naszej aplikacji
$params = array('grant_type'    => 'client_credentials',
                'client_id'     => $facebook->getAppId(),
                'client_secret' => $facebook->getAppSecret());
$ch = curl_init();
$url = 'https://graph.facebook.com/oauth/access_token';
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_HEADER, false);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);        
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, $params);
$return = curl_exec($ch);
curl_close($ch);
$return_array = explode('=', $return);
$app_token = $return_array[1];

// dodajemy nową subskrypcję
$params = array('access_token'  => $app_token,
                'object' => 'user',
                'fields' => 'television,books,music,movies',
                'verify_token' => 'aaabbbccc',
                'callback_url' => 'http://nasz-serwer.pl/katalog/rt_receive.php');
$ch = curl_init();
$url = 'https://graph.facebook.com/'.$facebook->getAppId().'/subscriptions';
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_HEADER, false);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);        
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, $params);
$return = curl_exec($ch);
curl_close($ch);

Fragment kodu odpowiedzialny za dodawanie nowej subskrypcji wymaga kilku słów wyjaśnienia - w tablicy $params mamy bowiem dwa parametry, o których wcześniej nie wspomniałem. Parametr verify_token to dowolny ciąg znaków, służący do weryfikacji żądania przez skrypt odbierający powiadomienia. Adres tego skryptu należy podać w parametrze callback_url - musi być on dostępny w momencie dodawania subskrypcji i musi zwrócić poprawną odpowiedź. Przykładowy, prosty skrypt odbierający (nazwijmy go rt_receive.php) może wyglądać tak:

Kod: Zaznacz cały
// ten sam token co w skrypcie dodającym subskrypcję
define('VERIFY_TOKEN', 'aaabbbccc');
$method = $_SERVER['REQUEST_METHOD'];
   
if($method == 'GET' && $_GET['hub_mode'] == 'subscribe' && $_GET['hub_verify_token'] == VERIFY_TOKEN)
{
    echo($_GET['hub_challenge']);
}
elseif($method == 'POST')
{
    // obsługa powiadomienia
    $updates = json_decode(file_get_contents("php://input"), true);
    file_put_contents('updates_log.txt', 'updates = ' . print_r($updates, true));
}

Skrypt ten pełni dwie funkcje: odpowiada na żądanie dodania subskrypcji (dane przysłane metodą GET) i odbiera powiadomienia o zmianie danych (dane przysyłane metodą POST). Odbieraniem danych zajmiemy się później.

Jeśli wszystko poszło zgodnie z planem, to nasza aplikacja ma w tym momencie aktywną subskrypcję zmian danych w polach television, books, music i movies w obiekcie użytkownika. Od tej pory jeśli któryś z użytkowników naszej aplikacji zmieni dane w tych polach (np. polubi stronę jakiegoś serialu czy filmu albo usunie tego typu stronę ze swojego profilu), nasz skrypt rt_receive.php otrzyma powiadomienie.

Aby pobrać aktywne subskrypcje można użyć takiego skryptu:

Kod: Zaznacz cały
// pobieramy aktywne subskrypcje
$ch = curl_init();
$url = 'https://graph.facebook.com/'.$facebook->getAppId().'/subscriptions?access_token='.$app_token;
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_HEADER, false);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);        
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'GET');
$return = curl_exec($ch);
var_dump(json_decode($return, true));

Warto dodać, że modyfikację aktywnych subskrypcji wykonuje się w taki sam sposób jak dodanie nowej. Przykładowo, jeśli mamy aktywną subskrypcję na pola television, music, books i movies, a następnie wyślemy zgłoszenie subskrypcji pól television i music, to nasza subskrypcja będzie obejmować tylko te dwa pola - pozostałe zostaną usunięte.

Jeśli zachodzi konieczność usunięcia wszystkich subskrypcji lub subskrypcji dla całego obiektu (np. user), należy wywołać API metodą DELETE. Nie jest to typowe działanie, tak więc można posłużyć się poniższym przykładem:

Kod: Zaznacz cały
// usuwanie subskrypcji
$ch = curl_init();
$url = 'https://graph.facebook.com/'.$facebook->getAppId().'/subscriptions?access_token='.$app_token.'&object=user';
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_HEADER, false);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);        
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'DELETE');
$return = curl_exec($ch);
curl_close($ch);

Wróćmy teraz do odbierania powiadomień przez nasz skrypt rt_receive.php. Powiadomienia otrzymujemy w formacie JSON, który transformujemy do tablicy (Array) funkcją json_decode(). Skrypt zapisał otrzymane dane do pliku updates_log.txt, tak więc możemy zobaczyć jak te dane wyglądają. Mogą mieć one na przykład taką formę:

Kod: Zaznacz cały
Array
(
    [object] => user
    [entry] => Array
        (
            [0] => Array
                (
                    [uid] => 990000505646950
                    [id] => 990000505646950
                    [time] => 1294519765
                    [changed_fields] => Array
                        (
                            [0] => television
                        )
                )
            [1] => Array
                (
                    [uid] => 990000505646952
                    [id] => 990000505646952
                    [time] => 1294519765
                    [changed_fields] => Array
                        (
                            [0] => music,
                            [1] => movies
                        )
                )
        )
)

Jak widać, powiadomienie zawiera tylko informacje o danych, które uległy zmianie (w tym przypadku u dwóch użytkowników) - nie zawiera dodanych lub usuniętych danych. Jeśli mamy dostęp do danych użytkownika (zezwolenie offline_access), to możemy pobrać wartości zmodyfikowanych pól już na etapie odbierania powiadomienia o zmianach. Trzeba jednak pamiętać, że skrypt odbierający powiadomienia musi zakończyć działanie w czasie krótszym niż 15 sekund - jeśli tak się nie stanie, to Facebook potraktuje to jako timeout (przekroczenie maksymalnego czasu odpowiedzi) i wyśle powiadomienie ponownie.

Zakładając, że mamy zezwolenie offline_access, możemy zmodyfikowane dane pobrać w taki sposób:

Kod: Zaznacz cały
// zmienna $updates zawiera tablicę (Array) z informacjami o zmianach danych otrzymanymi od Facebooka
$params = array('access_token' => $app_token);
foreach($updates['entry'] as $entry)
{
    foreach($entry['changed_fields'] as $field)
    {
        // pobieranie zmodyfikowanych danych użytkownika
        $data = $facebook->api('/'.$entry['uid'].'/'.$field, 'get', $params);
        // zobaczmy co dostaliśmy
        var_dump($data);
    }
}

Oczywiście w prawdziwej aplikacji nie będziemy wyświetlać pobranych danych - możemy je zapisać do bazy lub wykorzystać je w inny sposób, na przykład umieszczając wpis na tablicy użytkownika, wysyłając mu e-mail czy wykonując jakąś akcję w naszej aplikacji. Jeśli zasubskrybujemy zmiany w liście znajomych (object: user, fields: friends), możemy na przykład stworzyć aplikację powiadamiającą użytkownika o tym, że ktoś usunął go ze znajomych.

Inne artykuły na ten temat

Facebook - tworzenie aplikacji: pierwsza aplikacja Facebook - tworzenie aplikacji: zezwolenia i korzystanie z API Facebook: automatyczne dodawanie wpisów na stronie Facebook - tworzenie aplikacji: zaproszenia

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

Bartosz Romanowski

Programista, gadżeciarz, krytyczny miłośnik produktów Apple, fan ciężkich brzmień i niepoprawny pesymista.


Komentarze


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