11
9

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

【今日から始めるAWS】Lambdaを使ってLINEのbotをつくる

Last updated at Posted at 2020-08-08

#はじめに
30代未経験からエンジニアをめざして勉強中のYNと申します。お読みいただきありがとうございます。
少し前に作ったLINEのbotをつくりました。
下記参考記事をそのままコピーした内容になってしまったのですが、学習ログとして投稿させていただきました。

#今回やったこと
下記のように、こちらが送ったテキストメッセージをそのまま返答してくれる、オウム返しbotを作ります。
スクリーンショット 2020-08-08 11.16.49.png

下記のサーバレス構造を構築します。(こちらの記事から図を拝借させていただきました。)
スクリーンショット 2020-08-08 11.09.26.png

#手順

  • 事前準備
  • 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
line-bot/index.js
"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](https://github.com/line/line-bot-sdk-nodejs/blob/master/examples/echo-bot/index.js)でSDKの使い方が参照できます。



`②cryptoを使ってユーザーからのメッセージの署名を検証する`

>```javascript: 
>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公式ドキュメント](https://developers.line.biz/ja/reference/messaging-api/#webhook-event-objects)にまとめられています。
リクエストに含まれるメッセージがテキストの場合、`body.events[0].message.text`に含まれます。
また、`client.replyMessage(replyToken, message)`のメソッドを使うことで、ユーザーにメッセージを返信することが出来ます。

>```javascript: 
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にアップロードする
スクリーンショット 2020-08-08 17.59.05.png
  • 4. アクセストークン(ACCESSTOKEN)とChannelSecret(CHANNELSECRET)を環境変数に登録する
スクリーンショット 2020-08-08 18.04.54.png

#API-gatewayの設定

  • 1 POSTメソッドを作成する
スクリーンショット 2020-08-08 18.13.44.png
  • 2 リクエストヘッダーによる認証を追加する
スクリーンショット 2020-08-08 18.15.21.png
  • 3 統合リクエストに作成したLambda関数を設定する
スクリーンショット 2020-08-08 18.18.58.png
  • 4 APIをデプロイ
スクリーンショット 2020-08-08 19.24.39.png

LINE webhookの設定

LINEアプリを通してユーザーから受け取ったリクエストをLambdaへ送るwebhookの設定をします。
作成したAPIのエンドポイントを、LINEコンソールのwebhook設定に反映します。
スクリーンショット 2020-08-12 16.18.07.png

スクリーンショット 2020-08-12 16.23.46.png

LINEチャンネルの設定

LINE Official Account Managerからユーザーからのメッセージに対するあいさつや応答の設定をすることができます。
スクリーンショット 2020-08-08 19.29.07.png

#最後に
Lambdaを使うことで、簡単にLINEのbotを作ることができます。
初学者でも1時間弱でつくることができました。
機械学習や外部のAPIを組み合わせれば、面白いことができそうです。
ご覧いただきありがとうございました。

11
9
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
11
9

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?