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: zezwolenia i korzystanie z API

Warsztat / Artykuły i tutoriale

Facebook - tworzenie aplikacji: zezwolenia i korzystanie z API

Bartosz Romanowski 2 grudnia 2010 komentarze ()

W poprzednim artykule poświęconym tworzeniu aplikacji zintegrowanych z platformą Facebook omówiliśmy podstawowe zagadnienia związane z uruchomieniem własnej aplikacji i identyfikacją użytkownika. Teraz zajmiemy się zezwoleniami, jakich udzielają użytkownicy, oraz zobaczymy jakie możliwości daje na API serwisu.

Aby nasza aplikacja mogła mieć dostęp do określonych danych użytkownika lub mogła wykonywać w jego imieniu pewne działania, musi poprosić właściciela tych danych o zgodę. W serwisie Facebook istnieją dwa rodzaje zezwoleń: zezwolenia na publikację i zezwolenia na dostęp do danych.

Zezwolenia na publikację

Zezwoleń na publikację jest znacznie mniej i obejmują one następujące obszary:

  • publish_stream - pozwala aplikacji na umieszczanie wpisów i komentarzy na tablicy użytkownika oraz tablicach jego znajomych oraz oznaczać wpisy jako lubiane. Warto wiedzieć, że Facebook zaleca raczej sugerowanie użytkownikowi utworzenie wpisu (np. przez wyświetlenie okna dialogowego) niż automatyczne jego umieszczanie (co nie oznacza, że w ogóle nie wolno tego robić).
  • create_event - pozwala aplikacji na tworzenie wydarzeń.
  • rsvp_event - pozwala aplikacji na odpowiedź na wydarzenie (bierze udział, nie bierze udziału).
  • offline_access - powoduje, że token używany w autoryzacji OAuth ma dłuższy "czas życia"; wykorzystywane jest to przez np. aplikacje działające na komputerze użytkownika
  • publish_checkins - pozwala aplikacji na meldowanie się w usłudze Places (Miejsca), w tej chwili niedostępnej w Polsce.

Zatrzymajmy się na chwilę przy zezwoleniu offline_access. Mimo że nie będziemy z niego korzystali, to w jego opisie pojawiły się tajemnicze terminy token i OAuth, które warto krótko objaśnić. Platforma Facebook do autoryzacji wykorzystuje protokół OAuth 2.0. W dużym skrócie działa to w taki sposób, że dla każdego użytkownika, który zezwolił naszej aplikacji na jakieś działania, otrzymujemy specjalny token, który daje pewność, że daną czynność (publikację lub odczyt danych) wykonuje ta a nie inna aplikacja. Token ten ma określony, stosunkowo krótki czas ważności - gdy wygaśnie, generowany jest nowy. Wywołując metody Graph API musimy podać token (parametr access_token), aczkolwiek jeśli tworzymy aplikację działającą w ramach serwisu Facebook (w ramce - IFrame), to nie musimy sobie zaprzątać tym głowy. Dobrze jednak wiedzieć, że coś takiego jest i jak mniej więcej działa.

Zezwolenia na dostęp do danych

Zezwoleń na dostęp do danych jest całkiem sporo i obejmują one praktycznie wszystkie rodzaje informacji, które użytkownicy umieszczają w serwisie Facebook. Większość zezwoleń posiada dodatkowo analogiczne zezwolenie dotyczące znajomych użytkownika, na przykład user_about_me daje aplikacji dostęp do sekcji "O mnie" w profilu użytkownika, a friends_about_me daje dostęp do tej sekcji w profilach osób znajdujących się na liście znajomych użytkownika (oczywiście pod warunkiem, że znajomy nie zablokował takiej możliwości).

Pełna lista zezwoleń prezentuje się następująco (można ją znaleźć również w dokumentacji dla deweloperów):

