Automatyczna publikacja w serwisach społecznościowych

Pierwszy wpis niniejszego blogu zostaje poświęcony praktycznemu zagadnieniu, czyli mechanizmowi automatycznej publikacji treści w popularnych serwisach społecznościowych (Facebook oraz Twitter).


spis treści:
[1/5] AUTOPUBLIKACJA – ALE W JAKIM CELU?
[2/5] NARZĘDZIA
[3/5] FACEBOOK
[4/5] TWITTER
[5/5] PRZYDATNE ODNOŚNIKI I ŹRÓDŁA WIEDZY


[1/5] AUTOPUBLIKACJA – ALE W JAKIM CELU?

Typowe podejście do zarządzania profilem w serwisie społecznościowym opiera się na ręcznej publikacji treści. Dzięki użyciu kodu programistycznego można skorzystać z opcji udostępnionej przez twórców serwisów społecznościowych, aby poprzez komunikację z bramkami API zlecać automatyczne publikacje treści (postów, statusów, komunikatów, itp.). Poprawnie zautomatyzowany proces publikacji oszczędza czas, nie wymaga dokonywania ręcznych czynności: logowania się ani czasochłonnego klikania w przyciski. W przypadku publikacji treści w serwisie Facebook wymagane jest jedynie okresowe odświeżenie tokena dostępowego (który w swojej długoterminowej odmianie zachowuje ważność przez dwa miesiące od momentu jego wygenerowania).

Niniejszy wpis przede wszystkim szkicuje schemat działania oraz ilustruje jak można wdrożyć podstawową funkcjonalność publikacji treści. Podstawową funkcjonalność można rozszerzać. Do publikowanych treści bramki API umożliwiają dodawanie np. materiałów multimedialnych, hasztagów, odnośników, itp.


[2/5] NARZĘDZIA

Niezbędne prerekwizyty:
– dowolny język programowania (w poniższym przykładzie: PHP),
oraz
– założone konta w serwisach Facebook oraz Twitter, dostęp do kluczy (tokenów) oraz utworzone wewnętrzne aplikacje, które będą pośredniczyć w komunikacji.

Implementacja jest wykonana bez dodatkowych bibliotek.

PHP HMAC


[3/5] FACEBOOK

System API w tym serwisie rozróżnia dwa rodzaje tokenów:
User Access Token
oraz
Page Access Token

Pierwszy z nich pozwala publikować jako użytkownik, drugi z nich – jako strona.

Tokeny dzielą się na krótkoterminowe i długoterminowe. Tylko te drugie mają sens w praktycznych zastosowaniach.

Warto zwrócić baczną uwagę na ustawienia wewnętrznej aplikacji w serwisie Facebook:
* Ustawienia/Zaawansowane/Age Restriction powinno być ustawione na „Dla wszystkich (13+)” [inne ustawienie spowoduje, że publikowane treści nie będą widoczne publicznie]
* „Require App Secret” powinno być ustawione na TAK [dla lepszego bezpieczeństwa]
* Roles/Administratorzy [tutaj musi być wybrany twórca aplikacji, aby skutecznie publikować posty]
* „App Review/Udostępnić aplikację {nazwa aplikacji} publicznie?” = TAK [aby posty były publiczne]

Graph API

Istotne niuanse w Eksploratorze Graph API:
* aby publikacja treści była skuteczna następujące dwa uprawnienia są niezbędne: manage_pages, publish_pages
* kliknięcie w ikonę informacji oraz następnie „Otwórz w generatorze tokena dostępu” pozwala uruchomić polecenie „Extend Access Token” aby wygenerować długoterminowy token
* zapytanie „GET /me/accounts” w ręcznym edytorze Graph API i kliknięcie „Submit” również pozwala wygenerować token [ale taka operacja zadziała tylko z wyłączonym „Require App Secret” w ustawieniach aplikacji!]

Wzorcowe adresy URL, które przyjmują nadchodzącą komunikację i służą do publikacji treści to:
https://graph.facebook.com/me/feed
https://graph.facebook.com/{ID strony}/feed

IMPLEMENTACJA

