クイックスタートチュートリアル

このチュートリアルでは、初めてMessengerエクスペリエンスを構築する際に知っておくべきことがすべて網羅されています。始める前に、スタータープロジェクトにあるオプションの中から1つを選んで開始するために必要なコードを入手した後、スタートガイドに示されている手順を実行して設定してください。

完成したコードを見たいだけの場合は、どうしたらいいですか?問題ありません!GitHubで見ることができます。

内容

スタータープロジェクト

このクイックスタートを開始する前に、以下のいずれかを実行して、必要になるスターターコードを入手してください。スターターコードは、Messengerエクスペリエンスの基礎として使うことになる基本的なWebhookを提供します。

オプション1: 自分でビルドする

当社のWebhook設定ガイドでは、このクイックスタートで使うことのできる最初のWebhookをビルドする作業が、最初から最後まで説明されています。

Webhookをビルドする

オプション2: GitHubからダウンロードする

WebhookスターターコードをGitHubからダウンロードし、自分のサーバーにデプロイします。

コードをダウンロードする

オプション3: Glitchでリミックスする

Webhookをデプロイするサーバーがない場合は、Glitch上でMetaのスターターWebhookプロジェクトをリミックスできます。そうすることで、Webhook用のHTTPSのパブリックURLが提供されます。

Glitch上で独自のWebhookを作成する手順は、次のとおりです。

  1. GlitchでスターターWebhookプロジェクトを開きます。 Glitchでリミックスする
  2. [Remix Your Own]ボタンをクリックします。これで、プロジェクトのコピーが作成されます。
  3. 左上のドロップダウンメニューをクリックして、プロジェクト説明にある公開URLをコピーします。これが、WebhookのベースURLになります。
  4. アプリ設定ガイドに従って、WebhookでFacebookアプリをサブスクリプション登録します。Webhook URLは、Glitch URLに/webhookを追加したものです。
    https://

利用を開始する

初めてMessengerエクスペリエンスをビルドする前に、まずアプリの資格情報を設定します。

1
Facebookアプリを設定する

アプリ設定ガイドに従って、Messengerプラットフォームで使えるようにFacebookアプリを設定します(まだしていない場合)。

アプリを開発モードにする

アプリがMessengerで一般公開されるように申請して承認されるまでは、ページトークンがページに許可するのは、アプリの管理者、開発者、テスト担当者のいずれかの役割を付与されているFacebookアカウントとのやり取りだけです。

それらの役割を他のFacebookアカウントに付与するには、アプリ設定で[役割]タブにアクセスしてください。

2
ページアクセストークンを生成する

MessengerプラットフォームAPIに対するすべてのリクエストは、クエリ文字列のaccess_tokenパラメーターにページレベルのアクセストークンを含めることにより認証されます。

Facebookアプリ設定時にしていなかった場合は、以下を実行してページアクセストークンを生成ます。

  1. アプリのMessenger設定の[トークン生成]セクションの[ページ]ドロップダウンから、トークン生成の対象となるFacebookページを選択します。[ページアクセストークン]フィールドにアクセストークンが表示されます。
  2. [ページアクセストークン]フィールドをクリックして、クリップボードにコピーします。

生成されるトークンはこのUIに保存されません。ドロップダウンからページを選択するたびに、新しいトークンが生成されます。新しいトークンが生成されても、それ以前に作成されたトークンは引き続き機能します。
3
ページトークンを環境変数として保存する

ページアクセストークンなどの機密情報は、Webhookにハードコーディングしないことにより、安全に保管してください。

そのためには、環境変数に下記のものを追加します。ここで、<PAGE_ACCESS_TOKEN>は先ほど生成したアクセストークン、<VERIFY_TOKEN>はWebhookを確認するために設定したランダムな文字列です。

PAGE_ACCESS_TOKEN="

Glitchの環境変数

Glitchを使っている場合は、提供されている.envファイルで環境変数を設定することにより、それが他のGlitchユーザーから見られないようにしてください。

4
Webhookにページを追加し、トークンを検証する

あとは、app.jsファイルの先頭にページアクセストークンを追加し、トークンを認証するだけです。こうすると、自分のWebhookロジックで使えるようになります。

const PAGE_ACCESS_TOKEN = process.env.PAGE_ACCESS_TOKEN;
const VERIFY_TOKEN = process.env.VERIFY_TOKEN;

設定完了

では初めてのMessengerエクスペリエンスを構築しましょう!