Zezwolenie użytkownika Zezwolenie znajomych Opis
user_about_me friends_about_me Daje dostęp do sekcji profilu "O mnie"
user_activities friends_activities Daje dostęp do listy zdarzeń
user_birthday friends_birthday Daje dostęp do daty urodzin
user_checkins friends_checkins Daje dostęp do zameldowań
user_education_history friends_education_history Daje dostęp do informacji o wykształceniu
user_events friends_events Daje dostęp do listy wydarzeń, w których użytkownik bierze udział
user_groups friends_groups Daje dostęp do listy grup, których użytkownik jest członkiem
user_hometown friends_hometown Daje dostęp do informacji o mieście rodzinnym
user_interests friends_interests Daje dostęp do listy zainteresowań
user_likes friends_likes Daje dostęp do listy stron, które użytkownik lubi
user_location friends_location Daje dostęp do miejsca zamieszkania
user_notes friends_notes Daje dostęp do notatek użytkownika
user_online_presence friends_online_presence Daje dostęp do informacji o obecności użytkownika online
user_photo_video_tags friends_photo_video_tags Daje dostęp do listy zdjęć, na których użytkownik został oznaczony
user_photos friends_photos Daje dostęp do zdjęć użytkownika
user_questions friends_questions Daje dostęp do pytań, które zadał użytkownik
user_relationships friends_relationships Daje dostęp do informacji o związkach użytkownika
user_relationships_details friends_relationships_details Daje dostęp do szczegółowych informacji o związkach
user_religion_politics friends_religion_politics Daje dostęp do informacji o poglądach religijnych i politycznych
user_status friends_status Daje dostęp do ostatniej wiadomości (statusu) użytkownika
user_videos friends_videos Daje dostęp do filmów użytkownika
user_website friends_website Daje dostęp do informacji o stronach WWW użytkownika
user_work_history friends_work_history Daje dostęp do informacji o historii zatrudnienia
email * brak Daje dostęp do adresu e-mail użytkownika *
read_friendlist ** brak Daje dostęp do list znajomych, utworzonych przez użytkownika **
read_insights brak Daje dostęp do danych Insights (statystyki) dla stron, aplikacji i domen użytkownika.
read_mailbox *** brak Daje dostęp do skrzynki odbiorczej wiadomości ***
read_requests brak Daje dostęp do listy zaproszeń do grona znajomych
read_stream brak Daje dostęp do aktualności użytkownika z możliwością ich przeszukiwania
user_checkins friends_checkins Daje dostęp do zameldowań użytkownika lub widocznych dla niego zameldowań znajomych

* Co oczywiste, nie wolno wysyłać użytkownikom niechcianych wiadomości (spam). Wykorzystanie adresu e-mail musi być zgodne z zasadami Facebooka oraz wytycznymi CAN SPAM. ** Dostęp do listy znajomych użytkownika jest częścią standardowego zezwolenia. To zezwolenie pozwala na dostęp do list znajomych, które utworzył użytkownik. *** Aby móc zażądać tego zezwolenia, aplikacja musi zostać dodana do "białej listy". Zgłoszenia aplikacji dokonuje się na specjalnej stronie.

Uzyskiwanie zezwoleń

Tyle teorii, pora na trochę praktyki. Na początek musimy dowiedzieć się w jaki sposób mamy poprosić użytkownika o interesujące nas zezwolenia. Tradycyjnie można zrobić to na kilka sposobów. Zacznijmy od najprostszego, czyli dodania dodatkowych zezwoleń w momencie logowania użytkownika do naszej aplikacji. W zależności od tego, w jaki sposób udostępniamy użytkownikom możliwość zalogowania się, dorzucenie dodatkowych zezwoleń będzie wyglądało inaczej.

Kod: Zaznacz cały
// stworzenie linku do logowanie z wykorzystaniem PHP SDK
$loginUrl = $facebook->getLoginUrl(array('req_perms' => 'email,publish_stream'));
Kod: Zaznacz cały
<!-- stworzenie przycisku do logowania z wykorzystaniem JS SDK i XFBML -->
<fb:login-button perms="email,publish_stream"></fb:login-button>
Kod: Zaznacz cały
<!-- stworzenie przycisku do logowania z wykorzystaniem JS SDK -->
<a href="#" onclick="javascript:FB.login(function(response) { }, {perms:'email,publish_stream'});">zaloguj</a>

