サルでもできるかもしれないFacebook連携 〜WordPressとの連動〜

この記事はだいぶ前に書かれたものなので情報が古いかもしれません
モンキーボード

この記事を三行にまとめると

Facebook連携をやってみます
Wordpressで連携してみます
俺にできてサルにできないことはない
さてさて、それではいつぞやの記事で言った通り、FacebookのAPIを使って連携する方法をば。

今回の目的としては、Wordpressで記事を公開した際に、Facebookの方で「記事を更新したよー」みたいなことを自動でつぶやくようにする感じです。それ以外の余計なことはあまり書かないようにします。ちょっとめんどいなと思うことも極力やらない。一直線に投稿を目指す感じです。ボケも少なめで行きたいと思います。

複雑なことをやろうと思えばそれなりに面倒で難しいと思うんですが、とりあえず連携さえできれば良いってんなら、そこまで難しくはない。たぶん、ちょっと頑張ればサルでもできる。僕にもできたくらいだから。サルにできて僕にできないことはあっても(服を一切着ないで動物園の中にいるとか)僕にできてサルにできないことはないですからね。

端折って端折って簡潔にどばーっと説明するつもりですが、それでもちょーっと長い話になるんで、WordpressでFacebook連携したいけどこんな長い記事を読むのはめんどいって人は、Facebookが公式のプラグインを出してるんで、それ使っちゃいやしょう。あとtwitterfeedとかいう、twitterとかFacebookに自動投稿できるサービスもあるみたい。どっちも使ったことないんで、使い方はよく分からないんですけど。

Facebook公式プラグイン

twitterfeed

ほんじゃあ、あかつき、行きまーす。



アプリを作成

こちらのFacebook開発者ってページに移動して、まずはアプリを作成します。

ページの上部にあるメニューの「アプリ」ってところに「新しいアプリを作成」っていう項目があるんで、そこをクリック。すると新しいアプリを作成する画面が立ち上がります。

アプリを作成

「Display Name」と「Namespace」ってのを入力するところがありますが、今回は両方とも「norm-nois」と入力してみます。Namespaceの方は未入力でも作成できるっぽいです。

アプリが無事に作成されると、アプリの管理ページにアクセスできるようになります。

ダッシュボード

これがnorm-noisというアプリのダッシュボードですね。何か塗りつぶしちゃったけど、別にアプリIDは隠す必要なかったかしら?

ここに表示されているアプリIDとアプリのシークレットキーは後でAPIを使うときに必要になるので、要チェックやで。シークレットキーの方は「表示」ってボタンを押せば見れます。「ほんとに見えてもええんか?」的なことを一度聞かれますけど。



基本設定

さっきの管理ページの左メニューに「設定」ってのがあるんですけど、そこで先に基本設定を済ませておきます。

設定

これが基本設定のページ。

ここで設定が必要なのは、画像の真ん中よりちょい上にある「App Domains」ってところ。

基本設定1

ここに、連携したいウェブサイトのドメインを入力します。今回の場合で言えば、あかつきのお宿を連携させたいので「norm-nois.com」ですね。今は空になってますが、ここを設定してないと、あとでAPIを使おうとしたときに「おたくのサイトは連携の許可ができてへんで〜」的なエラーが返ってきてAPIが使えません。

ただし、ただ単純にこの項目にドメインを入力して変更を保存ってやると、保存ができない。何か「設定に必要な条件が揃ってへんよ」みたいなことを言われてしまいます。

じゃあどうすればその必要な条件を満たせんのかってーと、画像の真ん中くらいに「+Add Platform」ってのがありますよね。それを押して、プラットフォームとやらを追加すればオーケーです。

Add Platform

このボタンを押すと、何かプラットフォームの選択画面みたいなのが出て来るんで、そこから「App on Facebook」ってやつを選択します。

追加すると、基本設定のページに更なる設定項目が追加されますので、そこで「キャンパスページURL」ってやつを入力します。

キャンパスページURL

今回はあかつきのお宿のトップページである「http://norm-nois.com」を入力してみました。

このキャンパスページっていうのは、Facebookで表示されるアプリページみたいなものでして、キャンパスページURLというのは、そのアプリページの中にiframeで読み込まれるページのURLです。