Na początku definiujemy zmienne, które przydadzą się dalej:
$facebook_tresc_do_publikacji
$long_lived_access_token
$app_secret

Ustalamy adres, z którym odbywać się będzie komunikacja:
$facebook_url = 'https://graph.facebook.com/{id_strony}/feed';
Oraz obliczamy hasz przy użyciu metody HMAC oraz algorytmu SHA-256:
$appsecret_proof = hash_hmac( 'sha256', $long_lived_access_token, $app_secret );
Następnie przygotowujemy roboczą tablicę, która zostanie wysłana metodą POST do serwera docelowego:
$dane_post = array(
'message' => $facebook_tresc_do_publikacji,
'access_token' => $long_lived_access_token,
'appsecret_proof' => $appsecret_proof,
);

...
curl_setopt($curl_uchwyt, CURLOPT_URL, $facebook_url);
curl_setopt($curl_uchwyt, CURLOPT_POSTFIELDS, $dane_post);
...

W rezultacie otrzymamy odpowiedź w formacie JSON.

Wiadomość powinna zostać pomyślnie opublikowana.
Jeśli coś poszło nie tak, to warto sprawdzić zawartość odpowiedzi przy użyciu funkcji json_decode. Szczegóły problemu można odnaleźć w wartości odpowiedzi dla klucza „error”.


[4/5] TWITTER

Patrząc całościowo, autopublikacja w serwisie Twitter jest mniej absorbująca, bo nie wymaga okresowego odświeżania tokena (raz ustalony token dostępowy nie traci swojej ważności). Trudniej za to ją zaimplementować, bo wymaga wykonania bardziej skomplikowanych operacji na starcie.

IMPLEMENTACJA

Na początek warto ustawić roboczą zmienną tablicową zawierającą dane, których użyjemy za chwilę:
$twitter_konfiguracja = array(
'metoda' => 'POST',
'url' => 'https://api.twitter.com/1.1/statuses/update.json',
'status' => {{treść statusu do publikacji}},

'oauth_consumer_key' => ...,
'consumer_secret' => ...,
'oauth_token' => ...,
'token_secret' => ...,
'oauth_signature_method' => 'HMAC-SHA1',
'oauth_version' => '1.0',
'algorytm_haszowania' => 'sha1',
);

TT

Kostruujemy funkcję, która pozwoli na wygenerowanie sygnatury OAuth. Czym są zmienne $czas i $losowa_jednorazowka? O tym za chwilę.
function twitterStworzSygnatureOAuth( $twitter_konfiguracja, $czas, $losowa_jednorazowka ) {
//fragment 4.1.
$dane_skladowe = array(
'status' => $twitter_konfiguracja['status'],
'oauth_consumer_key' => $twitter_konfiguracja['oauth_consumer_key'],
'oauth_nonce' => $losowa_jednorazowka,
'oauth_signature_method' => $twitter_konfiguracja['oauth_signature_method'],
'oauth_timestamp' => $czas,
'oauth_token' => $twitter_konfiguracja['oauth_token'],
'oauth_version' => $twitter_konfiguracja['oauth_version'],
);

//fragment 4.2.
$skladowe_przetworzone = array();
foreach($dane_skladowe as $k=>$v) $skladowe_przetworzone[rawurlencode($k)] = rawurlencode($v);

ksort($skladowe_przetworzone);

//fragment 4.3.
$lancuch_parametrow = http_build_query($skladowe_przetworzone);

$hash_hmac_dane =
strtoupper($twitter_konfiguracja['metoda']).
'&'.
rawurlencode($twitter_konfiguracja['url']).
'&'.
rawurlencode($lancuch_parametrow);

$hash_hmac_klucz =
rawurlencode($twitter_konfiguracja['consumer_secret']).
'&'.
rawurlencode($twitter_konfiguracja['token_secret']);

//fragment 4.4.
$hash_hmac_obliczony =
hash_hmac(
$twitter_konfiguracja['algorytm_haszowania'],
$hash_hmac_dane,
$hash_hmac_klucz,
TRUE
);

return base64_encode($hash_hmac_obliczony);
}

