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

このチュートリアルでは、初めてMessengerボットを作成するために必要な情報を紹介します。開始する前に、スタータープロジェクトの下のいずれかのオプションを選択して開始するコードを取得し、スタートガイドの手順に従って設定してください。

完成したコードを確認したいですか?問題ありません。Githubで入手できます。

内容

スタートプロジェクト

このクイックスタートを開始する前に、以下のいずれかを完了し、必要なスターターコードをご用意ください。スターターコードは、Messengerボットの土台として使用される基本的なwebhookを提供します。

オプション1: 自分で作成する

webhook setup guide (Webhookセットアップガイド)」は、初めてwebhookを作成する手順を一から順に説明しており、このクイックスタートと併せて使用できます。

Webhookを作成

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

webhookスターターコードをGitHubからダウンロードして、任意のサーバーに配置します。

コードをダウンロード

オプション3: Glitchで編集する

webhookを配置するサーバーがない場合は、FacebookのスターターwebhookプロジェクトをGlitchで編集することができます。これにより、webhookのHTTPS経由の公開URLが作成されます。

独自のwebhookをGlitchで作成するには、次の手順に従います。

  1. FacebookのスターターwebhookプロジェクトをGlitchで開きます。Glitchで編集
  2. [Remix Your Own]ボタンをクリックします。プロジェクトのコピーが作成されます。
  3. 左上隅でドロップダウンメニューをクリックし、プロジェクトの説明の下にある公開URLをコピーします。これは、webhookの基本URLになります。
  4. app setup guide (アプリのセットアップガイド)」に従って、webhookをFacebookアプリでフォローします。webhook URLは次のように/webhookが付いたGlitch URLになります。
    https://<GLITCH_URL>/webhook

スタートガイド

初めてのMessengerボットを作成する前に、まずアプリの認証情報を設定します。

1
Facebookアプリを設定する

まだ設定していない場合は、「app setup guide (アプリのセットアップガイド)」に従い、Messengerプラットフォームで使用するFacebookアプリをセットアップします。

アプリが開発モードになっていること

アプリが申請され、Messengerでの公開使用が承認されるまで、ページトークンでは、アプリの管理者、開発者、テスターの役割が付与されたFacebookアカウントとのやり取りのみがボットで許可されます。

これらの役割をその他のFacebookアカウントに付与するには、アプリ設定の[役割]タブに移動します。

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

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

Facebookアプリを設定するときにまだ行っていない場合は、次のようにしてページアクセストークンを生成します。

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

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

ページアクセストークンなどの個人情報は、webhookにハードコーディングしないことをおすすめします。これは、次を環境変数に追加することで行います。ここで、<PAGE_ACCESS_TOKEN>は生成したアクセストークンを示します。

PAGE_ACCESS_TOKEN="<PAGE_ACCESS_TOKEN>"

Glitchの環境変数

Glitchを使用する場合は、提供された.envファイルの環境変数を設定して、その他のGlitchユーザーに表示されないようにしてください。

4
ページを追加し、webhookに対してトークンを認証する

最後に、ページアクセストークンを追加し、webhookコードに対してトークンを認証します。

1. ページアクセストークンをapp.jsファイルの先頭に追加します。

const PAGE_ACCESS_TOKEN = process.env.PAGE_ACCESS_TOKEN;

2. webhook認証コードに認証トークンを設定します。

app.get('/webhook', (req, res) => {
  
  const VERIFY_TOKEN = "<YOUR_VERIFY_TOKEN>";
  
  ...
  
})

セットアップが完了しました

初めてのMessengerボットを作成しましょう

ボットの作成

このチュートリアルでは、次のことを行う簡単なMessengerボットを作成します。

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

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

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

テキストメッセージでテキストメッセージに応答します。

受信した画像を使用する一般テンプレートを使用して画像添付ファイルに応答します。

条件付きでポストバックペイロードに応答します。


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

まず、サポートしたい受信webhookイベントタイプを処理する3つの関数をスタブアウトし、送信API経由で応答します。これを行うには、次の行を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ボットでは、メッセージ送信者のpage-scoped ID (PSID)を受信したwebhookイベントから取得することでこれを実現します。

PSIDとは何ですか?


利用者には、スレッドを開始するFacebookページごとに固有のpage-scoped ID (PSID)が割り当てられます。PSIDは、Messengerボットがメッセージを送信するときに利用者を特定するために使用されます。

上記の要件セクションのいずれかのオプションを完了した場合は、基本の/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を開き、ボットに関連付けられたFacebookページにメッセージを送信します。Messengerで応答を受け取ることはできませんが、webhookが実行されているコンソールにPSIDが記録されたメッセージが表示されます。
Sender PSID: 1254938275682919
3
webhookイベントタイプを解析する

ボットで2つのタイプのwebhookイベント(messagesmessaging_postback)を処理できるようにします。このイベントタイプの名前はイベント本文には含まれていませんが、特定のオブジェクトのプロパティを調べることで確認できます。

webhookイベントとは何ですか?


Messengerプラットフォームは、Messengerで発生したアクションをMessengerボットに通知するためにwebhookイベントを送信します。イベントはPOSTリクエストとしてJSON形式でwebhookに送信されます。詳しくは、「Webhookイベント」をご覧ください。

これを行うには、受信したイベントにbody.entry.forEachまたはmessageプロパティが含まれているかどうかを確認するという条件付きで、webhookの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
送信Send 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
  }
}

次に、POSTリクエストを送信API (https://graph.facebook.com/v2.6/me/messages)に送信すると、Facebookからメッセージが送信されます。

URLクエリ文字列のaccess_tokenパラメーターに、PAGE_ACCESS_TOKENを追加する必要があります。

HTTPリクエストの作成

このクイックスタートでは、Node.jsリクエストモジュールを使用してHTTPリクエストをMessengerプラットフォームに返していますが、任意の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": 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から利用できるため、これはイベントからも抽出されます。

サポートされる添付ファイルを教えてください。


Messengerボットは、画像、音声、動画、ファイルなど、ほとんどのアセットタイプを送受信できます。メディアが表示され、スレッド内でも再生可能なので、さまざまなメディアに対応する機能を作成できます。

メッセージが添付ファイルであるかどうかを判断するには、attachmentsプロパティにreceived_messageがあるかどうかを確認するようにhandleMessage()関数の条件を更新します。実世界のボットでは、複数の添付ファイルを確認するために配列を繰り返しますが、このクイックスタートでは、最初の添付ファイルのみを取得します。

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として使用してテンプレートに表示し、メッセージ受信者が応答できるいくつかのポストバックボタンを追加します。メッセージペイロードを作成して一般テンプレートを送信するには、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ページに送信します。Messengerボットは一般テンプレートで応答する必要があります。
8
ポストバックを処理する

最後のステップでは、メッセージ受信者が一般テンプレートのポストバックボタンをタップすると送信されるmessaging_postbacks webhookイベントを処理します。

ポストバックを使って何ができますか?


ポストバックボタンは、payloadプロパティに最大1,000文字のカスタム文字列を含むmessaging_postbacks webhookイベントをwebhookに送信します。これにより、特定の行動を解析して応答できるさまざまなポストバックペイロードを簡単に実装できます。

一般テンプレートでは、メッセージ受信者が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ボットが完成します。