記得當時歷經了 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 在本地端測試
同上一篇的聊天機器人 try try 抗之 LineBot 特輯,這邊也是用 ngrok 做本地測試!
ngrok 設定完成後,就可以回到 Facebook 應用程式裡,點擊左方我們申請的產品「Webhook」,勾選所需的功能,這些功能就是送審的主要 API,我這邊只勾了「pages_messaging」,官方說法是「讓你的應用程式可以使用 Facebook 粉絲專頁發送和接收訊息」的功能。
然後在「回呼網址」貼上 ngrok 產生的 https 網址;「驗證權杖」貼上 token,點擊「驗證並儲存」之後,就可以在本機測試看看有沒有連成功喔!

STEP 7. 連上正式的 Webhook,用 Heroku 發佈到雲端
同上一篇的聊天機器人 try try 抗之 LineBot 特輯,這邊也是發佈到 Heroku!一樣修改好 package.json 和 app.js 裡 port 的設定並 git 上傳上去後,回到上一步的「應用程式」>「Webhook」>「Edit Subscription」裡修改「回呼網址」,這樣就完成了喔!
其他補充
在寫回應的部分,我剛好需要傳送一些圖片和語音,但我發現在 Facebook 裡傳遞這些非 Facebook 網址、跨網域的檔案需要先做設定,否則會有錯誤,在「粉絲專頁」>「設定」>「Messenger 開放平台」中找到「允許清單中的網域」,加入你存放檔案的網域就可以使用了!

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

我在 Messenger 的腳本基本上跟 Line 相同,因為我只是想測試這兩個平台的差異,所以也故意用同一個腳本測看看!(我不會告訴你我其實只是懶得寫新的 😂)但就因為腳本相同,才發現有些問題產生,而且我暫時也沒找到怎麼連續傳送訊息,所以就改了一些小東西,另外是粉專機器人似乎無法加入群組(畢竟人家是粉專嘛!)所以也不能玩多人瘋狂模式啦!以下就來欣賞 FB 版本的 DOMO 桑吧!


「DOMO」才是叫出主要功能





(以上均由手機 Messenger 截圖,跟 Line 一樣,桌機版跟手機版的畫面會稍有不太相同,也與版本差異有關。)
Chat-Domo 粉專傳送門在這邊:https://www.facebook.com/ChatDomo/
不過目前送審沒有過,一般民眾不能玩 Q_Q,下一頁再說明送審的狀況…
原本我以為到剛剛那邊就搞定了!以為只是像 Line 一樣會有對話量限制,結果要開放給別人玩才發現…該死的…還有審核這件事…orz
Facebook 送審是出了名的麻煩,之前就聽說過有人要送一到兩個月不等,但也看功能多複雜、要取得多少權限而定,我自己正式申請審核也才申請過一次,印象中滿快的,大概半天到一天就好了,我想那次沒要什麼權限才會這麼快吧!?不過沒想到這次送審,發生一些有趣的事情,我想貼出來給大家笑笑(我覺得這才是比海更好笑的事哈哈哈😂😂😂)
好!那我們就來審核抗抗唄!
首先我需要送出我要審核的部分,在「應用程式」>「Messenger」>「設定」中找到「Messenger 的應用程式審查」,然後在「pages_messaging」(我目前只需要這個功能)點擊「新增到提交內容」

然後會請你填寫這種東西….我覺得很恥…😂😂😂怕審核沒過還不敢打 emoji 💩💩💩
當時還在給審查人員的備註欄上面打了「thanks!」(是不是非常有禮貌 😌

我那天大概中午送出,結果一兩個小時後就收到回覆!
噢喔!有錯嘍?!

然後我不疑有他地打開他們提供的螢幕截圖,看到這邊…WTF…
竟然全部自動英文化!!說我小孩是廢物!打錯指令還怪我!怎麼比我還幽默😂😂😂

我從後台看是長這樣的!

太幽默了!可能他們很少遇到瘋子開發者和瘋子機器人😜
因為之前聽同事說打中文會有審核翻譯的問題和工時,所以我決定在備註欄速速地回一則英文說明給他們!雖然我是很認真地想要解釋這個鬼東西(?!),但總感覺略帶挑釁😂😂😂
是說當媽之後,英文就突飛猛進(什麼補教業廣告 😆),可能文法都是錯的啦哈哈哈!

後來到了晚上 7 點左右我發現不斷有人來訪,看起來多了三個帳號測試,看來這些測試人員是有看懂我的鬼英文啊!!!深感欣慰!😌




可是他們後來卻需要我提供這些東西…我整個覺得超怪der,所以我就不客氣地回了這句…

我問過同事們,他們沒有遇到這種情況…
有可能我申請的是個人帳號,但我還是覺得很不妥…
更何況他們之前的一些詭異設定和亂刪文事件就有點激怒我了(好容易生氣喔這個人😂
所以呢,這個專案就這樣吧!這個審核就一直放著,採取一種消極做法,反正我也玩夠惹~~
雖然他們仍然會發信和發通知請我看 Facebook 的隱私權聲明,跟我說這一切都走合法途徑…
但來不及了~克柏!我們回不去了~😢
以上就是一場史上最荒謬的審核悲劇~