エクスペリエンスを構築する

このチュートリアルでは、以下のことをするシンプルなMessengerエクスペリエンスを構築します。

受信Webhookイベントから、メッセージと送信者のPage-scoped IDを解析します。

messagesmessaging_postbacksのWebhookイベントを処理します。

送信APIでメッセージを送信します。

テキストメッセージにテキストメッセージで返信します。

添付画像に対して、受信した画像を使った汎用テンプレートで返信します。

ポストバックペイロードに対して、条件に応じて返信します。


1
ハンドラー関数をスタブする

まず、送信APIで返信するだけでなく、サポートする受信Webhookイベントタイプを処理する3つの関数をスタブします。そのためには、app.jsファイルに以下を付加します。

// Handles messages events
function handleMessage(sender_psid, received_message) {

}

// Handles messaging_postbacks events
function handlePostback(sender_psid, received_postback) {

}

// Sends response messages via the Send API
function callSendAPI(sender_psid, response) {
  
}
2
送信者のPage-scoped IDを取得する

Messengerで返信するために最初にする必要があるのは、相手がだれかを知ることです。Messengerでは、受信Webhookイベントからメッセージ送信者のPage-scoped ID (PSID)を取得することにより、それができます。

PSIDとは?


ユーザーが開始するスレッドの相手となるFacebookページごとに一意のPage-scoped ID (PSID)がユーザーに割り当てられます。このPSIDは、メッセージ送信時にユーザーを識別するために使われます。

前述のスタータープロジェクトに示されているいずれかのオプションを実行したなら、次のような基本的な/webhookエンドポイントができているはずです。このエンドポイントは、POSTリクエストを受け入れ、受信したWebhookイベントの本文をログ記録します。

app.post('/webhook', (req, res) => {  

  // Parse the request body from the POST
  let body = req.body;

  // Check the webhook event is from a Page subscription
  if (body.object === 'page') {

    // Iterate over each entry - there may be multiple if batched
    body.entry.forEach(function(entry) {

      // Get the webhook event. entry.messaging is an array, but 
      // will only ever contain one event, so we get index 0
      let webhook_event = entry.messaging[0];
      console.log(webhook_event);
      
    });

    // Return a '200 OK' response to all events
    res.status(200).send('EVENT_RECEIVED');

  } else {
    // Return a '404 Not Found' if event is not from a page subscription
    res.sendStatus(404);
  }

});

送信者のPSIDを入手するには、以下のコードを入れてbody.entry.forEachブロックをアップデートし、イベントのsender.idプロパティからPSIDを抽出します。

body.entry.forEach(function(entry) {

  // Gets the body of the webhook event
  let webhook_event = entry.messaging[0];
  console.log(webhook_event);

  // Get the sender PSID
  let sender_psid = webhook_event.sender.id;
  console.log('Sender PSID: ' + sender_psid);

});

やってみましょう!


Messengerを開き、Messengerエクスペリエンスに関連付けられているFacebookページにメッセージを送信します。Messengerでは返信を受信しませんが、PSIDを含むメッセージが、Webhookが実行されているコンソールにログ記録されているのを確認できます。
Sender PSID: 1254938275682919
3
Webhookイベントタイプを解析する

ここでは、messagesmessaging_postbackの2つのタイプのWebhookイベントを処理できるエクスペリエンスにします。イベントタイプの名前はイベント本文に含まれませんが、特定のオブジェクトプロパティをチェックすることにより判別できます。

Webhookイベントとは?


Messengerで発生するアクションについて通知するWebhookイベントがMessengerプラットフォームから送信されます。POSTリクエストがWebhookに実行され、イベントはJSON形式で送信されます。詳しくは、Webhookイベントをご覧ください。

そのためには、Webhookのbody.entry.forEachブロックを更新して、受信したイベントにmessageまたはpostbackのプロパティが含まれているかどうかをチェックする条件を含めます。また、前にスタブしたhandleMessage()関数とhandlePostback()関数への呼び出しを追加します。

body.entry.forEach(function(entry) {

  // Gets the body of the webhook event
  let webhook_event = entry.messaging[0];
  console.log(webhook_event);


  // Get the sender PSID
  let sender_psid = webhook_event.sender.id;
  console.log('Sender PSID: ' + sender_psid);

  // Check if the event is a message or postback and
  // pass the event to the appropriate handler function
  if (webhook_event.message) {
    handleMessage(sender_psid, webhook_event.message);        
  } else if (webhook_event.postback) {
    handlePostback(sender_psid, webhook_event.postback);
  }
  
});
4
テキストメッセージを処理する

