本文示範的方法是以Node.js的架構建置LINE BOT,執行環境必須要先有Node.js才能順利運行,若你不曾安裝過Node.js請先從連結下載並安裝。
你好,我是Andy,作為Pyradise的前端工程師,這篇文章將分享使用Node.js架設一個LINE Bot的作法,也整理出先前學習時碰過的各種坑,希望讓讀過這篇文章的你也不會讓我之前犯了這些錯誤而花費大量時間檢查,操作步驟共歸納以下四個主題進行解說:
註冊LINE Channel
撰寫LINE Bot Node.js程式
使用ngrok測試Bot
設定Webhook
Part 1:註冊LINE Channel
想要建置LINE Bot首先你必須要有一個LINE Channel作為使用者跟Bot對答的帳號,因此請移駕至LINE Developers官方網站並且登入LINE帳號。
進入LINE Developer後點選右上角的Log in 並以你的LINE帳號登入
登入後,選擇「Create New Provider」,Provider可想像成是一個公司或是團隊層級的帳號,LINE Bot會被綁在這組Provider帳號底下,若我們只是想嘗試建置Bot,可輸入任何一個尚未被使用過的名稱即可。
Provider名稱可為團隊或公司的名稱,當然這個名字也可由你自行決定。
當Provider建立好後,進入Provider的頁面內,點選在「Messaging API」底下的「Create Channel」。
右側點選剛才建立的Provider名稱,並選擇Messaging API底下的Create Channel
填入App名稱、敘述分類等等的資訊後,按下確認後即可建立一個LINE Channel帳號。
額外提醒:在App名稱的設定上不可設定包含LINE這個字眼的名稱,否則將無法順利註冊。
填入App名稱、敘述並且選擇類別。App名稱不可包含「LINE」這個字眼。
當Channel成功被建立後,點選Channel卡片進入「Channel Settings」,在這個頁面裡有很多的重要資訊是待會寫Code時要使用到的,請務必在完成前保持此頁面在瀏覽器開啟的狀態,以便及時的查找。
在Provider頁面裡,點選Channel進入Channel Settings頁面。
在Channel Settings畫面裡總共有三個重要的資料要找到:
Channel ID
Channel Secret
Channel Access Token
在Channel Settings頁面內可直接找到Channel ID與Channel secret。
前面兩項初次進入時即可直接看到,唯獨Channel Access Token需先點選右手邊的「Issue」按鈕設定Token過期時效(若怕太快過期可設定24小時)後,才可取得:
Channel access token需按下issue選擇token時效後即可產生,若擔心太快過期可設定為24小時。
「Channel Secret, Channel Access Token是讓Line官方能辨識Bot的重要資訊,需注意這些資訊請勿外流給其他人知道,否則他人將有機會偽造你的Bot回傳訊息給你的使用者。」
當然,本縮圖僅是用於此示範文章使用,在你看到這篇文章時此Token與Secret我也已經替換了。
準備就緒後,我們就可以打開編輯器開始寫Code囉!
Part 2:撰寫LINE Bot Node.js程式
使用Node.js建置LINE Bot非常容易上手,原因就在LINE本身已有提供各種語言的SDK,這裡我使用在npm上可直接安裝的linebot Node.js SDK為基礎來建置。
首先先建立一個空白的資料夾,並透過終端機在資料夾內輸入以下指令安裝linebot Package。
$ npm install linebot --save
建立一個名為app.js的新檔案並輸入以下的範例程式碼:
// 引用linebot SDK var linebot = require('linebot'); // 用於辨識Line Channel的資訊 var bot = linebot({ channelId: '替換成你的CHANNEL_ID', channelSecret: '替換成你的CHANNEL_SECRET', channelAccessToken: '替換成你的CHANNEL_ACCESS_TOKEN' }); // 當有人傳送訊息給Bot時 bot.on('message', function (event) { // event.message.text是使用者傳給bot的訊息 // 使用event.reply(要回傳的訊息)方法可將訊息回傳給使用者 event.reply(event.message.text).then(function (data) { // 當訊息成功回傳後的處理 }).catch(function (error) { // 當訊息回傳失敗後的處理 }); }); // Bot所監聽的webhook路徑與port bot.listen('/linewebhook', 3000, function () { console.log('[BOT已準備就緒]'); });
接著,將CHANNEL_ID, CHANNEL_SECRET, CHANNEL_ACCESS_TOKEN更新成Channel Settings頁面裡所顯示的資訊,型別皆為字串。
將app.js裡的Channel Id, Channel Secret, Channel Access Token資訊替換。
接著我們繼續看下去,以下這段程式是當使用者傳送訊息時會自動觸發的事件:
// 當有人傳送訊息給Bot時 bot.on('message', function (event) { // event.message.text是使用者傳給bot的訊息 // 使用event.reply(要回傳的訊息)方法可將訊息回傳給使用者 event.reply(event.message.text).then(function (data) { // 當訊息成功回傳後的處理 }).catch(function (error) { // 當訊息回傳失敗後的處理 }); });
這個事件處理器中,有兩個重要的資訊必須認識,第一個是使用者傳送進來的文字資訊,可以透過event.message.text取得;Bot要回覆的內容需要從event.reply()這個方法傳入。
event.message.text:使用者透過Line傳給Bot的文字訊息。
event.reply():這個方法能讓Bot回傳訊息給使用者。
所以按照上述官方範例的結果,這個bot會重複使用者所傳的訊息並回傳給使用者。
我們可以稍微改寫一下程式,讓Bot除了能回傳使用者剛才講的訊息外,也在回話的內容上額外加上一些文字,而在透過event.message.text到event.reply()而這中間的過程即是你可以發揮創意的地方,例如加個判斷式判斷使用者傳入的文字(event.message.text)設定不同的訊息回覆。
// 當有人傳送訊息給Bot時 bot.on('message', function (event) { // event.message.text是使用者傳給bot的訊息 // 準備要回傳的內容 var replyMsg = `Hello你剛才說的是:${event.message.text}`; // 透過event.reply(要回傳的訊息)方法將訊息回傳給使用者 event.reply(replyMsg).then(function (data) { // 當訊息成功回傳後的處理 }).catch(function (error) { // 當訊息回傳失敗後的處理 }); });
所以若待會運行順利的話,你將看到像是以下的對話:
使用者傳入的文字訊息可用event.message.text取得,在取得文字後即是你可以發揮創意的地方,可以依照使用者傳入的訊息不同做判斷並使用event.reply()回傳文字
現在程式碼已經完成,至於如何在LINE上直接做測試,這時候就得給大家介紹ngrok這個測試後端應用的神器!
Part 3:使用ngrok測試Bot
簡單來說,ngrok這個服務能夠讓你在本機端運行的應用程式通過一個公開的URL作為通道直接連結,且架設時支援https,https也是LINE官方對於使用Webhook連結Bot必要的條件之一,進入ngrok官方網站,點選「Get started for free」。
點選Download的連結下載ngrok
申請帳號後進入此頁面下載ngrok應用程式,待下載解壓縮完成後,於ngrok所在的資料夾內使用終端機輸入以下指令登入:
$ ./ngrok authtoken 你的NGROK_TOKEN
登入後,因在app.js內現在code內所監聽的port為3000,我們輸入以下指令開始運行ngrok,啟動後即可在終端機上看到可連結至本機 port 3000的公開URL。
需要注意每次開啟時的URL都是「隨機產生」,除非升級成付費版本才可以客製化subdomain名稱:
$ ./ngrok http 3000
輸入指令啟動ngrok後你將可於Forwarding後面看到一個可連結至本機 port 3000的公開URL
下一步,回到剛在app.js所在的資料夾將bot啟動:
$ node app.js
在app.js所在路徑輸入node app.js啟動bot
Part 4:設定Webhook
LINE Bot運行的機制,是當使用者傳送訊息給Channel時,透過Webhook轉傳訊息以及額外的資訊(額外資訊如使用者的名字、頭像等)到你指定的URL,而我們必須透過瀏覽器回到剛才的Channel Settings頁面裡設定。
4.1 開啟Webhooks
一定要記得開啟Use webhooks的選項!
將Channel Settings底下的Use webhooks選項設定為Enabled,這一個步驟相當重要,webhooks的功能若沒有開啟,Channel就不會轉發訊息到你的Bot,你的Bot也就不會收到任何訊息,也就不用說回傳訊息了,沒有打開Bot連訊息也收不到。
更重要的是「Use webhooks選項」預設是關閉的!所以請一定要記得初次設定要手動設定為Enabled。
4.2 設定Webhook
將Webhook連結的URL設定進去
下一步,設定Webhook連結的URL,當app.js與ngrok都啟動後,你可以將ngrok面板所顯示的Forwarding的公開URL填入Webhook URL的設定內,另外記得在URL後面加上app.js的bot監聽路徑的名稱。
比如我在ngrok上的公開URL為:
deecb94e.ngrok.io
app.js裡的bot所監聽的路徑是:
bot.listen('/linewebhook', 3000)
我所需要填入Webhook URL的值就應該是
deecb94e.ngrok.io/linewebhook
更新後,並點選verify按鈕,驗證是否成功。
若顯示「Success」即可滑動至畫面最下方加入自己剛才創建的LINE Channel看看是否有成功唷!
你可以再Channel Settings的最下方找到加入Channel為好友的QR Code測試
4.3 關閉Channel的罐頭訊息
你可能有注意到如同上述影片所呈現的結果,Channel回傳給你的訊息中包含了一些LINE所預設的罐頭訊息,因現在Channel已經會轉發使用者的訊息到你的bot內,負責回覆的邏輯將會由bot負責處理,所以若想要關閉罐頭訊息的話,可把以下選項設定為Disabled:
設定完畢後再試一次,罐頭訊息就不見囉!
完整的範例程式碼
// 引用linebot SDK var linebot = require('linebot'); // 填入辨識Line Channel的資訊 var bot = linebot({ channelId: '替換成你的CHANNEL_ID', channelSecret: '替換成你的CHANNEL_SECRET', channelAccessToken: '替換成你的CHANNEL_ACCESS_TOKEN' }); // 當有人傳送訊息給Bot時 bot.on('message', function (event) { // event.message.text是使用者傳給bot的訊息 // 準備要回傳的內容 var replyMsg = `Hello你剛才說的是:${event.message.text}`; // 透過event.reply(要回傳的訊息)方法將訊息回傳給使用者 event.reply(replyMsg).then(function (data) { // 當訊息成功回傳後的處理 }).catch(function (error) { // 當訊息回傳失敗後的處理 }); }); // Bot所監聽的webhook路徑與port bot.listen('/linewebhook', 3000, function () { console.log('[BOT已準備就緒]'); });
初次建置需要注意的坑
綜合以上步驟,以下這幾項是我自己初次嘗試時常常碰到的問題,如果你不想和我一樣重道覆轍,實作時可以作為檢核表逐步檢查:
是否有把Channel ID, Channel Secret, Channel Access Token正確地寫到程式內?
是否有在Channel Settings內將Use webhooks設定為「Enabled」?
是否有把Webhook URL寫對?
如果在ngrok上的public URL是「xxxxxxxx.ngrok.io」
如果在app.js bot監聽的路徑是 /linewebhook
Channel Settings裡的Webhook URL就應該設定為「xxxxxxxx.ngrok.io/linewebhook」免費版的ngrok若有重啟,所產生的public URL將會是一組新的subdomain,若要測試需確認是否有在Channel Settings更新Webhook URL?
延伸問答
Q:是否可改寫bot監聽的路徑?
A:可以,但是需要跟填寫在Channel Settings的Webhook URL對應的到。
Q:每次都要進到ngrok所在的資料夾下指令,有沒有辦法能夠將ngrok設定為可Global呼叫使用?
A:透過Finder前往 “/usr/local/bin”資料夾,將ngrok直接放入。之後你即可在任何路徑內輸入以下指令開啟ngrok:
$ ngrok http 3000
Q:ngrok每次重開後所產生的Public URL都是隨機的,有沒有辦法固定停一個Public URL?
A:使用付費版ngrok即可自訂subdomain,並且在開啟ngrok時下以下指令即可:
$ ngrok http -subdomain mycoolestsubdomain 3000
最後,我也很高興能跟大家分享我們Pyradise團隊,在去年 Line Hack 2018中進入了最後十強的決賽,我們也有幸與其中的高手們一起Hack,最後由強隊IQ智能戰隊奪冠,超級恭喜他們。這次我們學到了很多,也會繼續努力,若大家對Chatbot有興趣,也請繼續支持我們喔!
YOTTA 你最專業的學習夥伴,提供優質內容與有趣觀點,擴大豐富你的視野。
- 訂閱Pyradise的專欄,定期收到新文章通知。
- 延伸學習:Python與前端技術綜合技能養成|20小時從零建構即時資訊儀表板
所有圖片來源:Pyradise