記得當時歷經了 Line 機器人沒多久,隔一天手癢想試試看 Facebook 的 Messenger 機器人,搞了一天總算看懂這是怎麼玩的!(奇怪!😂我怎麼不記得以前 FB 文件有寫得這麼清楚……)
本篇文章共有三頁,分為:1. 步驟紀錄 2. 成果紀錄 3. 送審後續
在開始做 Facebook Messenger Bot 之前,要先搞定兩個東西:粉絲專頁、應用程式
因為 Facebook 只提供粉絲專頁開發機器人功能,跟 Line 只提供官方帳號是一樣的意思,所以一定要先建立一個粉專!另一個是需要使用 Webhook 串接 API,也要建立一個應用程式,並且這整件事情如果要開放給大眾玩還需要送審!
簡單來說整個流程就是:建立粉絲專頁 → 建立應用程式 → 撰寫程式並架在雲端上 → 送審
以下步驟主要是參考 Facebook 官網的文件:Messenger 平台快速入門教學課程
而我還是用 nodeJS 來開發,基本上照著它的步驟寫就可以用設定好機器人了!而且他還有翻成繁中!麻瓜的我都看得懂!你也一定看得懂!😂
因為涉及粉專和應用程式的設定,我還是有參考網路上大大的筆記,補充官方文件說明上的不足,先貼一下以表尊敬:
步驟跟 LineBot 很類似,所以相同的地方我會省略說明~
詳細解說可以參考上篇文章的紀錄:聊天機器人 try try 抗之 LineBot 特輯
接下來開始進入步驟說明嘍!
STEP 1. 先把環境和該裝的東西先裝好
依據官方文件上提供能快速建置的 github 連結,可以直接把整個檔案拉下來,放到自己的專案裡!
打開 app.js 會看到需要的外掛,請自行 npm install 下面這些檔案:
const request = require('request'), express = require('express'), body_parser = require('body-parser'),
這個檔案除了載入套件和建立本機端伺服器之外,下面有兩個主要的程式,先簡單介紹一下:
- POST 用來接收和傳遞訊息
- GET 用來驗證網頁憑證
// Accepts POST requests at /webhook endpoint app.post('/webhook', (req, res) => { let body = req.body; if (body.object === 'page') { body.entry.forEach(function(entry) { let webhook_event = entry.messaging[0]; console.log(webhook_event); }); res.status(200).send('EVENT_RECEIVED'); } else { res.sendStatus(404); } }); // Accepts GET requests at the /webhook endpoint app.get('/webhook', (req, res) => { const VERIFY_TOKEN = "<YOUR_VERIFY_TOKEN>"; let mode = req.query['hub.mode']; let token = req.query['hub.verify_token']; let challenge = req.query['hub.challenge']; if (mode && token) { if (mode === 'subscribe' && token === VERIFY_TOKEN) { console.log('WEBHOOK_VERIFIED'); res.status(200).send(challenge); } else { res.sendStatus(403); } } });
STEP 2. 申請粉絲專頁
Facebook 首頁左下角找到「粉絲專頁」> 「建立粉專」或直接點進此連結建立

STEP 3. 申請應用程式,設定和連接粉專
Facebook 首頁左下角「管理應用程式」>「建立應用程式」或直接點進此連結建立

建立好了,請自行到「設定」>「基本資料」填寫資料,例如網域、隱私權網址、應用程式圖示等等,主要我們要到「產品」那邊新增兩個權限功能,分別是 Messenger 和 Webhook,如下圖

好了之後要來設定連結對應的粉專,請在「Messenger」>「設定」中找到「存取權杖」和「Webhooks」,設定好要對應的粉專~

如果設定完成,在對應的「粉絲專頁」>「設定」>「Messenger 開放平台」中找到「連結的應用程式」,就會看到兩者有串起來嘍!(好煩喔!一直在 Facebook 大海裡跑來跑去😆)

