Desenvolvendo iframe apps no Facebook com PHP – 5 dicas importantes

Em cada aplicativo que desenvolvemos aqui na Polvo aprendo uma porção de coisas novas, as quais gostaria de compartilhar agora. A documentação do Facebook não é excepcional, então tive que ir garimpando muitas coisas na internet.

Como na internet há muita informação boa, mas também muita coisa ruim, em alguns momentos utilizei métodos que acreditava estarem corretos quando, na verdade, tinham uma funcionalidade bastante limitada. Bastava terem alguns votos no fórum do StackOverflow e já via isso como correto.

Na segunda app que fui fazer, alguns códigos que estava utilizando na primeira não funcionavam mais, então fui filtrando um pouco mais o que achava na internet, refiz várias coisas e cheguei a algumas conclusões importantes, que aqui posto como dicas, e são elas:

1) Tudo pode ser feito utilizando a SDK do Facebook

Após baixar a SDK do Facebook (que está nesse link aqui), estava me complicando no momento de fazer a autenticação do usuário. Na segunda app é que fui descobrir como fazer isso de maneira correta. Na internet achei um método chamado oauth(), que eu fazia de maneira separada à SDK do Facebook, e que aparentemente funcionava, mas depois descobri que utilizar este recurso não é saudável para o código da app.

Depois de instanciar a classe Facebook, você pode pegar o endereço de login através de um método chamado getLoginUrl(), através do qual é possível passar uma url de retorno e o scope, que são as autorizações necessárias para o funcionamento da app (fotos, e-mail, etc).

Então, ao acessar a app, fiz o seguinte método:

private function getFacebook(){

   $facebook = $this->constructFacebook();

   if (!$facebook->getAccessToken()){
      $this->retornaHome($facebook);
   }

   try {
      $user_profile = $facebook->api('/me');
   } catch(FacebookApiException $e) {
      $this->retornaHome($facebook);
   }
   return $facebook;
}

Este é um método privado que chamo em todos os métodos da app. Primeiramente, ele chama o método constructFacebook(), que é o método que instancia a classe da SDK do Facebook:

private function constructFacebook(){
   $config = array();
   $config['appId'] = self::APP_ID;
   $config['secret'] = self::SECRET;
   $config['cookie'] = true;

   return new Facebook($config);
}

Onde self::APP_ID e self::SECRET são constantes que criei na classe da minha app com os valores que peguei lá das configurações da app no Facebook.

Tendo o objeto $facebook instanciado, agora eu posso verificar a existência de um access token. Para isso eu utilizo o método $facebook->getAccessToken(). Caso ele não retorne um valor, será chamado o método retornaHome(), que mostrarei abaixo. Depois eu faço uma pequena verificação utilizando a api graph, que tenta pegar alguns dados do usuário atual. Caso não conseguir, ele também chama o retornaHome().

Esse método retornaHome() é responsável por levar o usuário para a tela de login do Facebook, onde ele irá checar as autorizações necessárias para o funcionamento do aplicativo. Se o usuário já estiver logado e tiver autorizado o scope previamente, ele será levado automaticamente à página inicial da app.

O método retornaHome() consiste em:

private function retornaHome($facebook){

   die("<script> top.location.href='" . $facebook->getLoginUrl(array("canvas"=>1, "redirect_uri"=>self::APP_URL_SEM_BARRA,"scope"=>array("publish_stream","user_photos","email"))) . "'</script>");

}

Ou seja, aí ele faz um direcionamento, utilizando javascript, para a página de login do Facebook. Para saber qual é o endereço dessa página, eu chamo o método getLoginUrl(), no meu objeto $facebook já existente. Para este método estou passando três parâmetros:

canvas – Informa se a minha app está dentro de um canvas ou não (1 para verdadeiro e 0 para falso)

redirect_uri - Endereço da minha app sem a última barra. Para parametrizar, preferi salvá-la em uma constante dentro da classe. Ela possui valor de “https://apps.facebook.com/nomedaminhaapp”.

scope – São as autorizações que necessito, passadas por array, sendo elas “publish_stream”, que é a autorização para eu publicar na linha do tempo do usuário, “user_photos”, que é para eu acessar os álbuns dele e “email”, para eu ter essa informação e, por segurança, salvar em minha base.

Feito isso, já tenho como autenticar o usuário em todas as minhas páginas: basta chamar o método getFacebook().

2) Links dentro do iframe

A primeira página está em perfeito funcionamento, consigo pegar informações do usuário, etc. Então eu tinha o seguinte link:

<a href="pagina2.php">Link para a página 2</a>

