はじめに
30代未経験からエンジニアをめざして勉強中のYNと申します。お読みいただきありがとうございます。
少し前に作ったLINEのbotをつくりました。
下記参考記事をそのままコピーした内容になってしまったのですが、学習ログとして投稿させていただきました。
今回やったこと
下記のように、こちらが送ったテキストメッセージをそのまま返答してくれる、オウム返しbotを作ります。
下記のサーバレス構造を構築します。(こちらの記事から図を拝借させていただきました。)
手順
- 事前準備
-
Lambda
の設定 - API-gatewayの設定
- LINE webhookの設定
- LINEチャンネルの設定
事前準備
- LINEデベロッパー登録
Lambdaの設定
- 1. ローカルPCでlambda関数のフォルダを作成
$ cd ~
$ mkdir line-bot
$ cd line-bot
- 2. index.jsを作成
$ npm install @line/bot-sdk
"use strict";
const line = require("@line/bot-sdk");
const client = new line.Client({ channelAccessToken: process.env.ACCESSTOKEN });
// ①SDKをインポート
const crypto = require("crypto");
exports.handler = function (event, context) {
let body = JSON.parse(event.body);
let signature = crypto
.createHmac("sha256", process.env.CHANNELSECRET)
.update(event.body)
.digest("base64");
let checkHeader = (event.headers || {})["X-Line-Signature"];
if (signature === checkHeader) {
// ②cryptoを使ってユーザーからのメッセージの署名を検証する
if (body.events[0].replyToken === "00000000000000000000000000000000") {
let lambdaResponse = {
statusCode: 200,
headers: { "X-Line-Status": "OK" },
body: '{"result":"connect check"}',
};
context.succeed(lambdaResponse);
// ③接続確認エラーを確認する。
} else {
let text = body.events[0].message.text;
const message = {
type: "text",
text,
};
client
.replyMessage(body.events[0].replyToken, message)
.then((response) => {
let lambdaResponse = {
statusCode: 200,
headers: { "X-Line-Status": "OK" },
body: '{"result":"completed"}',
};
context.succeed(lambdaResponse);
})
.catch((err) => console.log(err));
// ④リクエストとして受け取ったテキストをそのまま返す
}
} else {
console.log("署名認証エラー");
}
};
下記、index.jsにおける処理を解説します。
①SDKをインポートする
const line = require("@line/bot-sdk"); const client = new line.Client({ channelAccessToken: process.env.ACCESSTOKEN });
githubのexampleでSDKの使い方が参照できます。
②cryptoを使ってユーザーからのメッセージの署名を検証する
const crypto = require("crypto"); exports.handler = function (event, context) { let body = JSON.parse(event.body); let signature = crypto .createHmac("sha256", process.env.CHANNELSECRET) .update(event.body) .digest("base64"); let checkHeader = (event.headers || {})["X-Line-Signature"]; if (signature === checkHeader) { // ここでlambdaの処理を記載 }
cryptoはnode.jsに標準で組み込まれている暗号化に関するライブラリで、botにおける実装の詳細についてはLINE公式ドキュメントに書いてあります。
(暗号化についてはこちらの記事が分かりやすかったです)ここでは、下記2点が一致するかを検証しています。
signature
: ユーザーから送られてきたリクエスト(event.body
)を、秘密鍵(CHANNELSECRET
)を使って暗号化したもの
event.headers["X-Line-Signature"]
:リクエストヘッダーに含まれる署名
③接続確認の場合の処理を実装する
botが接続確認を行う場合、
replyToken="000..."
のリクエストが来ます。let body = JSON.parse(event.body); if (body.events[0].replyToken === "00000000000000000000000000000000"){ let lambdaResponse = { statusCode: 200, headers: { "X-Line-Status": "OK" }, body: '{"result":"connect check"}', }; context.succeed(lambdaResponse); }
④リクエストとして受け取ったテキストをそのまま返す
ユーザーから送られてきたリクエストの中身(イベントオブジェクト)はLINE公式ドキュメントにまとめられています。
リクエストに含まれるメッセージがテキストの場合、body.events[0].message.text
に含まれます。
また、client.replyMessage(replyToken, message)
のメソッドを使うことで、ユーザーにメッセージを返信することが出来ます。let text = body.events[0].message.text; const message = { type: "text", text, }; client .replyMessage(body.events[0].replyToken, message) .then((response) => { let lambdaResponse = { statusCode: 200, headers: { "X-Line-Status": "OK" }, body: '{"result":"completed"}', }; context.succeed(lambdaResponse); })
- 3. index.jsとnode_modulesを圧縮しLambdaにアップロードする
- 4. アクセストークン(ACCESSTOKEN)とChannelSecret(CHANNELSECRET)を環境変数に登録する
API-gatewayの設定
LINE webhookの設定
LINEアプリを通してユーザーから受け取ったリクエストをLambda
へ送るwebhookの設定をします。
作成したAPIのエンドポイントを、LINEコンソールのwebhook設定に反映します。
LINEチャンネルの設定
LINE Official Account Manager
からユーザーからのメッセージに対するあいさつや応答の設定をすることができます。
最後に
Lambda
を使うことで、簡単にLINEのbotを作ることができます。
初学者でも1時間弱でつくることができました。
機械学習や外部のAPIを組み合わせれば、面白いことができそうです。
ご覧いただきありがとうございました。