Mimo że to rozwiązanie wygląda na najprostsze (użytkownik od razu daje nam wszystkie potrzebne zezwolenia), to nie jest najlepsze z punktu widzenia użytkowników - nie każdy przecież chce "w ciemno" zezwalać na wszystko aplikacji, której jeszcze nie widział i o której nie wie praktycznie nic. O wiele lepiej jest umożliwić zalogowanie bez żadnych dodatkowych zezwoleń, a dopiero później prosić o dodatkowe uprawnienia, najlepiej z wyjaśnieniem, do czego są one aplikacji potrzebne. Jest to o tyle mało problematyczne, że jeśli poprosimy użytkownika o zezwolenia A, B i C, a nasza aplikacja ma już od tego użytkownika zezwolenie B, to okno dialogowe z prośbą o udzielenie dodatkowych zezwoleń nie będzie zawierać zezwolenia B jako już nadanego (nie musimy sami się o to martwić).

Aby poprosić użytkownika o dodatkowe zezwolenia robimy dokładnie to samo co przy jego logowaniu. Oczywiście bez sensu jest tworzenie kolejnego przycisku logowania, bo będzie to mylące, dlatego też znacznie lepiej jest wykorzystać do tego celu jakiś własny przycisk, link czy kawałek grafiki, a następnie podpiąć do tego wywołanie funkcji FB.login() albo URL zwrócony przez funkcję getLoginUrl(). Jeśli zdecydujemy się na pierwszy wariant, to warto stworzyć sobie funkcję, dzięki której nasz link będzie wyglądał w miarę przyjaźnie.

Kod: Zaznacz cały
<script>
// prosimy o zezwolenia na dostęp do adresu e-mail i publikowanie wiadomości
function e_ps_dialog()
{
  FB.login(function(response) {
  if (response.session) {
    if (response.perms) {
      window.location.reload();
    }
  }
}, {perms:'email,publish_stream'});
}
</script>
<a href="#" onclick="javascript:e_ps_dialog()">Zezwól na dostęp do adresu e-mail i na publikowanie wiadomości</a>

Publikowanie wiadomości na tablicy

Załóżmy, że mamy już wszystkie potrzebne do działania naszej aplikacji zezwolenia i spróbujmy coś z nimi zrobić. Na początek zróbmy coś, czego Facebook nie poleca, czyli opublikujmy wiadomość na tablicy użytkownika. Potrzebne jest nam do tego zezwolenie publish_stream. Tradycyjnie możemy to zrobić na kilka sposobów.

Możemy utworzyć listę parametrów i (nieco topornie) przekazać ją do odpowiedniego API za pośrednictwem CURLa.

Kod: Zaznacz cały
// przekazanie tokena; nie jest konieczne jeśli nasza aplikacja działa w ramce (IFrame)
$post_data =  "access_token=".$session['access_token']."&";
$post_data .= "message=Testowy wpis&";
$post_data .= "link=http://nasza-strona.pl&";
$post_data .= "name=Tytuł wpisu&";
$post_data .= "caption=Opis wpisu&";
$post_data .= "picture=http://nasza-strona.pl/obrazki/obrazek.jpg&";
$post_data .= "description=Dłuższy opis&";
$post_data .= "actions={'name': 'Przejdź do aplikacji Nasza Aplikacja', 'link': 'http://apps.facebook.com/nasza_aplikacja/'}&";
$post_data .= "privacy={'value': 'ALL_FRIENDS'}";

$c = curl_init();

// URL interfejsu API; konieczne https
curl_setopt($c, CURLOPT_URL, 'https://graph.facebook.com/me/feed');

curl_setopt($c, CURLOPT_HEADER, 0);
curl_setopt($c, CURLOPT_RETURNTRANSFER, 1); 
curl_setopt($c, CURLOPT_POST, 1);
curl_setopt($c, CURLOPT_POSTFIELDS, $post_data);
$result = curl_exec($c);
curl_close($c);

Warto zauważyć, że parametry actions i privacy przyjmują wartości w formacie JSON.

Znacznie bardziej elegancko jest zrobić to za pośrednictwem metody api().

Kod: Zaznacz cały
$params = array('message' => 'Testowy wpis',
				'link' => 'http://nasza-strona.pl',
				'name' => 'Tytuł wpisu',
				'caption' => 'Opis wpisu',
				'picture' => 'http://nasza-strona.pl/obrazki/obrazek.jpg',
				'description' => 'Dłuższy opis',
				'actions' => "{'name': 'Przejdź do aplikacji Nasza Aplikacja',
                                               'link': 'http://apps.facebook.com/nasza_aplikacja/'}",
				'privacy' => "{'value': 'ALL_FRIENDS'}");

