【WordPress】プラグインを使わずに投稿を公開するタイミングで自動でFacebookにも投稿する 

前回、[【WordPress】プラグインを使わずに投稿を公開するタイミングで自動でTwitterにもツイートする](http://qiita.com/hituziando/items/4421ee31a5b74a4ad0a0)、という投稿を書きましたが、今回はその続きで、**Facebookに自動投稿する仕組みを実装してみます。**
Twitterと同時にFacebookにも投稿できたら便利ですよね^^

前回の投稿をまだ読まれていない方は、まずはそちらを読んでください。

Facebookへの投稿は、個人のタイムラインにではなく、自分が管理しているFacebookページに投稿することを前提にします。

#やりたいこと

- WordPressの投稿の公開と同時にFacebookにも投稿する
- 投稿のテキストと一緒に画像も投稿する
- 自分が管理するFacebookページに投稿する

#Facebook SDKのセットアップ

[Facebook Developers](https://developers.facebook.com/)の登録、およびFacebookにアプリ(Webサイト)の登録は、すでに完了しているものとして話を進めます。

##SDKのダウンロード

まず、[PHP用Facebook SDK](https://developers.facebook.com/docs/php/gettingstarted)をダウンロードしてください。
※本稿を執筆した時点ではfacebook-php-sdk-v4-5.0.0.zipでした。

ダウンロードしたzipを適当なところに解凍し、src/FacebookディレクトリをWordPressプロジェクトの適当なところにコピーします。なお、僕はディレクトリ名をFacebookからfacebook-php-sdkにリネームしています。

次に、functions.phpに以下のように追記します。

```functions.php
include('/path/to/facebook-php-sdk/autoload.php');

// 名前空間のエイリアス
use Facebook\Facebook;
use Facebook\Exceptions\FacebookSDKException;
```

##APIキーを取得する

Facebook Developersおよびアプリの登録が完了していると、以下のようなダッシュボード画面にたどり着けると思います。

![fbdev.jpg](https://qiita-image-store.s3.amazonaws.com/0/73490/bce89409-d4c2-ec9f-b80d-cd519267d1ba.jpeg)

この画面上にある**アプリID**と**app secret**は、後で使いますのでメモします。

次に、**アクセストークン**を生成します。

右上にある「[ツール&サポート](https://developers.facebook.com/tools-and-support/)」をクリックします。

「Graph API Explorer」をクリックします。以下のような画面が表示されるかと思います。

![fb_graph_api.jpg](https://qiita-image-store.s3.amazonaws.com/0/73490/6733ee20-8a0f-b5e2-3d10-b37e74f78525.jpeg)

右上の「Graph API Explorer」をクリックし、登録したアプリ名を選択します。
「Get Token」をクリックし、「Get User Access Token」を選択します。

自分が管理するFacebookページに投稿するためには、以下のアクセス許可にチェックを入れます。

- manage_pages
- publish_pages
- publish_actions (不要かもしれない)

なお、自分が管理するページに投稿するだけならば、Facebookによるレビューは必要ありません。

[参考] https://developers.facebook.com/docs/facebook-login/permissions

アクセストークンが生成されますが、このままでは有効期限が1時間程しかありません。そこで、期間延長をします。本稿を執筆した時点では、延長した有効期限は**2ヶ月**です。

アクセストークンの横にある「i」マークをクリックします。
ポップアップ上にある「Open in Access Token Tool」をクリックします。
「Extend Access Token」をクリックします。

生成されたアクセストークンをメモします。

functions.phpにメモしたアプリID、app secret、アクセストークンを定義します。

```functions.php
include('/path/to/facebook-php-sdk/autoload.php');

// 名前空間のエイリアス
use Facebook\Facebook;
use Facebook\Exceptions\FacebookSDKException;

// Facebook APIキー
define('FB_APP_ID', '*********************');
define('FB_APP_SECRET', '*********************');
define('FB_ACCESS_TOKEN', '*********************');
```

#投稿の公開と同時にFacebookに投稿する

投稿が公開されたタイミングをフックする処理は前回と同じなので説明は割愛します。

Facebook SDKを利用して、画像とテキストを投稿します。
今回も画像は投稿のアイキャッチ画像に設定されている画像を利用します。テキストは、投稿のタイトルと本文の冒頭70文字、パーマリンクとします。

```functions.php
function hook_transition_post_status($new_status, $old_status, $post) {
  // 投稿のステータスが「新規追加」または「下書き保存」または「レビュー待ち」または「予約投稿」から
  // 「公開」へ変わった時にFacebookに自動投稿する
  if (($old_status == 'auto-draft'
    || $old_status == 'draft'
    || $old_status == 'pending'
    || $old_status == 'future')
    && $new_status == 'publish' && $post->post_type == 'post') {

    // Facebook API
    $fb = new Facebook(array(
      'app_id' => FB_APP_ID,
      'app_secret' => FB_APP_SECRET,
      'default_graph_version' => 'v2.6'  // ダッシュボード画面のAPIバージョンを指定しておく
    ));

    // FBに投稿するテキスト
    $message = '{{TITLE}}{{BR}}{{CONTENT}}{{BR}}{{URL}}';  // TODO: テンプレートを適当なところから取得
    $message = str_replace('{{TITLE}}', $post->post_title, $message);
    $message = str_replace('{{CONTENT}}', _excerpt(strip_tags($post->post_content), 70), $message); // HTMLタグを除去し冒頭70文字を抜粋
    $message = str_replace('{{URL}}', get_permalink($post->ID), $message);
    $message = str_replace('{{BR}}', "\n", $message);

    try {
      if (has_post_thumbnail($post->ID)) {
        // アイキャッチ画像があるならば写真付きで投稿
        $fb->post('/me/photos', array(
          'message' => $message,
          'source' => $fb->fileToUpload(_get_post_thumbnail_url($post->ID, 'large'))
        ), FB_ACCESS_TOKEN);
      } else {
        // アイキャッチ画像が無いならばリンクを投稿
        $fb->post('/me/feed', array(
          'message' => $message,
          'link' => get_permalink($post->ID)
        ), FB_ACCESS_TOKEN);
      }
    } catch (FacebookSDKException $e) {
      //echo $e->getMessage();
    }
  }
}
add_action('transition_post_status', 'hook_transition_post_status', 10, 3);

/**
 * アイキャッチ画像のURLを取得します
 */
function _get_post_thumbnail_url($post_id, $size) {
  $image_id = get_post_thumbnail_id($post_id);
  $images = wp_get_attachment_image_src($image_id, $size);
  $image_url = $images[0];
  return $image_url;
}

/**
 * 指定した文字列を先頭から指定した文字数分だけ抜粋した文字列を返します
 */
function _excerpt($text, $char_length = 40) {
  $excerpt = $text;
  if (mb_strlen($excerpt) > $char_length) {
    return mb_substr($excerpt, 0, $char_length).'...';
  } else {
    return $excerpt;
  }
}
```

これでFacebookにも投稿することができるようになりました。
前回同様、テンプレートをテーマオプションやカスタムフィールドから取得すれば、より柔軟に対応できます。

---

#参考

[facebook for developers: Facebook SDK for PHP Reference (v5)](https://developers.facebook.com/docs/php/api/5.0.0)
[facebook for developers: アクセス許可のリファレンス](https://developers.facebook.com/docs/facebook-login/permissions)