快速入門教學導覽

本教學導覽指引您學習建構第一個 Messenger 體驗的所有須知。開始之前,請在入門專案之下選擇其中一個選項,取得入門所需的程式碼,接著按照立即開始所列的步驟進行設定。

只想查看完成的程式碼?沒問題!請上 GitHub 取得程式碼

內容

入門專案

開始進入快速入門教學導覽之前,請務必完成下列其中一項,備妥您需要的入門程式碼。入門程式碼提供基本 Webhook,這是 Messenger 體驗的基礎。

選項 1:自行建構

我們的 Webhook 設定指南會引導您建構在本快速入門中全程可以使用的第一個 Webhook。

建構 Webhook

選項 2:自 GitHub 下載

自 GitHub 下載我們的 Webhook 入門程式碼,再將程式碼部署於您所選的伺服器。

下載程式碼

選項 3:在 Glitch 上混搭程式碼

如果您沒有可部署 Webhook 的伺服器,可以在 Glitch 上混搭我們的入門 Webhook 專案,如此可為您的 Webhook 提供透過 HTTPS 所傳送的公開網址。

若要在 Glitch 上建立自己的 Webhook,請執行以下操作:

  1. 在 Glitch 上開啟我們的入門 Webhook 專案: Remix on Glitch
  2. 點擊「Remix Your Own」按鈕。系統將為您建立專案複本。
  3. 點擊左上角的下拉式功能表,接著複製專案說明下方的公開網址。此網址將是您 Webhook 的基底網址。
  4. 按照我們的應用程式設定指南,讓 Facebook 應用程式接受您的 Webhook。您的 Webhook 網址會是 Glitch 網址後面附加 /webhook
    https://

立即開始

開始建構第一個 Messenger 體驗之前,請先設定應用程式的憑證。

1
設定 Facebook 應用程式

如果您尚未準備好,請按照應用程式設定指南設定 Facebook 應用程式,以利在 Messenger 開放平台使用。

您的應用程式處於開發模式

在您提交應用程式且獲准能在開放 Messenger 公開使用之前,粉絲專頁權杖只開放您的粉絲專頁與申請獲准的應用程式管理員、開發人員或測試人員的 Facebook 帳號互動。

若要將這些角色授予其他 Facebook 帳號,請前往應用程式設定的「角色」頁籤。

2
產生粉絲專頁存取權杖

要驗證對 Messenger 開放平台 API 提出的要求,一律要在查詢字串的 access_token 參數中加入一個粉絲專頁層級的存取權杖。

若您在設定 Facebook 應用程式時未產生粉絲專頁存取權杖,請先完成下列步驟:

  1. 在應用程式 Messenger 的設定中進入「產生權杖」部分,在「粉絲專頁」下拉式功能表中找到您想用於產生權杖的 Facebook 粉絲專頁。「粉絲專頁存取權杖」欄位中隨即會出現存取權杖。
  2. 點擊「粉絲專頁存取權杖」欄位,將權杖複製到剪貼簿中。

這個用戶介面並不會儲存所產生的權杖。每次您在下拉式功能表中選擇一個粉絲專頁時,均會產生一個新的權杖。產生新的權杖後,之前建立的權杖仍會繼續發揮作用。
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 事件的訊息和傳送者的粉絲專頁範圍編號。

處理 messagesmessaging_postbacks Webhook 事件。

透過傳送 API 傳送訊息。

以文字訊息回覆文字訊息。

以通用範本回覆影像附件,這個範本會使用所收到的影像。

有條件回覆回傳承載。


1
完成處理函式的虛設常式

首先我們要完成三個函式的虛設常式,這三個函式將處理我們想要支援的傳入 Webhook 事件類型,以及透過傳送 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
取得傳送者的粉絲專頁範圍編號

要在 Messenger 回覆用戶,首先需要知道對方的身分。在 Messenger 中,要知道對方的身分就要從傳入的 Webhook 事件取得訊息傳送者的粉絲專頁範圍編號 (PSID)。

什麼是 PSID?


當用戶開始與 Facebook 粉絲專頁展開對話時,會為每個 Facebook 粉絲專頁分配一個不重複的粉絲專頁範圍編號 (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 事件類型

我們希望這個體驗能夠處理兩種類型的 Webhook 事件:messagesmessaging_postback。事件主體不會包含事件類型的名稱,但我們可以查看特定物件屬性,以判斷名稱。

什麼是 Webhook 事件?


Messenger 開放平台會傳送 Webhook 事件,讓您知道在 Messenger 中發生的操作。事件傳送格式以 JSON 為準,並且會以 POST 要求的方式傳送至 Webhook。如需詳細資訊,請參閱 Webhook 事件

若要這麼做,請更新 Webhook 的 body.entry.forEach 區塊,加註會檢查收到的事件是否包含 messagepostback 屬性的條件。我們也會新增呼叫稍早完成虛設常式的 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 的要求有兩個屬性:

  • recipient:設定預定的訊息收件者。這個時候會依 PSID 分辨收件者的身分。
  • message:設定待傳送訊息的詳細資料。這裡我們會將它設定為自 handleMessage() 函式傳入的訊息物件。

要建構要求內文,請更新 callSendAPI() 的虛設常式:

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

現在我們只要提交一則 POST 要求至 https://graph.facebook.com/v2.6/me/messages 的傳送 API 並傳送訊息即可。

請注意,您必須將 PAGE_ACCESS_TOKEN 附加在網址查詢字串的 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": 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 屬性公開,所以我們也會從事件擷取這一項。

支援哪些附件類型?


您的 Messenger 體驗可以傳送及接收大多數的素材類型,包括影像、音訊、影片和檔案。影音素材會顯示在對話中,甚至可以播放,支援您建構多媒體體驗。

要判斷訊息是否為附件,請更新 handleMessage() 函式中的條件,用於檢查 attachments 屬性的 received_message,接著擷取其所需網址。在實際的 Bot(機器人程式)中,我們會反覆測試陣列並檢查多個附件,但在本快速入門中,我們只會取得第一個附件。

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
傳送結構化訊息

接下來我們要以通用範本訊息回覆影像。通用範本是最常用且結構化訊息類型,支援您在同一則訊息中傳送影像、文字和按鈕。

有其他範本可以使用嗎?


有!Messenger 開放平台提供一組實用的訊息範本,每一個範本的設計分別支援不同的常用訊息結構,包括清單、收據、按鈕等等。如需完整詳細資料,請參閱範本

訊息範本需在訊息的 attachment 屬性中定義,其中包含 typepayload 屬性。我們要在 payload 中的下列屬性設定通用範本的詳細資料:

  • template_type:設定訊息所用範本的類型。我們要使用通用範本,所以這個值是「generic」。
  • elements:設定範本的自訂屬性。我們會為通用範本指定一個標題、副標題、影像,以及兩個回傳按鈕。

結構化訊息要使用 attachment_url,這是我們所收到的 image_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 事件。

回傳的功能是什麼?


回傳按鈕會傳送一個 messaging_postbacks Webhook 事件到 Webhook,其中包含一個自訂字串,其 payload 屬性包含的字元不超出 1,000 個。這項功能支援您輕鬆實作不同的回傳承載,以利剖析及回覆特定行為。

由於我們的通用範本提供兩個回傳按鈕供訊息收件者選擇,因此我們會根據回傳事件的 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 體驗就大功告成了!

開發人員支援