えーと、どういうことかってーと、キャンパスページURLの入力項目のちょい上にキャンパスページってのがありますよね。そこに「https://apps.facebook.com/norm-nois」って書いてありますが、これがFacebookのアプリページのURLです。このページにアクセスすると、キャンパスページURLで設定したページ(http://norm-nois.com)がiframeで読み込まれてると、そんな感じです。

ぶっちゃけ、今回の連携ではこのキャンパスページってやつは特に使用しないんですが、でもこのキャンパスページの設定をしないと、先ほどの「App Domains」ってやつが設定できないんで、しょうがないから(?)入力します。

ちなみに、キャンパスページである「https://apps.facebook.com/***」の***の部分は、Namespaceを設定していればNamespaceが入り、Namespaceが未入力の場合は、アプリIDが入るようになっているみたいです。まあ、だからやっぱりアプリIDは別に隠す必要はなかったってことだよね、たぶん。



SDKの準備

以上でFacebook側の設定は終わりなので、いよいよ開発に入って行きます。

今回はPHPでの開発を行うので、ここからPHPのSDKをダウンロードして、自分とこのサーバーにアップロードします。どこにアップするかはお任せします。おーまーかせ♪ おーまーかせ♪



アクセストークンの取得

FacebookのAPIを使うには、アクセストークンってやつが必要になります。

Facebookのアクセストークンには、ユーザートークンってのと、アプリトークンっていう2種類のトークンがあります。今回はユーザートークンってやつを使います。両者の使い分けは正直よく分かってないんですが、たぶんアプリとしてではなく、FacebookユーザーとしてAPIを使いたい場合はユーザートークンの方を使うんじゃないでしょうか。

本来ならユーザートークンを取得するためのコードってやつを自分でごちゃごちゃ書かなきゃならないんですが、SDKを使えばわりとあっさりトークンの取得やセットができます。

百聞は一見にしかず、新聞は一見もせず(そもそも新聞取ってねーし)。とりえあずコード書いてみましょう。

//SDKファイルの読み込み
require 'Facebook.php'

//初期設定
$config = array('appId' => アプリID, 'secret' => アプリシークレットキー);
$facebook = new Facebook($config);

//ユーザーIDを取得
$user_id = $facebook->getUser();

//ユーザーIDが取得できなかった場合
if(empty($user_id)) {
  $login_url = $facebook->getLoginUrl(array('scope' => 'publish_stream'));
  echo $login_url;
}

Facebook.phpってのは、ダウンロードしてきたSDKの中に入ってるファイルです。この記事を書いてるときと仕様が変わってなければ、「src」っていうフォルダの中に入ってるはずです。それを読み込む。

$user_idってやつにユーザーIDが入っていたらオッケーです。APIを使う準備が整っています。これから上手いことを言いそうなねづっちくらい整ってます。

えー……アプリケーションプログラムインターフェースとかけまして、円周率とときます。その心は……どちらもAPI。「A、PI」「あ、パイ」

よっし、上手くない!



もし$user_idってやつが空だったら、まあ最初は空の状態だと思うんですが、その場合は、「getLoginUrl()」ってやつを使って、ログインURL……連携認証用のURLとでも言うんですかね、そのURLを取得します。

この$login_urlの中には「https://www.facebook.com/dialog/oauth?・・・」っていうやたら長ったらしいURLが入ってるんですが、まあとりあえずそれをコピって実際にアクセスすると、認証が行われて、元のページに帰ってきます。元のページってのは、自分で$user_idだの$login_urlだのを取得するためのコードを書いたページっすね。

認証に成功してれば、今度は$user_idにユーザーIDが入ってるはずなので、これでAPIを使う準備が整いました。ガンダムのコックピットに乗り込んで「行きまーす」って叫ぶ直前のアムロくらい整ってます。

ちなみに、この$login_urlで取得したURLにアクセスする際、Facebookアプリページの基本設定で「App Domains」の設定をし忘れていると、エラーになるみたいです。だから先にやっとこう。





追記(2015/05/07)

なんか数日前から「scope」を「public_stream」にしていると認証が上手く行かなくてアクセストークンが取得できなくなってしまいました。何でだろ?

とりあえず自分のウォールに投稿するなら「public_actions」でもOKなので、もし僕と同じエラーが出たって場合は、scopeをpublic_actionsにして試してみてください。

