Publikování na facebooku jako stránka

Včera se za mnou stavil kamarád s úplatky, že by potřeboval pomoct rozběhat automatické přispívání na Facebook Page. Protože Facebook zase nedávno udělal novou verzi api, tentokrát v2.3, tak spousta návodů jak publikovat na stránky jménem stránky je trošku obsolete a hlavně, ještě nikdo nenapsal návod pro Kdyby/Facebook :) Tak jsem na to s ním sedl, opravil pár compatibility drobností v Kdyby/Facebook a během půl hodinky nám to fungovalo.

Založení stránky a aplikace

Nejprve si založíme novou aplikaci, případně pokud máte existující aplikaci, doporučuji pro práci na localhostu si založit testovací aplikaci.

publikovani-na-fb-create-test-app

Pro funkční přihlašování samozřejmě budeme potřebovat App Id a App Secret.

A protože chceme na stránku publikovat, budeme potřebovat, aby nám Facebook schválil práva publish_pages a manage_pages. To se dělá v nastavení aplikace záložkou “Status & Review”, kde klikneme na “Start a Submission”, najdeme práva které potřebujeme, potvrdíme a pak musíme ještě vyplnit proč ta práva chceme. Facebook je posledních pár verzí API opravdu hodně přísnej na to co komu povolí, takže opravdu musíte napsat dobré důvody proč ty práva chcete. Dokud vám ty práva neschválí, bude všude hromada warningů u přihlašovacích dialogů, ale mělo by fungovat proti tomu vyvíjet a testovat.

Dále je potřeba založit novou stránku případě použít existující. Na záložce “Informace” stránky, na kterou chceme publikovat, ja úplně dole “ID stránky Facebooku”, tohle ID budeme za moment potřebovat.

Založení projektu a přihlašování

Nainstalujeme si vyčištěný Nette sandbox a Kdyby/Facebook

$ composer create-project nette/web-project facebook-pages/
$ cd facebook-pages/
$ composer require kdyby/facebook

Když si teď v prohlížeči otevřeme aplikaci, měla by se ukázat “Congratulations!” stránka.

Abychom mohli poslat něco na Facebook Page, musíme nejprve autorizovat do naší Facebook App uživatele, který na stránku může publikovat.

Konfigurace Kdyby/Facebook je dostatečně popsaná v dokumentaci, stejně tak jak rozběhat přihlášení je popsané v dokumentaci.

Nezapomenout nastavit verzi graph api.

facebook:
    appId: "123"
    appSecret: "abc"
    graphVersion: v2.3

Všimněte si, že v configu nenastavuju práva na práci se stránkou, ale nechávám zde pouze výchozí práva, která mi dovolí číst informace o uživateli. Je to proto, že “dokonalé” workflow má vypadat tak, že uživatele nejprve přihlásím a požádám o read práva a až když je přihlášený a chtěl by například v administraci připojit stránky pro publikování, tak ho pošlu na Facebook login znovu, tentokrát ale s upraveným “scope” a budu po něm chtít ať mi přidá další práva. Tenhle proces se jmenuje rerequest. Vyladit tohle workflow ale není cílem návodu, takže si ho tím komplikovat nebudeme a rovnou při prvním přihlášení budeme chtít všechna práva. Je ale důležité tenhle princip znát, protože Facebook by si mohl usmyslet, že to děláte špatně a zablokovat vás.

A takhle by mohlo vypadat hodně vyčištěné přihlašování bez persistence pouze se sessions

class HomepagePresenter extends Nette\Application\UI\Presenter
{
    /** @var \Kdyby\Facebook\Facebook @inject */
    public $facebook;

    /** @return \Kdyby\Facebook\Dialog\LoginDialog */
    protected function createComponentFbLogin()
    {
        $dialog = $this->facebook->createDialog('login');
        /** @var \Kdyby\Facebook\Dialog\LoginDialog $dialog */

        $dialog->setScope(['publish_pages', 'manage_pages']);

        $dialog->onResponse[] = function (\Kdyby\Facebook\Dialog\LoginDialog $dialog) {
            $fb = $dialog->getFacebook();

            if (!$fb->getUser()) {
                $this->flashMessage("Sorry bro, facebook authentication failed.");
                return;
            }

            try {
                $me = $fb->api('/me');
                $this->user->login(new Identity($me->id, [], (array) $me));

            } catch (\Kdyby\Facebook\FacebookApiException $e) {
                \Tracy\Debugger::log($e, 'facebook');
                $this->flashMessage("Sorry bro, facebook authentication failed hard.");
            }

            $this->redirect('this');
        };

        return $dialog;
    }

}

Do šablony app/presenters/templates/Homepage/default.latte si pro test vložíme něco jako

<div id="content">
    {if !$user->loggedIn}
        <a n:href="fbLogin-open!">Login using facebook</a>
    {else}
        {? dump($user->identity)}
    {/if}
</div>

publikovani-na-fb-congratulations

Tak a teď se kliknutím na odkaz přihlásíme, povolíme čtení profilu a v dalším kroku by po nás Facebook měl chtít potvrzení práv pro publikaci

publikovani-na-fb-login-step1

Detailněji si to můžeme ověřit rozklinutím “Vybrat co povolíte”

publikovani-na-fb-login-step2

A po potvrzení bychom měli dostat něco takového

publikovani-na-fb-after-login

Publikování na stránku

Když jsme teď přihlášeni do aplikace na našem webu, zbývají už jen dva kroky.

  • získat access_token stránky na kterou budeme pulikovat (což je úplně jiný access_token, než jaký máme pro přihlášení uživatele)
  • poslat příspěvek na zeď

Na endpointu /me/accounts máme seznam všech stránek, se kterými přihlášený uživatel může pracovat, takže si ho zavoláme

$accounts = $this->facebook->api('/me/accounts');

A ani ho nemusíme dumpovat, panel nám ukáže co vrací

publikovani-na-fb-me-accounts

V reálné aplikaci by bylo vhodné proiterovat $accounts->data a uložit si je třeba do databáze, protože v jedné z položek je ten access_token, který nás zajímá.

Publikovat budeme na endpoint /{page-id}/feed, jehož dokumentace a všechny parametry co přijímá je rozepsaná zde. Pro test si do HomepagePresenter přidáme následující signál

public function handlePublishPost()
{
    $accounts = $this->facebook->api('/me/accounts');
    foreach ($accounts->data as $page) {
        if ($page->id == "425160755061") {
            $this->facebook->api('/' . $page->id . '/feed', 'POST', [
                'link' => 'https://www.kdyby.org/',
                'message' => 'testing publishing on page',
                'caption' => 'testing caption',
                'description' => 'testing description',
                'access_token' => $page->access_token,
            ]);
        }
    }
}

A do {else} větve v šabloně přidáme

<p><a n:href="publishPost!">Publikova na stránku</a></p>

Když teď klikneme na tento odkaz, měl by se na naši stránku přidat nový příspěvek

publikovani-na-fb-published

V tenhle moment by měla už být automatizace publikování příspěvků hračka. Já bych si buď udělal cron pomocí Kdyby/Console a nebo lépe nějaký RabbitMQ worker :)

TL;DR

Fungující aplikaci najdete na Githubu, stačí jenom doplnit appId, appSecret a fbPageId v config.local.neon.

Mám tu chybu? Fix me

Autor:

comments powered by Disqus