$post = $facebook->api('/me/feed', 'post', $params);

Można do tego wykorzystać również JavaScript SDK. W tym przypadku wszystkie parametry trzeba przekazać w formacie JSON.

Kod: Zaznacz cały
FB.api('/me/feed', 'post', { message: 'Testowy wpis', link: 'http://nasza-strona.pl', name: 'Tytuł wpisu', caption: 'Opis wpisu', picture: 'http://nasza-strona.pl/obrazki/obrazek.jpg', description: 'Dluzszy opis', actions: {name: 'Przejdź do aplikacji Nasza Aplikacja', link: 'http://apps.facebook.com/nasza_aplikacja/'}}, function(response) {
    if (!response || response.error) {
        alert('Wystąpił błąd');
    } else {
        alert('Wiadomość zapisana');
    }
});

Niezależnie od wybranej metody, efektem jest mniej więcej taki wpis na tablicy użytkownika. Warto przyjrzeć mu się przez chwilę aby zrozumieć które parametry odpowiadają za zawartość poszczególnych elementów wpisu. Warto dodać, że pliki przekazywane w parametrze picture muszą być dostępne z zewnątrz - najczęstszą przyczyną problemów z pobieraniem plików przez Facebooka jest włączone na serwerze zabezpieczenie przed hotlinkowaniem.

Facebook - wpis

Jak widać, całość nie jest zbyt skomplikowana. Jedynym parametrem, który może budzić wątpliwości, jest parametr privacy. Określa on grupy osób, dla których widoczny będzie wpis. W naszym przypadku ma on wartość ALL_FRIENDS, co oznacza, że wpis będzie widoczny dla wszystkich osób z listy znajomych użytkownika. Może on również przyjmować wartości EVERYONE (wszyscy), CUSTOM (wymaga dodatkowych parametrów), NETWORKS_FRIENDS (znajomi i sieci) lub FRIENDS_OF_FRIENDS (znajomi znajomych). Jeśli ustawimy tu wartość CUSTOM, będziemy musieli przekazać jeden lub więcej dodatkowych parametrów, określających szczegółowo osoby, które będą widziały wpis. Parametr friends określa znajomych, którzy będą widzieć wpis. Może on przyjąć wszystkie wartości z parametru nadrzędnego lub dodatkowo SOME_FRIENDS (wybrani znajomi, wymaga przekazania dodatkowego parametru), SELF (tylko użytkownik będący autorem wpisu) lub NO_FRIENDS (wpis widoczny tylko dla sieci). Parametr networks może zawierać listę sieci, dla których wpis będzie widoczny. Wartość 1 oznacza wszystkie sieci, do których należy użytkownik. Parametry allow i deny zawierają listę identyfikatorów użytkowników, którzy będą widzieć wpis (allow) lub dla których będzie on ukryty (deny). Należy pamiętać, że ustawienia te dotyczą tylko wpisów umieszczanych na tablicy użytkownika - zostaną zignorowane w przypadku wpisów publikowanych na tablicach znajomych, stronach, stronach wydarzeń czy grup. Warto również pamiętać, że (zgodnie z polityką prywatności Facebooka) należy informować użytkownika o próbie opublikowania wpisu z niestandardowymi ustawieniami prywatności.

Jak już wcześniej wspomniałem, publikowanie wpisów na tablicy bez wiedzy użytkownika nie jest ani eleganckie, ani zalecane przez Facebooka. Najlepszym sposobem jest skorzystanie ze standardowych okien dialogowych, za pomocą których możemy zaproponować użytkownikowi umieszczenie wpisu na jego tablicy. Służy do tego metoda FB.ui(), będąca częścią JavaScript SDK. Korzystanie z niej nie różni się specjalnie od tego, co robiliśmy do tej pory, z tą małą różnicą, że musimy w jej przypadku korzystać z metod starego REST API.

Aby zaproponować użytkownikowi umieszczenie wpisu na tablicy należy wywołać metodę FB.ui() w mniej więcej taki sposób:

