Несмотря на некоторое внешнее сходство ВКонтакта и Facebook'a (а также на наличие понятия "приложения", которые пользователи могут себе добавлять и запускать) в реальности это сильно разные вещи. Среди прочего, разница заметна по предоставляемым обеими системами API.
Если взять ВКонтакт, то его API (я сейчас говорю не о userapi.com , который скорее надо сравнивать с Facebook Connect , а о внутреннем API ) то разработчику предоставляется возможность загрузить Flash приложение на сервер ВКонтакта, получать из этого приложения некоторую информацию об окружающей среде:
- Через Application.parameters: с чьей страницы запущено приложение, у кого запущено приложение, его права, права в группе (если приложение в группе).
- Через запросы к ВКонтактовскому серверу: работа с сессиями, сохранение на сервере и извлечение переменных и сообщений
Всё достаточно просто и ясно, хотя и сильно ограничено как по предоставляемым возможностям, так и с точки зрения технической реализации.
С Facebook всё иначе. Приложения - это не только Flash, но и любые другие (JS, PHP и пр.), а хранятся они не на сервере Facebook, а на хостинге разработчика. Есть огромное и подробное, но при этом сумбурно и невнятно документированное API, в котором вдобавок недавно произошли изменения отражённые не полностью.
Попробую изложить, как я понял это сам. В отличие от ВКонтакта с его "добавлением приложения на страничку пользователя" здесь всё куда менее однозначно. Существуют как минимум следующие понятия:
- Добавление приложения в profile box (раздел Profile, левая колонка)
- Добавление приложения в profile tab (раздел Profile, новый tab)
- Добавление приложения в profile info (раздел Profile, Info tab)
- Добавление приложения в букмарки
- Авторизация приложения (разрешает некоторые дальнейшие действия)
В последние месяцы у них произошли серьезные изменения в результате которых прежнее понятие "добавление в профайл" устарело и теперь появились новые, в первую очередь Profile Tab и "авторизация приложения"
Углубляться в детали не будем, рассмотрим ситуацию наиболее близкую по смыслу к ВКонтактовскому "добавлению приложения".
В Facebook'e есть понятие profile tabs. Если нажать на Profile то там можно увидеть табы "Wall", "Info" и "+". Приложения добавляются как раз сюда. Что для этого нужно сделать (как вариант):
1.Зайти на так называемую canvas страницу с понравившимся приложением (оно там само по себе - ему не передается id владельца) . Например: http://apps.facebook.com/facebookbridge/
2.Авторизовать это приложение. Если приложение вызывает например $facebook->require_login(); , то при попадании на canvas страницу с ним facebook автоматически запросит авторизацию. Если нет, это можно сделать принудительно переходом по ссылке типа:
<a href="http://apps.facebook.com/fbtest" requirelogin=1> Add (authorize) app</a>
или через FBML:
<fb:if-is-app-user>
<!-- your normal code -->
<fb:else>
<fb:redirect url="http://www.facebook.com/login.php?v=1.0&api_key=[your_app_key]&next=[your_canvas_page_URL]&canvas="/>
</fb:else>
</fb:if-is-app-user>
3.Учтите, что для данного приложения обязательно должны быть заполнены поля Profile Tab URL (например '?test') и Profile Tab Name (например "App Tab") в "My Applications/Edit settings", иначе следующее действие не сработает.
4.После авторизации идёте в Profile, нажимаете "+" и видите, что среди вариантов добавляемых табов появилось название этого приложения. Выбираете его, у вас появляется новый таб, при переходе на который должно открыться это приложение.
Однако, приложение там ограничено в своих действиях. Flash показывается только после клика на него мышкой (вначале показывается заданная картинка), IFRAME не работает. И масса других тонкостей.
Все эти страдания, однако, имеют цель. Дело в том, что только приложение запущенное внутри Profile Tab может получить uid владельца Profile'a (fb_sig_profile_user) , а не только текущего/смотрящего пользователя, как в canvas'e (fb_sig_user). Соответственно, можно показывать какие-то данные с привязкой к владельцу.
Здесь, впрочем, возникает новая проблема - недоступен на этот раз уже URL посетителя - fb_sig_user
Пишут, что because of privacy и не лечится.
Ещё раз: приложение в Profile Tab не может узнать кто его смотрит. В результате непонятно как выяснить, разрешать смотрящему редактировать в нем данные или нет (т.е. для приложения смотрящий и владелец профайла, куда оно добавлено - неразличимы).
Выход видится в следующем:
Приложение различает внутри себя две ситуации - оно в Profile Tab, либо оно на Application page/Canvas (можно даже сделать два разных приложения для этих ситуаций).
Если оно в Profile Tab, показываем собственную кнопку "Редактировать". При нажатии на неё переходим в Canvas, передавая в query string fb_sig_profile_user (id пользователя у которого в профайле стоит приложение). В Canvas'e нам доступен fb_sig_user (id текущего пользователя). Имея эти два id, можно сравнить и сделать вывод - владелец это или гость.
Оба id передаются (наряду с некоторой другой информацией) через $_REQUEST (php), Application.parameters (AS)
(упомяну, что подделка передаваемого fb_sig_profile_user ничего не даст злоумышленнику, т.к. если он подделывает чужой id, тот не совпадёт с его текущим, а если свой собственный, то в этом нет смысла )
Если помимо fb_sig_* мы хотим получать ещё какую-то информацию или осуществлять взаимодействие с Facebook API из приложения на Flex/Flash, то здесь появится ещё одна тонкость. Flex классы для Facebook'a работают через JS Bridge. Т.е. обращаются к внешним JS функциям, которые в свою очередь обращаются к Facebook-овскому REST серверу.
Это будет работать (хотя, теперь уже тоже не факт) если Flex приложение запущено из Canvas'a. Но если оно запущено в Profile Tab, JS Bridge работать не будет и нужно обращаться к серверу напрямую (см. предыдущий пост про безопасность).
Сразу скажу, что в документации указан старый адрес Facebook API сервера - http://api.facebook.com/restserver.php. Новый такой: http://api.new.facebook.com/restserver.php . Причём, у нового в корне лежит crossdomain.xml, так можно обращаться прямо из Flex'a.
Кроме двух перечисленных представлений приложения (Canvas и Profile Tab) есть еще одно - Profile Box. Это маленький блок в левой колонке на странице Profile.
Для того, чтобы приложение что-то там отобразило, необходимо сделать две вещи:
1.Вызвать profile.setFBML() в одном из параметров которого указать что именно надо вывести (кстати, этот вызов сработает только из Canvas'e, но не из Profile Tab).
2.Отобразить кнопку "Add Profile" через FBML: <fb:add-section-button section="profile" />
Нажатие на эту кнопку вызовет появление заданного кода в Profile Box колонке.
Напоследок ещё одна неочевидная вещь. Чтобы удалить приложение (есть два варианта - Remove и Block) надо нажать слева внизу на Application и там Edit. Строго говоря, ни то ни другое не удалит приложение бесследно. Однако "Block" в принципе должно хватать во всех случаях :)
В целом впечатление от Facebook'a такое, как будто когда-то хотели сделать всё красиво и по уму, но с определенного момента правильные идеи были забыты. Более того, изменения которые происходят в API часто не отражены в документации, народ в форуме тычется вслепую, разработчики толком ничего не отвечают (есть, как минимум, штук пять очень важных вопросов, которые повторяются месяцами и всегда остаются без ответа).