STEP 4. 取得權杖
接下來先把應用程式中「存取權杖」取得的權杖憑證(就是傳說中的 token,以下都簡稱 token)貼到 app.js 程式中,為了方便後面程式碼使用,可以宣告一個常數:
const PAGE_ACCESS_TOKEN = "<YOUR_VERIFY_TOKEN>";
這樣就可以把原本 GET 那段改成這樣:
app.get('/webhook', (req, res) => { const VERIFY_TOKEN = PAGE_ACCESS_TOKEN; // 以下省略... });
這樣就表示設定好 Webhook 的憑證了!
STEP 5. 接受和回應資料
設定好 GET 憑證,現在來說明 POST 那一坨(?!)東西吧!
主要需要用到的地方就是 body.entry.forEach 裡面的 function:
app.post('/webhook', (req, res) => { let body = req.body; if (body.object === 'page') { body.entry.forEach(function(entry) { // 取得 Webhook 的事件 let webhook_event = entry.messaging[0]; // 取得發送者的 PSID let sender_psid = webhook_event.sender.id; // 判斷訊息是屬於 message 還是 postback if (webhook_event.message) { handleMessage(sender_psid, webhook_event.message); } else if (webhook_event.postback) { handlePostback(sender_psid, webhook_event.postback); } }); res.status(200).send('EVENT_RECEIVED'); } else { res.sendStatus(404); } });
上方程式碼中,「PSID」就是機器人需要回應的「對象」,也就是我們 FB 的辨識 ID,而另一個「判斷訊息是屬於 message 還是 postback」意思是發送者是否是透過機器人提供的選擇做回覆,如果「是」就是 postback;「不是」就屬於 message,官方教學分別用下面這兩個函數包起來:
// 處理發送者直接傳送的訊息 function handleMessage(sender_psid, received_message) { // ... } // 處理發送者回覆機器人的訊息 function handlePostback(sender_psid, received_postback) { // ... }
然後兩種訊息的處理一樣需要讓機器人做出回應,所以官方教學是用 callSendAPI 函數包起來重複使用:
// 發送機器人的回應 function callSendAPI(sender_psid, response) { let request_body = { "recipient": { "id": sender_psid }, "message": response } 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); } }); }
處理訊息的部分就需要透過開發者編寫!
首先,handleMessage 是處理發送者直接傳送的訊息,官方提供如下:
function handleMessage(sender_psid, received_message) { let response; // 判斷訊息是否包含文字 if (received_message.text) { // 回傳的文字訊息 response = { "text": `You sent the message: "${received_message.text}". Now send me an image!` } } // 機器人發送回應 callSendAPI(sender_psid, response); }
handlePostback 是處理發送者回覆機器人的訊息,官方提供如下:
function handlePostback(sender_psid, received_postback) { let response; // 取得發送者回覆內容 let payload = received_postback.payload; // 判斷回覆的內容,對應機器人回應的訊息 if (payload === 'yes') { response = { "text": "Thanks!" } } else if (payload === 'no') { response = { "text": "Oops, try sending another image." } } // 機器人發送回應 callSendAPI(sender_psid, response); }
因此要做很多機器人的腳本回應,都可以在 handleMessage 和 handlePostback 裡面加以撰寫!
若要判斷發送者的訊息是什麼類型可以在Sending Messages找到對應的名稱。
當然,跟 Line 機器人一樣,Facebook 也有提供很多訊息範本和回傳訊息的格式可以使用,都可以自行到官網查詢。
好可惜竟然不能傳貼圖!!!!! 😭😭😭
只好寫信請 Facebook 改進惹(喂
STEP 6. 連上 Webhook,用 ngrok 在本地端測試
同上一篇的聊天機器人
然後在「回呼網址」貼上 ngrok 產生的 https 網址;「驗證權杖」貼上 token,點擊「驗證並儲存」之後,就可以在本機測試看看有沒有連成功喔!

STEP 7. 連上正式的 Webhook,用 Heroku 發佈到雲端
同上一篇的聊天機器人
其他補充
在寫回應的部分,我剛好需要傳送一些圖片和語音,但我發現在 Facebook 裡傳遞這些非 Facebook 網址、跨網域的檔案需要先做設定,否則會有錯誤,在「粉絲專頁」>「設定」>「Messenger 開放平台」中找到「允許清單中的網域」,加入你存放檔案的網域就可以使用了!

最後,就會看到它真的會亂傳垃圾話給我呢~~😂
