快速入門教學導覽

本教學導覽會介紹有關建立首個 Messenger 體驗的所有須知事項。在開始之前,請選擇新手專案下方的其中一個選項以取得入門所需的程式碼,然後按照新手指南下方的步驟完成設定。

只想查看已完成的程式碼?沒問題!您可以在 GitHub 上 Fork 這些程式碼

內容

新手專案

在開始按照本快速入門教學導覽操作之前,請確認您已完成下列其中一項操作,以確保您已取得必要的新手程式碼。新手程式碼提供了我們將用作 Messenger 體驗基礎的基本 Webhook。

選項 1:自行建立

我們的 Webhook 設定指南會逐步引導您如何建立首個 Webhook,以供您在按照本快速入門教學導覽操作的整個過程中使用。

建立 Webhook

選項 2:從 GitHub 下載

從 GitHub 下載我們的 Webhook 新手程式碼,並將其部署至您所選的伺服器。

下載程式碼

選項 3:在 Glitch 上整合運用

如果您沒有伺服器可部署為 Webhook 的目的地,則可以在 Glitch 上整合運用我們的新手 Webhook 專案,為 Webhook 提供透過 HTTPS 供應的公開網址。

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

  1. 在 Glitch 上開啟我們的新手 Webhook 專案: 在 Glitch 上混合配搭
  2. 點擊「Remix Your Own」按鈕。系統會為您建立專案副本。
  3. 點擊左上角的下拉式選單,然後複製專案描述下方的公開網址。此網址將是您 Webhook 的基底網址。
  4. 按照我們的應用程式設定指南,為您的 Webhook 訂閱 Facebook 應用程式。您的 Webhook 網址將是附有 /webhook 的 Glitch 網址:
    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 專頁展開對話時,系統都會為用戶分配一個不重複的專頁範圍編號(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
  }
}

現在,我們只需要在 https://graph.facebook.com/v2.6/me/messages 向傳送 API 提出 POST 要求,即可傳送訊息。

請注意,您必須在網址查詢字串的 access_token 參數中附加 PAGE_ACCESS_TOKEN

執行 HTTP 要求

在本快速入門指南中,我們使用 Node.js 要求模組來向 Messenger 平台傳回 HTTP 要求,但您可以隨意使用其他 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:設定範本的自訂屬性。對於通用範本,我們會指定標題、副標題、圖片,以及兩個回傳按鈕。

對於結構化訊息,我們會使用傳送給我們作為 image_urlattachment_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 體驗!

開發人員支援