Facebookページでよくあるキャンペーンアプリ(申し込んだら抽選で○○が当たる的なやつ)の作成方法をそれなりに詳しく解説してみます。
事例
サンプルアプリのフロー
- いいねをしてもらう
- アプリ承認ページへ遷移して承認
- 入力ページを表示
- 確認ページを表示
- 完了ページを表示 + ウォールへの投稿
必要な環境
- PHP5.2以上(5.2未満だと Facebook SDKが動きません。最後にメモ書いときます)
- Facebook公式SDK
- http, https が利用できるサーバ(SSLは開発時のみ自己証明で可)
サンプルアプリのディレクトリ構成
src/ facebook.php base-facebook.php view/ page1.php page2.php page3.php page4.php page5.php index.php (controller) model.php
いちおMVCを意識してこんな構成に。framework使う場合は適宜、読み替えてください。
srcディレクトリは、Facebook公式SDKです。
前準備
サーバ準備
http、httpsが利用可能な開発環境を用意します。開発するだけならSSLは自己証明書(オレオレ証明)でいいです。
Facebookアプリの登録
ぐぐればいくらでも出てきますが、当サイトでも紹介してるので一応こちらもどうぞ
登録できたらPage Tabアプリ用の設定をしてあげます。
基本データ
Snadbox Mode: 開発中は「有効」にしておくと一般ユーザにアプリへのリンクが表示されません。
Facebookでログインするウェブサイト
サイトURL: http://www.facebook.com
ページタブ
ページタブ名: Facebookページからページタブへのリンク名
Page Tab URL: 自前アプリのURL(http)
Secure Page Tab URL: 自前アプリのURL(https)
ページタブの画像: Facebookページに載せるページタブ画像
Page Tab Width: 横幅いっぱいなら、通常(810px)を選択
# Page Tab URL は、今回のサンプルの場合、index.php へのURLとなります
アプリをページに登録する
Facebookページからアクセスしないと開発し辛いのでとりあえずページにアプリを登録してしまいます。
ブラウザで下のURLの「AppID」部分を変更してアクセス。
http://www.facebook.com/add.php?api_key=AppID&pages=1
こんな画面がでるので、ページを選択して追加します。
これで追加したページにアプリのリンクが表示されます。
(Sandbox がONなら管理者にしか表示されません)
開発準備
ソースダウンロード
設置予定のサーバへログイン、開発場所のディレクトリへ移動してサンプルアプリのソースをダウンロードして展開。
wget https://github.com/temog/pagetab/archive/master.zip -O pagetab.zip unzip pagetab.zip cd pagetab-master wget https://github.com/facebook/facebook-php-sdk/archive/master.zip -O sdk.zip unzip sdk.zip mv facebook-php-sdk-master/src/ . rm -rf facebook-php-sdk-master rm sdk.zip
これで「サンプルアプリのディレクトリ構成」と同じ状態になったはずです。
設定値入力
サンプルアプリでは index.php の冒頭部分に設定値があるので入力します。
class CampaignController { private $appId = ''; private $secret = ''; private $appUrl = ''; private $pageUrl = ''; private $scope = 'email, user_birthday, publish_stream'; private $wallParam = array( 'picture' => '', 'name' => '', 'caption' => 'caption', 'description' => 'description', );
10行目 $appId : アプリの App ID を入力
11行目 $secret : アプリの App Secret を入力
12行目 $appUrl : アプリのURLを入力。自前サーバのほうです。
13行目 $pageUrl : Page Tab アプリのURLを入力。Facebookページからアプリを開けばURLわかります。
14行目 $scope : APIで取得したい情報、利用したい機能を定義。publish_stream でウォール投稿が可能に。
16行目 picture : ウォール投稿に表示する画像URL
17行目 name : ウォール投稿に表示するアプリ名(じゃなくてもいいんだけど)
18行目 caption : ウォール投稿に表示されるはず、、なんだけど最近表示されないかも・・?
19行目 description : ウォール投稿に表示されるアプリ詳細
ソース説明
最低限しか書いてないので見ればわかると思いますが要所だけ簡単に説明を。
index.php
controller です。中身は、CampaignController クラスの定義とインスタンス作成して、dispatchメソッドをコールするのみ。
dispatch メソッドは、「Likeしてるか」、「アプリ承認してるか」などで表示する view を切り替えてます。以下、dispatch メソッドの中身解説。
if(! $this->signed_request){ // Facebookページ外からの利用。エラーぺーじへ $this->viewPage('error1.php'); }
constructor で signed_request には値セット済み。Facebookページからの遷移なら値がセットされます。セットされてないならFacebookページ以外からのアクセスと判定。
あとこの処理のあとに重複申し込みのチェックを書いとくといいです。
if(! CampaignModel::isLiked()){ $this->viewPage('page1.php'); }
いいね済みかチェック。判定ロジックは、model.php の static method に書いてます。
いいね未済みなら viewPage メソッドで、view/page1.php を表示。
else if(! CampaignModel::getUser()){ $url = CampaignModel::getLoginUrl($this->pageUrl, $this->scope); $this->viewPage('page2.php', array('url' => $url)); }
アプリ承認済みか判定して、未承認なら、アプリ承認URLを取得し、page2.php で javascript から遷移します。(直接Redirectできないため)
else if(! isset($_POST['page'])){ $userInfo = CampaignModel::getUserInfo(); // facebook から取得できるデータ見たかったら表示 // print_r($userInfo); $this->viewPage('page3.php', array( 'signed_request' => $this->signed_request, 'id' => $userInfo['id'], 'name' => $userInfo['name'], 'birthday' => $userInfo['birthday'], 'gender' => $userInfo['gender'], 'email' => $userInfo['email'], )); }
Like済み、アプリ承認済みならこちらへ。CampaignModel::getUserInfo メソッドでFacebookのユーザ情報を取得して、viewPage メソッドへ渡し、page3.php(サンプルでは入力ページ)を表示します。
取得できるユーザ情報は、$scope で指定した内容に依存するので注意。
else if(isset($_POST['page']) && $_POST['page'] == 'page4'){ /* * 普通このへんでフィルターとかバリデーション */ $this->viewPage('page4.php', array( 'signed_request' => $this->signed_request, 'id' => $_POST['id'], 'name' => $_POST['name'], 'birthday' => $_POST['birthday'], 'gender' => $_POST['gender'], 'email' => $_POST['email'], 'message' => $_POST['message'], )); }
page3.php(入力ページ)からの遷移。コメントに書いてますが、普通はフィルター、バリデーションが必要です(最低限バリデーションは)。バリデーションでこけたら page3.php を再表示、通ったら確認ページ(page4.php)を表示する、っていう流れになると思います。
else if(isset($_POST['page']) && $_POST['page'] == 'page5'){ $userInfo = CampaignModel::getUserInfo(); /* * 普通このへんでフィルターとかバリデーション */ /* * 申し込み情報をDBなり、ファイルなりに保存する。 * facebook id を保存しておけば重複申し込みを制限できる */ /* * ウォールへの投稿。ユーザの認識なしにウォール投稿は * Facebook規約に違反するので注意。 * * サンプルでは入力されてたら投稿します。 */ if($_POST['message']){ $param = $this->wallParam; $param['message'] = $_POST['message']; $param['link'] = $this->pageUrl; CampaignModel::postWall($userInfo['id'], $param); } $this->viewPage('page5.php'); }
確認画面からの遷移。フィルター、バリデーションは、一つ前の処理で共通化しとくといいと思います。
バリデーションが通ったら、申し込み情報をDBなりファイルなりに保存します。重複申し込みを制限したければ facebook id も保存しましょう。
ウォール投稿は、申込情報の保存成功後、処理するといいでしょう。ユーザの認識なしにウォール投稿するとFacebook規約違反になるので注意。
最後に viewPage メソッドで完了ページを表示して終わりです。
view/header.php
iframeでのTipsがいろいろあるので解説。
<script type="text/javascript" src="https://connect.facebook.net/ja_JP/all.js"></script>
以下で解説するスクロールバー非表示、スクロール位置調整で使うJavaScriptを読み込みます。
https にしとけば http https どちらでも使えるのでプロトコル判定とか書いてないです。
window.fbAsyncInit = function() { FB.init({ appId : '<?php echo $this->appId; ?>', status : true, cookie : true, xfbml : true, logging : true }) FB.Canvas.setAutoGrow(); FB.Canvas.scrollTo(0, 0); };
setAutoGrow()
これでiframeの高さ調整を自動でやってくれます。結果、スクロールバーが非表示になります。
scrollTo()
iframe 内でスクロール位置が画面幅に収まらないとき、次の画面に遷移すると、スクロール位置が下にいったままで、上のほうにあるコンテンツが最初から見えない状態になってしまいます。この問題を避けるために scrollTo(0,0)と指定しておけば画面遷移後、スクロール位置が一番上に行ってくれます。
PHP 5.2 未満でSDKを使う場合
SDKでは json関数を利用しているので5.2未満だと利用できません。
pecl から json関数をインストールして動かしてみてください。
pecl install json
ソースコード
GitHubに置いてます。temog/pagetab · GitHub