これで、受信メッセージが適切なハンドラー関数にルーティングされるようになったので、handleMessage()を更新して、基本的なテキストメッセージを処理し、それに返信するようにします。そのためには、コードを更新して返信のメッセージペイロードを定義し、それからそのペイロードをcallSendAPI()に渡します。基本的なテキストメッセージで返信するには、"text"プロパティを使ってJSONオブジェクトを定義します。

function handleMessage(sender_psid, received_message) {

  let response;

  // Check if the message contains text
  if (received_message.text) {    

    // Create the payload for a basic text message
    response = {
      "text": `You sent the message: "${received_message.text}". Now send me an image!`
    }
  }  
  
  // Sends the response message
  callSendAPI(sender_psid, response);    
}
5
送信APIでメッセージを送信する

いよいよMessengerプラットフォームの送信APIを使って最初のメッセージを送信します!

現在、handleMessage()callSendAPI()を呼び出しています。これを更新して、リクエストの全本文を構成し、それをMessengerプラットフォームに送信する必要があります。送信APIへのリクエストには、2つのプロパティがあります。

  • recipient: 意図されたメッセージ受信者を設定します。ここでは、PSIDにより受信者を識別します。
  • message: 送信するメッセージの詳細を設定します。ここではそれを、handleMessage()関数から渡したメッセージオブジェクトに設定します。

リクエスト本文を構成するため、callSendAPI()のスタブを次のように更新します。

function callSendAPI(sender_psid, response) {
  // Construct the message body
  let request_body = {
    "recipient": {
      "id": sender_psid
    },
    "message": response
  }
}

あとは、https://graph.facebook.com/v2.6/me/messagesPOSTリクエストを送信APIに対して送信すれば、メッセージが送られます。

URLクエリ文字列のaccess_tokenパラメーターにPAGE_ACCESS_TOKENを付加する必要があることに注意してください。

HTTPリクエストを実行する

このクイックスタートでは、HTTPリクエストをMessengerプラットフォームに返すため、Node.jsリクエストモジュールを使っています。しかし任意のHTTPクライアントを使うことができます。

リクエストモジュールをインストールするには、コマンドラインからnpm install request --saveを実行し、app.jsの先頭に以下を追加してインポートします。

const request = require('request');
function callSendAPI(sender_psid, response) {
  // Construct the message body
  let request_body = {
    "recipient": {
      "id": sender_psid
    },
    "message": response
  }

  // Send the HTTP request to the Messenger Platform
  request({
    "uri": "https://graph.facebook.com/v2.6/me/messages",
    "qs": { "access_token": process.env.PAGE_ACCESS_TOKEN },
    "method": "POST",
    "json": request_body
  }, (err, res, body) => {
    if (!err) {
      console.log('message sent!')
    } else {
      console.error("Unable to send message:" + err);
    }
  }); 
}

やってみましょう!

Messengerで、別のテキストメッセージをFacebookページに送信します。Messengerエクスペリエンスから自動返信が送られてくるはずです。それは、送信したメッセージのエコーバックであり、画像を送信するように促しています。
6
添付を処理する

返信プロンプトはメッセージ受信者に画像を送信するように促しているため、次のステップとして、添付を処理するようにコードを更新します。送信された添付ファイルはMessengerプラットフォームにより自動的に保存されて、配列attachmentsの各インデックスのpayload.urlプロパティにあるURLから入手できます。それで、イベントからそのURLも抽出します。

どんなタイプの添付がサポートされるか?


Messengerエクスペリエンスでは、ほとんどのアセットタイプの送受信が可能です。それには、画像、音声、動画、ファイルが含まれます。メディアはスレッドで表示され、再生も可能です。これにより、メディアを駆使したエクスペリエンスを作り出すことができます。

メッセージが添付かどうかを調べるには、handleMessage()関数の条件を更新して、received_messageattachmentsプロパティがあるかどうかをチェックし、そのURLを抽出します。現実世界のボットでは、その配列を反復処理することにより、複数の添付の存在をチェックすることになりますが、このクイックスタートでは最初の添付だけを取得することにします。

