LINE Messaging API w/AWS Lambda, Amazon API Gateway, apex
API Gateway と AWS Lambda で LINE Messaging API を使った Bot を作る
tl;dr
LINE Bot w/Node
基本的には、client からのメッセージを webhook で受けとり、 Messaging API 経由で返事をする。
Lambda で Node を使って webhook を受けとり、テキストメッセージにだけエコーする処理は以下の通り。API Gateway から event を受け取る事を想定している。API Gateway に向けて {status: ..., headers: ..., body: ...}
のような形で返すと、各 field が http の response にマッピングされる。
'use strict'; const crypto = require('crypto'); const https = require('https'); const channelAccessToken = process.env.CHANNEL_ACCESS_TOKEN; const channelSecret = process.env.CHANNEL_SECRET; const isValidSignature = (headerSignature, body) => { const generatedSignature = crypto.createHmac('sha256', channelSecret) .update(body, 'utf8') .digest('base64'); return headerSignature === generatedSignature; }; const replyTextMessage = (replyToken, text) => { const body = { replyToken: replyToken, messages: [ {type: 'text', text: text}, ], } const options = { method: 'POST', hostname: 'api.line.me', path: '/v2/bot/message/reply', headers: { 'Content-Type': 'application/json; charset=utf-8', 'Authorization': 'Bearer ' + channelAccessToken, }, }; const req = https.request(options, (res) => console.log(res)); req.write(JSON.stringify(body)); req.end(); }; exports.handle = (event, context, callback) => { // console.log(event); const xLineSignature = event.headers['X-Line-Signature']; const body = event.body; if (!isValidSsignature(xLineSignature, body)) { callback(null, { statusCode: 400, headers: {}, body: 'NG', }); return; } JSON.parse(body).events.forEach((event) => { if (event.type == 'message' && event.message.type === 'text') { replyTextMessage(event.replyToken, event.message.text); } else { console.log('no implementation.') } }); callback(null, { statusCode: 200, headers: {}, body: 'OK', }); };
apex
Node の Library とか使いたいし、気軽に Lambda に deploy したいので apex を利用する。
GitHub - apex/apex: Build, deploy, and manage AWS Lambda functions with ease (with Go support!).
上記の Node のコードでは channelAccessToken
と channelSecret
を環境変数から取得している。apex init
後にコードを置いて、apex deploy -E env.json
すると、環境変数が設定された上で Lambda にコードを deploy 出来る
{ "CHANNEL_ACCESS_TOKEN": "...", "CHANNEl_SECRET": "..." }
apex を利用した場合、zipにまとめて Lambda に乗せてくれるため、npm/yarn で管理した library も簡単に利用することが出来る。
API Gateway
手で設定するなら Endpoint を作って、 apex で deploy された Lambda へ繋げるだけ。 後々このあたりは terraform で管理する。