Aí, quando eu tentava pegar alguma informação do usuário na página 2, não funcionava. Em algumas ocasiões, funcionava no Chrome, mas no Internet Explorer o problema persistia. Então descobri que o signed_request, que a classe Facebook vai ler e pegar as informações do usuário, vem através do cabeçalho do Facebook, e não da app, ou seja, na primeira vez que abria, o cabeçalho do Facebook era carregado, então eu tinha o signed request. Como eu tinha um link dentro do iframe, na segunda página ele não era carregado, então eu perdia as informações.

Isso foi solucionado apontando os links para o próprio facebook, da seguinte maneira:

<a href="https://apps.facebook.com/nomedaminhaapp/pagina2.php?var1=1&var2=2" target="_top">Link para a página 2</a>

Ou seja, ele irá carregar a página que eu queria, só que dando reload na página inteira. Ao dar esse reload, o signed_request é carregado novamente e eu consigo ter informações do usuário. O target=”_top” é importante pois estou direcionando um link de dentro do iframe para fora. Esse endereço irá carregar a página www.enderecodocanvas.com.br/pagina2.php e enviar as variáveis do método get normalmente.

3) Formulários

Depois de ter arrumado os links, percebi que meus formulários não estavam funcionando. O action deles tem que ser alterado da mesma maneira que os links, e também deve ser inserido um target=”_top”. O method deve ser setado para GET.

<form action="https://apps.facebook.com/nomedaminhaapp/targetdoform.php" method="GET" target="_top"></form>

Você também pode fazer o action como o endereço do seu canvas, processar as informações lá e depois voltar para o facebook com um redirect. Isso pode ser útil quando for necessário um upload de arquivo.

<form action="https://www.meucanvas.com.br/targetdoform.php" method="POST" target="_top" enctype="multipart/form-data">
   <input type="file" name="foto">
</form>

4) FQL Multiquery pode economizar muito tempo de processamento na sua app

Na primeira app que fiz, eu trabalhei da seguinte maneira: fiz uma query para pegar a lista de álbuns da pessoa. Depois de ter esse array já no php, dei um foreach() nele e, dentro de cada um, fiz uma nova query para pegar as fotos. Caso a pessoa tivesse 15 álbuns, eu fazia 16 queries: uma para a lista de álbuns e 15 para pegar as fotos de cada um deles. Cada uma levava em torno de 1 segundo para ser executada, gerando um tempo de processamento de 16 segundos. Parece pouco, mas para uma app ou para um piloto de Fórmula 1 é muita coisa.

Então descobri que podia fazer todas essas queries em uma só, ou seja, ao invés de usar:

$albuns = $facebook->api(array(
"method" => "fql.query",
"query" => "SELECT aid FROM album WHERE owner=me()"
));

E depois fazer a mesma coisa para as fotos, passei a usar:

$fql = '{
"data_album" : "SELECT aid FROM album WHERE owner=me()",
"photos" : "SELECT object_id FROM photo WHERE aid IN (SELECT aid FROM #data_album)",
}';

$params = array(
'method' => 'fql.multiquery',
'queries' => $fql
);

$albuns_fotos = $facebook->api($params);

Dessa maneira, consegui colocar todos os álbuns e fotos dentro da variável $albuns_fotos. Isso reduziu o tempo de execução de 16 segundos para 1, uma redução de 93,75%, o que é um valor bastante considerável. Para mais informações de como trabalhar com as FQL’s, clique aqui.

5) Salve informações do usuário em sua base utilizando o método getUser() e a api graph

Caso você quiser pegar o id do usuário que está utilizando sua app, basta utilizar o método $facebook->getUser();

Caso queira pegar mais informações, como nome, sexo, localização ou e-mail (caso você tiver colocado email no seu scope), você poderá fazer a seguinte consulta:

$user_profile = $facebook->api('/me','GET');

A variável $user_profile conterá um array com diversas informações sobre o usuário. Aí basta salvá-las. Vale lembrar que, quanto mais informações você colocar no scope, na hora de fazer o getLoginUrl(), maior é a chance de o usuário desistir de usar sua app. Portanto, use esta ferramenta com moderação. Você também pode salvar a quantidade de usuários que chegam ao método getLoginUrl() mas que acabam não utilizando a sua app, o que pode te dar uma ideia da taxa de conversão. Se estiver muito baixa, verifique se não está pedindo dados demais.

É isso aí, valeu e até a próxima! =)

Presença na web

Sua empresa criou um site, uma página no Facebook, um perfil no Twitter, um canal no YouTube e uma conta no Instagram, mas ainda não sabe o que vai fazer com todas essas ferramentas?