//修正前
if(empty($user_id)) {
  $login_url = $facebook->getLoginUrl(array('scope' => 'publish_stream'));
  echo $login_url;
}

//修正後
if(empty($user_id)) {
  $login_url = $facebook->getLoginUrl(array('scope' => 'publish_actions'));
  echo $login_url;
}

ちなみにエラーの内容はこんなんです。

Invalid Scopes: publish_stream. This message is only shown to developers. Users of your app will ignore these permissions if present. Please read the documentation for valid permissions at: https://developers.facebook.com/docs/facebook-login/permissions




実際に投稿してみる

本来であれば、取得したユーザートークンとかを自分でセットしてデータをPOSTとかしなきゃならないんですが、SDKはその辺を上手いことやっちゃってくれるんで、上記のコードでユーザーIDが取得できていれば、あとはもう投稿に必要な情報(コメントとか画像とか)さえセットすれば、投稿はできます。

これも百聞は一見に何とやらで、コードだけ先に書いちゃいましょう。

//ウォールに投稿
$params = array(
  'name' => 記事のタイトル,
  'link' => 記事のURL,
  'description' => 記事のディスクリプション,
  'picture' => 記事の画像のURL,
  'message' => ウォールの本文,
);
$facebook->api('/me/feed/', 'POST', $params);

これでFacebookにウォールを投稿できます。

それぞれのパラメータが何を表してるかってーと……実際に見てもらった方が早いですかね。

投稿内容

これは先日僕が実際にここのブログと連携してFacebookに投稿したコメントなんですけど、この画像と照らし合わせると、上のコードのパラメータはこんな感じになります。

$params = array(
  'name' => '桜の花が咲く頃に 一つの恋が散りゆきて',
  'link' => 'http://norm-nois.com/blog/archives/2718',
  'description' => 'また新しい年度がスタートしましたねー(以下略)',
  'picture' => 'http://norm-nois.com/images/sample.jpg',
  'message' => '戯言妄想の記事を投稿っと',
);

こんなんですね。ディスクリプションと画像のURLはちょっと手抜きで書いちゃいましたが、こんな感じでパラメータを渡してリクエストを投げれば、ウォールに投稿できます。



WordPressで記事を公開

さて、ここまでで一応、Facebookに投稿する部分は作れたってことにして……これを使って、Wordpressで記事を公開したタイミングに合わせて自動的に投稿できるようにしてみましょう。

functions.phpに書いちゃっても良いでしょうし、プラグインにして有効化しちゃっても良いと思いますが、とりあえず僕はこんな感じでやったってのを書きます。異論は認める。

//投稿するメソッド
function post() {
  //公開済みの記事が編集された場合はつぶやかない
  if($_POST['original_post_status'] != 'publish') {
    require_once 'facebook.php';

    $config = array('appId' => アプリID, 'secret' => アプリシークレットキー);
    $facebook = new Facebook($config);

    //ウォールに投稿
    $params = array(
      'name' => 記事のタイトル,
      'link' => 記事のURL,
      'description' => 記事のディスクリプション,
      'picture' => 記事の画像のURL,
      'message' => ウォールの本文,
    );
    $facebook->api('/me/feed/', 'POST', $params);
  }
}

//Wordpressのアクションフック
add_action('publish_post', 'post');

Wordpressのアクションフックに「publish_post」ってのがあります。これは記事を公開したときに発動するフックなので、これで記事を公開したタイミングでpost()が呼ばれます。

ただし、このフックは新規に記事を公開したときだけでなく、公開中の記事を編集したときにも発動してしまいます。なので、単純にこのフックを使うだけだと、編集するたびにウォールに投稿されることになってしまう。

そこで、「$_POST[‘original_post_status’]」というやつの中身を見ています。この「original_post_status」には現在の記事のステータスが入ってます。「publish」ってのは公開の状態。下書きの状態だと確か「draft」とかだった気がする。

つまり、記事を新規に公開にするときはdraft、公開中の記事を更新するときはpublishが$_POST[‘original_post_status’]に入っているので、それで更新のときにはウォールに投稿しないように処理を分けています。

ちなみにこの場合、一度公開中の記事を下書きの状態に戻して再度公開ってやると、$_POST[‘original_post_status’]にdarftが入ってる状態になるからウォールに投稿されてしまいます。でもまあ、あかつきのお宿は僕の個人ブログだし、僕はたぶん一度公開した記事を下書きの状態に戻すことはないだろうってことで、運用対処にしちゃってます。だからこの辺の処理を厳密にやりたいのであれば、別な方法を検討する必要があります。今回はやらないですけど。