Kilka wyjaśnień:
4.1. – tworzymy tablicę danych składowych, która zostanie docelowo wykorzystana do obliczenia wartości sygnatury OAuth
4.2. – kodujemy wszystkie składowe zgodnie z RFC 1738, następnie sortujemy alfabetycznie według kluczy
4.3. – budujemy zwarty ciąg zapytania przy użyciu funkcji http_build_query oraz generujemy dane oraz klucz jako argumenty dla funkcji hash_hmac
i wreszcie:
4.4. – obliczamy potrzebny nam hasz
Oczywiście wszystkie powyższe kroki spełniają wymogi specyfikacji Twitter API.

Przydatne w toku działania będą zmienne:
$losowa_jednorazowka
$czas

pierwsza z nich to znana z angielskiego wartość nonce, czyli 16-znakowy losowy ciąg, który posłuży jako kryptograficzna sól.
Potrzebujemy też aktualną wartość czasu w formacie UNIX (wystarczy użyć funkcji time()).

Teraz, kiedy dysponujemy funkcją obliczającą hasz i wszystkimi potrzebnymi danymi, możemy skonstruować właściwy kod:
$sygnatura_wygenerowana = twitterStworzSygnatureOAuth( $twitter_konfiguracja, $czas, $losowa_jednorazowka );

$dane_skladowe = array(
'oauth_consumer_key' => $twitter_konfiguracja['oauth_consumer_key'],
'oauth_nonce' => $losowa_jednorazowka,
'oauth_signature' => $sygnatura_wygenerowana,
'oauth_signature_method' => $twitter_konfiguracja['oauth_signature_method'],
'oauth_timestamp' => $czas,
'oauth_token' => $twitter_konfiguracja['oauth_token'],
'oauth_version' => $twitter_konfiguracja['oauth_version'],
);

$skladowe_przetworzone = array();
foreach($dane_skladowe as $k=>$v) {
$skladowe_przetworzone[] = rawurlencode($k).'="'.rawurlencode($v).'"';
}

//fragment 4.5.
$naglowki = array();
$naglowki[] = 'Content-Type: application/x-www-form-urlencoded';
$naglowki[] =
'Authorization: OAuth '.
implode( ', ', $skladowe_przetworzone );

$tmp_status =
'status='.
rawurlencode( $twitter_konfiguracja['status'] );

//fragment 4.6.
...
curl_setopt( $curl_uchwyt, CURLOPT_URL, $twitter_konfiguracja['url'] );
curl_setopt( $curl_uchwyt, CURLOPT_POSTFIELDS, $tmp_status );
...

4.5. – tworzymy nagłówki wskazujące, że mamy do czynienia z mechanizmem OAuth

Warto nadmienić, że wynik działania funkcji rawurlencode może powodować nieoczekiwane problemy (zdarza się, że łańcuch %25 bywa kodowany błędnie i wymaga specjalnej poprawki).

Po wywołaniu funkcji curl z właściwymi parametrami (4.6.) pożądane dane powinny zostać niezwłocznie opublikowane w serwisie Twitter.


[5/5] PRZYDATNE ODNOŚNIKI I ŹRÓDŁA WIEDZY

(platforma developers.facebook.com)

dostęp do ustawień aplikacji
https://developers.facebook.com/apps/{ID aplikacji}
Graph API Explorer
https://developers.facebook.com/tools/explorer/
dokumentacja Graph API
https://developers.facebook.com/docs/graph-api
szczegóły specyfikacji Graph API
https://developers.facebook.com/docs/graph-api/reference
dokumentacja tokenów dostępowych
https://developers.facebook.com/docs/facebook-login/access-tokens/

(platforma dev.twitter.com)

opis API
https://dev.twitter.com/rest/public
szczegółowy opis dostępnych operacji
https://dev.twitter.com/rest/reference
informacje o autoryzacji za pośrednictwem mechanizmu OAuth
https://dev.twitter.com/oauth/overview/authorizing-requests

(funkcje PHP)

hash_hmac
http://php.net/manual/pl/function.hash-hmac.php
rawurlencode
http://php.net/manual/pl/function.rawurlencode.php

Dodaj komentarz

Twój adres email nie zostanie opublikowany. Pola, których wypełnienie jest wymagane, są oznaczone symbolem *