Se você chegou até aqui quer dizer que tem interesse e se preocupa com a impressão da sua marca, empresa, produto ou serviço na internet. Esse é um ótimo começo, mesmo! Mas pode ser que todas estas ferramentas listadas acima não sejam úteis para seu público-alvo e consequentemente para sua empresa. Porque nas redes sociais seu trabalho deve ser totalmente focado no seu cliente, que também pode ser chamado de fã ou seguidor, ou seja, ele é quem guia a sua atuação nessas mídias.

Importante é gerar conteúdo interessante e que agregue algum valor, conhecimento ou informação que seu “fã” julga valiosa para ele. Para que lhe agregue algo e depois ele lembre que sua marca disse isso, mostrou uma solução para o problema dele.

A presença online de uma empresa é baseada em dois pontos: na geração de conteúdo relevante para seu cliente e no conteúdo relativo à sua empresa que esses clientes publicam nas redes sociais. E é nessa questão de conteúdo publicado pelos clientes que é preciso cuidado. Considerando que não há como proibir na internet, é possível reverter uma situação negativa gerada, mas é mais importante evita-la. É nesse momento que faz a diferença contar com profissionais da área que sabem o quê e como deve ser feito esse trabalho. Para que eventuais dificuldades maiores sejam evitadas e sua marca só ganhe com a presença nas redes sociais.

As olimpíadas de Londres na internet

Em 2008, há quatro anos, durante as Olimpíadas de Pequim, o cenário digital e virtual do mundo era muito diferente. Principalmente para as redes sociais, que tinham os recém-nascidos Twitter e Facebook com 3 e 100 milhões de usuários, respectivamente. Valores que, comparados aos números de hoje, soam inexpressivos: confira no último infográfico da Polvo Digital, que retrata o acesso à internet no Brasil neste período.

Mas hoje, com a evolução tecnológica em crescimento constante e com a grande aceitação e uso de smartphones, tablets e computadores para o acesso à internet, principalmente as redes sociais, esse panorama mudou. Para ilustrar essa informação, temos um dado espantoso: somente durante a a abertura dos jogos Olímpicos de Londres, cerca de 900 milhões de usuários no Facebook compartilhavam imagens e comentavam sobre o evento. Isso significa que o número de pessoas na rede social interagindo com o evento foi maior do que toda a população da Europa!

E é por isso e muito mais que as Olimpíadas de Londres estão sendo chamadas de “Jogos das Mídias Sociais”. Tanto é que durante a cerimônia de abertura, Tim Berners-Lee, o inventor da “World Wide Web”, participou do evento e tuitou sobre o que acontecia ao vivo, direto de seu smartphone.

Os jornalistas e entusiastas que estão participando dos jogos não largam os notebooks e smartphones para publicar notícias a todo o momento. Assim como muita gente do Brasil e de outras nacionalidades, que também noticiam o que acontece na capital inglesa direto de suas casas, como vemos nas redes sociais Twitter e Instagram:

O Pinterest, a rede social mais recente entre as envolvidas com os jogos, também não ficou por fora e recebe “pins” de imagens relacionadas às Olimpíadas o tempo todo, de diferentes lugares do mundo.

         

No YouTube são encontradas transmissões ao vivo, além de vídeos de todas competições olímpicas. Assim é possível rever os melhores momentos ou assistir àquela partida não pode ser conferida ao vivo. Lembra que anos atrás era preciso programar o vídeocassete para gravar da televisão? :)

O Google não ficou de fora: além do doodle homenagear um esporte diferente por dia durante as Olimpíadas, o site também proporciona uma barra com informações sobre os jogos – datas, contagem de medalhas, calendário:

Ou seja: pra quem está online, é praticamente impossível não saber o que está acontecendo nos jogos do outro lado do oceano. Seja pelo smartphone, pelo tablet ou pelo notebook, não é mais preciso ficar conectado na programação da televisão para acompanhar o que acontece, muito menos preencher uma tabela feita à mão para contar os pontos ou medalhas dos países.

O mundo está conectado pelas redes sociais e os esportes estão aí para provar isso. Porque um jogo de futebol, uma Copa do Mundo, uma Olimpíadas, um jogo de vôlei, uma luta do UFC, uma corrida de Fórmula 1 e muitos outros eventos esportivos são relatados praticamente na íntegra nas redes sociais. Porque “está se tornando comum assistir esportes em uma segunda tela, como no computador, tablet ou smartphone”, segundo a autora do livro A Twitter Year: 365 days in 140 caracters, Kate Bussman. E isso é facilmente percebido nas noites de quarta-feira, quando o futebol do Campeonato Brasileiro se torna o assunto mais comentado no Twitter ou Facebook.

E esse deve ser só o começo, porque a evolução tecnológica não parou no smartphone, no tablet e muito menos nas redes sociais. Vamos esperar para ver?