アクセストークンの有効期限について

Facebookのアクセストークンには有効期限ってのがあります。デフォルトだと1時間くらいで切れちゃうんですが、やり方次第でそれを60日に延長することができます。SDKを使ってユーザートークンを取得している場合は、SDK側で有効期限が60日になるような処理をやってくれてるんで、あまり気にしなくても良いかも。

でもしょせんは60日、2ヶ月ですからね。永続的に使えるわけじゃないんで、いつ取得したのか忘れちゃうと、ついうっかりトークンの有効期限が切れちゃってて連携できなかったなんてこともあるかもしれない。

かといって、切れるたびに例のgetLoginUrl()を使って取得するのも億劫というか、運用上あまりよろしくはないというか……できれば自動で取得したいっすよね。

まあ、トークンの有効期限を永続的にする方法もあるにはあるらしいんですが、ちょっと僕にはよく分からなかったので、今回はこんな感じで自動化してみました。

function getToken() {
  $config = array('appId' => アプリID, 'secret' => アプリシークレットキー);
  $facebook = new Facebook($config);

  //ユーザーIDを取得
  $user_id = $facebook->getUser();

  //取得できなかったらlogin_urlにリダイレクトする
  if(empty($user_id)) {
    $login_url = $facebook->getLoginUrl( array( 'scope' => 'publish_stream' ) );
    header('Location: '.$login_url);
    exit;
  }
}

//アクションフック
add_action('load-post-new.php', 'getToken');
add_action('load-post.php', 'getToken');

Wordpressには「load-ページ名」っていうフックがあるみたいで、そのページが読み込まれるときに発動します。Wordpressの管理画面を使っているときにURLを見れば分かるんですけど、記事の新規追加ページは「post-new.php」、編集ページは「post.php」となっていますので、それぞれ「load-post-new.php」「load-post.php」でフックが発動します。

これで、新規追加、及び編集ページを開いたときに、ユーザーIDが取得できなければlogin_urlに自動でリダイレクトさせる処理を実装しています。

厳密にいうと、ユーザーIDが取得できないとリダイレクト処理が走っちゃうんで、トークンの有効期限が切れてなくてもセッションが切れれば発動しちゃうんですけど、トークンの有効期限が切れるとユーザーIDの取得もできないような気がするので、とりあえず大丈夫かなーって思ってます。

実はまだFacebookとあかつきのお宿を連携するようになってから60日経ってないんで、これで大丈夫かどうかもまだ検証できてないんですけど、もしこの方法が有効じゃなかったら申し訳ねっす。そんときは違う処理を実装し直して、それをまた記事におこそうと思います。






ってなわけで、Facebook連携でしたー。

いやー、やっぱり長くなっちゃいましたねー、あっはっは。まあしゃーないっすわ。

説明は長ったらしいですけど、実際にやる作業はそんなに多くないので、安心してください。いつぞやの記事でも言いましたが、映画一本見ている間に完了できるくらいの作業です。ウルフ・オブ・ウォールストリートを見終わる頃には、Facebookのウォールにも投稿できるようになっているはずです。順調に行けばもっと短い時間で済むと思う。

もし興味があればお試しあれー。
 もしかしたら何か関連しているかも? 
 みんなからのコメント 
2014年05月25日 13:38:59
[…] 記事を書いてる途中でこんな記事を見つけた。後で試してみる。 自動記事投稿に関してはこちらのブログで解説とコードが公開されています。 ■サルでもできるかもしれないFacebook連携 | 日記の間 | あかつきのお宿 […]
2017年04月29日 15:01:05
匿名
コードはどこに書くのですか
2017年04月29日 21:31:54
まっち~(管理人)
この記事の例ではWordpressのプラグインを作ってその中にコードを書いています。「plugins」フォルダの中に適当なフォルダを作成して、その中にpost.phpみたいなファイルを作りました。SDKも一緒にアップしてます。

プラグイン化しない場合はfunctions.phpに書いてもオッケーです。SDKを適当なところにアップロードして、それをfunctions.phpからrequireなりincludeなりすればやることは同じです。