記得當時歷經了 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'),


這個檔案除了載入套件和建立本機端伺服器之外,下面有兩個主要的程式,先簡單介紹一下:

  1. POST 用來接收和傳遞訊息
  2. 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」,設定好要對應的粉專~

存取權杖的 token 碼等下會使用,可以先複製好!


如果設定完成,在對應的「粉絲專頁」>「設定」>「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,點擊「驗證並儲存」之後,就可以在本機測試看看有沒有連成功喔!

小提醒,如果回頭要修改網址和權杖,就會跟第一次進來畫面不同,要記得點擊「Edit Subscription」就能再做修改!


STEP 7. 連上正式的 Webhook,用 Heroku 發佈到雲端

同上一篇的聊天機器人 try try 抗之 LineBot 特輯,這邊也是發佈到 Heroku!一樣修改好 package.json 和 app.js 裡 port 的設定並 git 上傳上去後,回到上一步的「應用程式」>「Webhook」>「Edit Subscription」裡修改「回呼網址」,這樣就完成了喔!


其他補充

在寫回應的部分,我剛好需要傳送一些圖片和語音,但我發現在 Facebook 裡傳遞這些非 Facebook 網址、跨網域的檔案需要先做設定,否則會有錯誤,在「粉絲專頁」>「設定」>「Messenger 開放平台」中找到「允許清單中的網域」,加入你存放檔案的網域就可以使用了!


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


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

一樣的垃圾話,只是貼圖變 emoji

輸入「Domo」一樣是找他媽😂
「DOMO」才是叫出主要功能
「呼叫神奇DOMO」!!!

回應「來啊!陪我玩!」就會跳出那一堆 APP,這也是依據官方文件提供的範本版型
「聽海笑的聲音」會隨機傳我準備的笑話😂,「看偶的美照~」會隨機傳照片給你
因為不能傳貼圖,所以我只好把貼圖拔下來假裝是貼圖,但實際上是傳一張圖片😂
如果你傳非文字訊息,一樣傳懶熊假貼圖給你😆

(以上均由手機 Messenger 截圖,跟 Line 一樣,桌機版跟手機版的畫面會稍有不太相同,也與版本差異有關。)

Chat-Domo 粉專傳送門在這邊:https://www.facebook.com/ChatDomo/
不過目前送審沒有過,一般民眾不能玩 Q_Q,下一頁再說明送審的狀況…


原本我以為到剛剛那邊就搞定了!以為只是像 Line 一樣會有對話量限制,結果要開放給別人玩才發現…該死的…還有審核這件事…orz

Facebook 送審是出了名的麻煩,之前就聽說過有人要送一到兩個月不等,但也看功能多複雜、要取得多少權限而定,我自己正式申請審核也才申請過一次,印象中滿快的,大概半天到一天就好了,我想那次沒要什麼權限才會這麼快吧!?不過沒想到這次送審,發生一些有趣的事情,我想貼出來給大家笑笑(我覺得這才是比海更好笑的事哈哈哈😂😂😂)

好!那我們就來審核抗抗唄!

首先我需要送出我要審核的部分,在「應用程式」>「Messenger」>「設定」中找到「Messenger 的應用程式審查」,然後在「pages_messaging」(我目前只需要這個功能)點擊「新增到提交內容」


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


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


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


我從後台看是長這樣的!


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


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


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

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

以上就是一場史上最荒謬的審核悲劇~