function handleMessage(sender_psid, received_message) {

  let response;

  // Checks if the message contains text
  if (received_message.text) {
    
    // Creates the payload for a basic text message, which
    // will be added to the body of our request to the Send API
    response = {
      "text": `You sent the message: "${received_message.text}". Now send me an attachment!`
    }

  } else if (received_message.attachments) {
  
    // Gets the URL of the message attachment
    let attachment_url = received_message.attachments[0].payload.url;
  
  } 
  
  // Sends the response message
  callSendAPI(sender_psid, response);    
}
7
フォーマット済みメッセージを送信する

次に、汎用テンプレートメッセージを使って画像に返信します。汎用テンプレートは、最も広く使われるフォーマット済みメッセージタイプであり、それにより画像、テキスト、ボタンを1つのメッセージで送信することができます。

利用可能なメッセージテンプレートは他にもありますか?


はい!Messengerプラットフォームには、一連の便利なメッセージテンプレートが用意されています。リスト、領収書、ボタンなど、よく使われる各種のメッセージフォーマットをサポートしています。詳しくは、テンプレートをご覧ください。

メッセージテンプレートは、メッセージのattachmentプロパティで定義されます。それには、typeプロパティとpayloadプロパティが含まれています。ここでは汎用テンプレートの詳細を、payloadの以下のプロパティで設定しました。

  • template_type: メッセージに使われているテンプレートのタイプを設定します。ここでは汎用テンプレートを使っているので、値は「generic」です。
  • elements: テンプレートのカスタムプロパティを設定します。この汎用テンプレートでは、タイトル、サブタイトル、画像、そして2つのポストバックボタンを指定します。

このフォーマット済みメッセージでは、送られてきたattachment_urlimage_urlとして使用し、テンプレートで表示します。さらに、メッセージ受信者が返信できるようにするため、2つのポストバックボタンを含めます。メッセージペイロードを構成し、汎用テンプレートを送信するため、handleMessage()を次のように更新します。

function handleMessage(sender_psid, received_message) {
  let response;
  
  // Checks if the message contains text
  if (received_message.text) {    
    // Create the payload for a basic text message, which
    // will be added to the body of our request to the Send API
    response = {
      "text": `You sent the message: "${received_message.text}". Now send me an attachment!`
    }
  } else if (received_message.attachments) {
    // Get the URL of the message attachment
    let attachment_url = received_message.attachments[0].payload.url;
    response = {
      "attachment": {
        "type": "template",
        "payload": {
          "template_type": "generic",
          "elements": [{
            "title": "Is this the right picture?",
            "subtitle": "Tap a button to answer.",
            "image_url": attachment_url,
            "buttons": [
              {
                "type": "postback",
                "title": "Yes!",
                "payload": "yes",
              },
              {
                "type": "postback",
                "title": "No!",
                "payload": "no",
              }
            ],
          }]
        }
      }
    }
  } 
  
  // Send the response message
  callSendAPI(sender_psid, response);    
}

やってみましょう!

Messengerで、画像をFacebookページに送信します。汎用テンプレートで返信が来るはずです。
8
ポストバックを処理する

最後のステップは、messaging_postbacks Webhookイベントを処理することです。このイベントは、メッセージ受信者が汎用テンプレートのいずれかのポストバックボタンをタップすると送信されます。

ポストバックで何ができるのか?


ポストバックボタンは、messaging_postbacks WebhookイベントをWebhookに送信します。そのpayloadプロパティには、1,000文字以下のカスタム文字列が含まれます。これにより、さまざまなポストバックペイロードを簡単に実装できます。それらを解析して特定の動作を行う返信ができます。

この汎用テンプレートでは、メッセージ受信者が2つのポストバックボタンのいずれかを選ぶことができるため、ポストバックイベントのpayloadプロパティの値に基づいて返信します。そのためには、handlePostback()スタブを次のように更新します。

function handlePostback(sender_psid, received_postback) {
  let response;
  
  // Get the payload for the postback
  let payload = received_postback.payload;

  // Set the response based on the postback payload
  if (payload === 'yes') {
    response = { "text": "Thanks!" }
  } else if (payload === 'no') {
    response = { "text": "Oops, try sending another image." }
  }
  // Send the message to acknowledge the postback
  callSendAPI(sender_psid, response);
}

やってみましょう!

Messengerで、汎用テンプレートのポストバックボタンのそれぞれをタップします。各ボタンで異なるテキストメッセージの返信を受け取ります。
9
すべてが問題なくうまくいったなら、初めてのMessengerエクスペリエンスの構築は完了です!

開発者サポート