Kod: Zaznacz cały
FB.ui(
  {
    method: 'stream.publish',
    message: 'Polecam wszystkim tą świetną aplikację.',
    attachment: {
      name: 'Nasza Aplikacja',
      caption: 'Krótki opis',
      description: 'Dłuższy opis',
      media: [ { type: 'image', src: 'http://nasz-serwer.pl/obrazki/obrazek.jpg', href: 'http://apps.facebook.com/nasza-aplikacja/' } ]
    },
    action_links: [{ text: 'Przejdź do aplikacji', href: 'http://apps.facebook.com/nasza-aplikacja/' }],
    user_message_prompt: 'Napisz co myślisz o naszej aplikacji'
  },
  function(response) {
    if (response && response.post_id) {
      alert('Wpis został opublikowany.');
    } else {
      alert('Coś poszło nie tak...');
    }
  }
);

Większość parametrów jest na tyle oczywista, że nie wymaga dodatkowych wyjaśnień. Warto przyjrzeć się bliżej parametrowi attachment i jego zawartości. W naszym przykładzie umieściliśmy tam obrazek, który będzie jednocześnie linkiem do naszej aplikacji (parametr media). Może to być równie dobrze plik MP3 (atrybut type: music) lub animacja Flash (atrybut type: flash), z tym że każdy z tych typów posiada inne dodatkowe atrybuty (np. plik dźwiękowy posiada tytuł i wykonawcę, a animacja Flash wysokość i szerokość). Na podobnej zasadzie możemy dołączać załączniki do wpisów zamieszczanych automatycznie, bez interakcji z użytkownikiem. Więcej na temat załączników można dowiedzieć się z dokumentacji Facebooka dla twórców aplikacji.

Wywołanie zamieszczonego powyżej kodu spowoduje pojawienie się takiego okna dialogowego.

Facebook - wpis

W dwóch ostatnich przykładach została zawarta podstawowa obsługa danych zwracanych przez metodę FB.ui(). Jeśli przyjrzymy się obiektowi response, to zawiera on tylko jedną interesującą nas informację: zmienną post_id, w której znajdziemy identyfikator dodanego wpisu. Można skorzystać z niego np. do wygenerowania bezpośredniego linku do utworzonej wiadomości, ale generalnie jest to mało użyteczne. W ostatnim przykładzie zakładamy, że przekazanie do naszego skryptu identyfikatora nowego wpisu jest równoznaczne z poprawnym jego opublikowaniem (tak też zresztą mówi dokumentacja) i w takim przypadku wyświetlamy odpowiedni komunikat. Oczywiście zamiast tego możemy wykonać dowolne inne operacje, na przykład zapisanie informacji o umieszczonym wpisie do bazy danych czy przekierowanie użytkownika na jakąś stronę. Warto dodać, nie musimy w ogóle obsługiwać zwracanych przez FB.ui() danych - być może wcale nas nie interesuje czy użytkownik opublikował proponowaną przez nas wiadomość.

Dostęp do danych użytkownika

Wiemy już jak publikować wiadomości na tablicy użytkownika, teraz pora na wyciągnięcie jego danych. Za przykład posłuży nam lista stron, które lubi nasz użytkownik. Potrzebne nam będzie do tego zezwolenie user_likes - wiemy już jak o nie poprosić, tak więc nie będę się powtarzał. Dane wyciągniemy korzystając z PHP SDK, bo jest to wygodniejsze niż używanie JavaScriptu (mimo że da się to zrobić).

Kod: Zaznacz cały
// zmienna $me, znana z pierwszej części tego artykułu
if($me)
  $likes = $facebook->api('/me/likes');
// zobaczmy co dostaliśmy
var_dump($likes['data']);

W odpowiedzi otrzymamy tablicę (array) z danymi na temat stron oznaczonych przez użytkownika jako lubiane. Dane te składają się z nazwy strony (name), jej unikalnego identyfikatora (id), nazwy kategorii stron (category, na przykład Application, Musicians, Television itp.) oraz daty dodania do ulubionych (created_time).

Teraz dla każdego z elementów pobierzmy bardziej szczegółowe informacje. Ponieważ jest to tylko przykład wykorzystania API Facebooka, pominiemy kluczową kwestię, czyli wydajność. Absolutnie nie należy wykonywać takich operacji w aplikacji udostępnionej użytkownikom, ponieważ zbyt intensywne wywoływanie w pętli metod API może zostać odebrane przez Facebooka jako nadużycie, a i czas ładowania strony aplikacji będzie bardzo długi.

