串接一個 LINE Bot 來做小應用!
LINE Bot
今天要分享關於串接 LINE Bot 的過程中遇到的一些小坑和經驗~ 使用 LINE Bot 可以把一些簡單的小應用以 LINE 聊天機器人的形式發布出去,對於一些功能不複雜的應用來說是蠻方便的一個部署管道。
這次要串接的服務是一個簡易的短網址服務,它的功能就只有一個:把長網址縮短!會以這個服務為核心主要的目的是在閱讀到系統設計相關書籍裡和短網址服務相關的一些系統層面的細節,因此想要實際的來動手玩玩看!
後續的內容主要會從 LINE Developers 相關的設定開始,一直到串接後端的部分,實際的後端功能實現在這邊就不會特別花篇幅來敘述,有機會的話會留到其它篇文章來好好的介紹~ 而這次的後端服務使用的是 NestJS,如果是使用 Node.js、Express 的話應該也能夠參考當中的一些內容。
開發者頁面
首先要到 LINE Developers 登入開發者的 Console 頁面,如果之前沒有申請過開發者帳號的話也可以用一般的帳號去註冊成為開發者帳號。進入到 Console 後可以看到左邊有一個 Provider 的選項,我們需要在這裡建立一個新的 Provider (有點類似建一個新專案)。

點選進入剛剛創建好的 Provider 裡面,會包含 Channels、Roles、Settings 幾個分頁,Roles 可以邀請其他開發者一起參與,也可以在裡面設定每個參與者的權限管理,而 Channels 就是接下來會利用到的部分。
新增一個 Channel
切換到 Channels 之後,可以從這邊建立一個新的 Channel,類別的話則是要選到 Messaging API,不過目前進去之後會出現一段說明,大意是說現在已經將新增的功能轉移到另一個官方帳號管理的頁面來處理,可以透過裡面提供的連結來跳轉到一個創建官方帳號的地方,就可以根據指示把帳號先建立起來。

建立完成之後可以在官方帳號管理的頁面把官方帳號的一些基本資訊給設定好,像是頭像、歡迎訊息、基本介紹等等。
取得認證資訊
接下來就可以回到 LINE Developers 的頁面,此時 Provider 裡面應該會多出一個剛剛建立的官方帳號 Channel,點進去之後我們會需要取得兩個關鍵的認證資訊,分別是 Channel Secret 和 Channel Access Token,可以分別在 Basic settings 和 Messaging API 的分頁中找到,儲存下來之後也可以直接把這兩個 key 先保存到自己專案的環境設定檔裡 (如 .env),後面會利用到它們來進行 LINE 的認證。
串接到後端
以下會使用 NestJS 來將後端串接到 LINE 的服務上,順帶一提 LINE 官方也有關於 Messaging API 的文件可以參閱~
首先會需要安裝 line sdk 的套件:
$ npm install @line/bot-sdk
在 Module 中把剛剛取得的兩個認證資訊以 Config 的方式載入進來,這邊是利用另一篇文章有提到的自定義命名空間的方式將設定檔帶入。比較重要的是下面我們會需要自行定義 Module 來執行 LINE 的認證。透過重寫 Module 的方式在裡面以 configure 方法將 middleware 載入進來,此處的 lineMiddleware 是從 @line/bot-sdk 套件中所引用的 middleware,並將其套用到一個自定義的 POST 路由上。
@Module({ imports: [ ConfigModule.forRoot({ load: [LineBotConfigFactory], }), ], controllers: [LineBotController], providers: [LineBotService], }) export class LineBotModule implements NestModule { constructor(private readonly configService: ConfigService) {} configure(consumer: MiddlewareConsumer) { const lineConfig = { channelSecret: this.configService.get<string>( 'line-bot.channelSecret', ) as string, channelAccessToken: this.configService.get<string>( 'line-bot.channelAccessToken', ) as string, }; consumer.apply(lineMiddleware(lineConfig)).forRoutes({ path: 'line-bot/callback', method: RequestMethod.POST, }); } }
另外一點需要注意的是這個 middleware 會需要讀取原始的 raw body,但在 NestJS 預設裡會自動將讀取進來的 body 解析為 JSON,導致認證簽章失敗,因此需要在 main.ts 處設定使用原始的 rawBody 才能順利通過 LINE Webhook 的驗證。
const app = await NestFactory.create(AppModule, { rawBody: true });
處理 Webhook event
而在 service 這邊則會負責處理主要的邏輯,不過在此之前會需要再次透過 Channel Access Token 建立一個 Messaging API 的 Client,這個 Client 主要可以拿來處理訊息回傳,也就是實際上官方帳號會回應給使用者什麼樣的內容。
至於 handleEvents 會接收 LINE 的 WebhookEvent 陣列,首先判斷 event 的內容是否為文字 (這邊可以根據實際需求去修改,由於本專案主要只針對文字進行處理,因此會跳過所有文字以外的內容),如果符合條件的話就會進到裡面的 handleTextMessage (這邊也是根據實際的需求撰寫的功能函式)。
export class LineBotService { private client: messagingApi.MessagingApiClient; constructor( private readonly configService: ConfigService, private readonly urlService: UrlService, ) { const channelAccessToken = this.configService.get<string>( 'line-bot.channelAccessToken', ); if (!channelAccessToken) { throw new Error('LINE Bot channel access token is not configured.'); } this.client = new MessagingApiClient({ channelAccessToken }); } async handleEvents(events: WebhookEvent[]): Promise<any> { const results = await Promise.all( events.map(async (event) => { if (event.type === 'message' && event.message.type === 'text') { return await this.handleTextMessage( event.replyToken, event.message.text, ); } return null; }), ); return results; } }
最後將 service 注入到 controller 中使用即可,這邊在回傳的地方可以手動回傳一個 200 OK 確保 LINE 在接收回應的時候不會出錯。
constructor(private readonly lineBotService: LineBotService) {} @Post('callback') async callback( @Body() body: WebhookRequestBody, @Res() res: Response, ) { const events = body.events; try { if (events && events.length > 0) { await this.lineBotService.handleEvents(events); } else { console.log('No events to process.'); } } catch (error) { console.error(error); } return res.status(200).send('OK'); } }
測試、部署
測試時我們會使用到另一個輔助工具 ngrok,它可以暫時的將自己本機端運行的服務代理到一個臨時的 https 路徑上,以方便我們進行測試。可以從官網進入並建立一個帳號,並到下載的區域把 ngrok 下載下來。
安裝成功後我們還要在終端機裡將授權的 token 加入到設定檔裡面,完成之後就可以開始使用了~
# 添加授權資訊 $ ngrok config add-authtoken (your-token) # 開始掛載(可自行設定協定類型和 port number) $ ngrok http 3000
再來回到 LINE Developers 的頁面,找到 Messaging API 底下有一欄關於 Webhook URL 的設定處,將剛剛從 ngrok 取得的連結設置進去,後面記得要帶上在伺服器中所設定處理 LINE Webhook 的路由,完成之後可以點按旁邊的 Verify 進行測試,如果出現成功的提示的話就代表基本上完成後端和 LINE Bot 的接通了~ 接下來就可以到 LINE 聊天室裡實際測試一下功能是否有正常運作。

確認功能運作正常後就可以將伺服器給部署上線了,最後也要記得再將 LINE Webhook URL 更改為服務正式的 URL~
完整的專案範例可以參考這個 Repo(一個提供短網址轉換的服務)