Kod: Zaznacz cały
foreach($likes['data'] as $like)
{
  $page_data = $facebook->api($like['id']);
  echo($like['name']." (".$page_data['category'].")<br /><a href="".$page_data['link']."">Przejdź do strony</a><br /><br />");  
}

Druga kwestia to różnice w danych dla poszczególnych kategorii stron. Na przykład strony z kategorii 'Application' posiadają takie atrybuty jak opis (desctiption) czy podkategoria (subcategory), a z kolei strony z kategorii 'Television' mają określony gatunek (genre). Dla ułatwienia w powyższym przykładzie wykorzystujemy tylko te dane, które są wspólne dla wszystkich kategorii stron.

Warto zwrócić uwagę na to, że dane dla wszystkich dostępnych przez Graph API elementów (użytkownik, grupa, wydarzenie, wpis, aplikacja, strona, notatka, zdjęcie, wideo, link i album) pobieramy dokładnie tak samo, czyli posługując się tylko identyfikatorem elementu. Alternatywnie możemy odwołać się do API bezpośrednio przez URL, na przykład https://graph.facebook.com/182475962998 (w takim przypadku otrzymamy dane w formacie JSON). Równie łatwo możemy pobrać elementy (np. wpisy na tablicy, albumy, notatki czy linki) dla konkretnego użytkownika, strony, aplikacji itp. - wystarczy dodać na końcu interfejsu typ elementu, na przykład:

Kod: Zaznacz cały
// pobiera zwartość tablicy użytkownika/strony/grupy itp.
$facebook->api($identyfikator.'/feed');
// URL: https://graph.facebook.com/182475962998/feed 
// pobiera linki udostępnione przez użytkownika/stronę itp.
$facebook->api($identyfikator.'/links');
// URL: https://graph.facebook.com/182475962998/links

Pełna lista dostępnych interfejsów znajduje się w dokumentacji Facebooka dla twórców aplikacji. Jeśli chcemy dowiedzieć się jakie informacje są dostępne dla określonego elementu, wystarczy spojrzeć na sekcję "Połączenia" na odpowiedniej stronie dokumentacji (np. dla aplikacji).

Wciąż możemy również korzystać ze starszego REST API, co jednak nie jest zalecane, ponieważ (jak można przeczytać w dokumentacji) Facebook sukcesywnie przenosi funkcjonalności do Graph API i twórcom nowych aplikacji sugeruje korzystanie z tych właśnie interfejsów. Korzystając z REST API trzeba liczyć się z tym, że w pewnym momencie któreś z jego metod przestaną działać. Na szczęście Facebook informuje o takich działaniach ze sporym wyprzedzeniem. Niestety, ponieważ jeszcze nie wszystkie interfejsy są dostępne w Graph API, czasem będziemy musieli skorzystać z którejś ze starszych metod. Jak ich używać w JavaScript SDK możemy zobaczyć na przykładzie FB.ui() i publikowania wiadomości na tablicy użytkownika. Używanie REST API w PHP SDK jest równie proste, co możemy zobaczyć na przykładzie pobierania listy notatek opublikowanych przez użytkownika (a konkretnie stronę):

Kod: Zaznacz cały
$params = array('method' => 'notes.get',
                               'uids' => 182475962998,    // ID strony, użytkownika itp.
                               'fields' => 'title, content, created_time',    // pola, które chcemy pobrać
                               'callback' => '');    // nazwa funkcji JavaScript, która zostanie wywołana po wykonaniu metody REST API
$notatki = $facebook->api($params);

Pełną listę metod REST API można znaleźć w dokumentacji Facebooka dla twórców aplikacji.

Wiemy już jak umieszczać wpisy na tablicy użytkownika i jak pobierać dane z serwisu Facebook. Teraz przydałoby się wykorzystać jedną z głównych zalet tego serwisu społecznościowego, czyli olbrzymią bazę użytkowników, którzy nawzajem polecają sobie interesujące aplikacje. W kolejnym artykule stworzymy więc mechanizm wysyłania zaproszeń do znajomych.

Inne artykuły na ten temat

Facebook - tworzenie aplikacji: pierwsza aplikacja
Facebook - tworzenie aplikacji: zaproszenia
Facebook: automatyczne dodawanie wpisów na stronie
Facebook - tworzenie aplikacji: real-time updates

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