Line Messaging API で Line Bot を作ってみた | AWS lambda
March 03, 2020

DEVELOPMENT

web
line

Line Messaging API を AWS Lambda + API Gatewayで実装する設定方法のご紹介です。

はじめに

Twitterをやっていて、いろんなエンジニアを見て触発されたので、

自分の事業にためになるものを!と思い!

今や老若男女、ほとんどの人が使っているLineを使った簡単なサービスができたらな。と思い、

何かできないかと考えていたところ、

自分の事業でやっている焼肉店で使えるものがいいなっと思い、

今回は、

どの部位を食べればいいかわからない時に、提案してくれるBot

を作成してみました。

使うもの

  • Line developer アカウント
  • AWS アカウント(httpリクエストを投げれて、レスポンスを返せれば何でもよい。)
  • 言語はNode.jsでやりました。

サーバーが必要

色々と、迷ったのですが、一番使い慣れている、AWS(API Gateway + Lambda)を使いました。他に、GCPやLine developerのドキュメント見るとHerokuでの方法が紹介されていました。

Line側でメッセージを受信すると、設定されているwebhookのURLに著名をつけて、httpリクエストを投げるので、それを受け取れれば、どこでもOKです。

Ngrokを使えば、localで試すこともできますね

参考([Rails]LINE Botをローカル環境で動かしたりデバッグしたりする方法)


Line Developer登録

こちらのLine Developerサイトから、

「今すぐはじめよう」から進みます。

必要事項を入力していきます。

入力内容は、Messaging APIを利用するにはを見ればわかります。

  • プロバイダ → 会社名や使う組織名
  • チャンネル → これが実際のアカウントとなる

進めていき、webhookのURLを有効にし、設定しますが、まだわかりませんね。


必要事項だけメモ

  • チャンネル基本設定から「チャンネルシークレット」
  • Messaging API設定の設定から「チャネルアクセストークン」

の2つをメモして、一旦AWSの設定に行きます。


AWS 側

Lambdaの作成

  • コンソールから、Lambdaへ
  • 関数を新規作成
  • line-bot等のnode moduleが必要なので、一旦ローカルでインストールする

    $ npm install @line/bot-sdk

    ※ npm initする際、lambda側のnode バージョンと、localのnodeバージョンは合わせておきましょう

  • lambda関数のnodeスクリプトを書く
'use strict';
const crypto = require('crypto');
const line = require('@line/bot-sdk');
const client = new line.Client({channelAccessToken: process.env.ACCESSTOKEN});

exports.handler = function (event, context) {

 let signature = crypto.createHmac('sha256', process.env.CHANNELSECRET).update(event.body).digest('base64');
 let checkHeader = (event.headers || {})['X-Line-Signature'];
 let body = JSON.parse(event.body);

 if (signature === checkHeader) {
  // lineの接続チェック用
  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': 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('署名エラー');
 }
};

こちら参考にさせていただきました。

  • 圧縮してlambdaにUP

    $ zip -r lambda.zip .

    これをLambda画面からアップロードします。

  • 先程した、Lineの必要事項を設定 Lambdaの環境変数に2つを設定します。
ACCESSTOKEN => メモした「チャンネルシークレット」
CHANNELSECRET => メモした「チャネルアクセストークン」

Lambdaは以上です。


APIGatewayの設定

  • 新規にAPIを作成し、/直下(何でもいいリソース作ってもOK)で、POSTメソッドを作成します。
  • 下記設定をメソッドリクエストの設定をする

統合タイプ = Lambda

Lambda プロキシ統合の使用 = チェック

Lambda リージョン = 先ほど作ったLambdaのリージョン

先程Lambda 先程作ったLambda関数を選択

  • HTTPリクエストヘッダー の設定

LINEからのリクエストには「X-Line-Signature」がついてくるので、これを必須とする

リクエストの検証 = なし

HTTP リクエストヘッダー = “X-Line-Signature”

  • ステージを作成(なんでもOK)して、デプロイしてURLをコピる

Line Developerでwebhookを設定

Messaging API設定の設定から

  • Webhookの利用をON
  • Webhook URLを先程取得した、API GatewayのURLを設定
  • 通信チェックを行う

StatusOKとなれば、大丈夫です。

  • APIのデプロイに時間がちょっとかかるんで、少し時間をおいてからやればOKになるはずです。

ここまでで、AWSとLine messaging APIの設定はOKです。


試す

Line Developer のMessaging API設定に、QRコードがあると思うので、これを取ると、トーク画面にいけますね。

たぶん、アカウントの認証すれば、LINE上で検索しても出てくると思います。


どんなBOTか?

僕は、焼肉店を経営しているのですが、お客さんによく部位の質問をされます。

そんときに、面白おかしく、Lineで

その人におすすめのお肉を提案してあげる

というようなBOTにしました。

AWS Lambda上で、コード修正し実装しましたが、質問して、YESかNOで答えてもらって、 その内容に応じて質問を変えていき、最終的に絞り込み、肉の部位を答えるというような、

一時期はやったアキネイターみたいなイメージをラインのトークで行うというものです。

AI的な要素は全くの素人なので難しいですね。

本当は、DynamoDBとかにデータ用意したほうがいいと思うのですが、とりあえず配列で、

  • 質問一覧
  • 答え一覧
  • 答えと質問のマッピングデータ
  • ユーザーが答えることにより抽出された残りの答えリスト

こんな感じデータを用意し、配列をガチャガチャいじって、 最終的に「ユーザーが答えることにより抽出された残りの答えリスト」が一つになったら終了という感じです。

コードの内容はお見せするに価しないので、どうしてもの方がもしいらっしゃれば、Twitterにでもコメント下さい。。。

なお、Lineから取得するリクエストデータと、返すべきレスポンスの一覧はそれぞれ以下に記載があります。


まとめ

今回なんとか、対話ができ、最終的におすすめのお肉を提案できるところまで行きました。 Lambdaのグローバル変数により、キャッシュされるので、それのおかげで、対話の答えを記録し、最終的に答えまで持って行けていますが、 実際サービスにする場合は、

これをLineからくるユーザーIDごとに、DyanamoDBにしまう処理が必要になるので後日改修し、サービスインできたらなーっと 思います。

結構面白いので、ぜひやってみて下さい。

あとAIエンジニアの方、いい方法あったら教えて下さい。

追記 2020/03/04

→ DynamoDBにデータを保存し、Lineに申請を出しました! 申請が降りたら使って頂けます!楽しみです。

サンプルはこんな感じです。動画キャプチャです。

うかい / 株式会社UKAI
うかい@代表取締役兼エンジニア株式会社UKAI
Nobuyuki Ukai

株式会社UKAI 代表取締役CEO。建築を専攻していたが、新卒でYahoo!Japanにエンジニアとして入社。その後、転職、脱サラ、フリーランスエンジニアを経て、田舎へ移住し、ゲストハウスの開業、法人成り。ゲストハウス2軒、焼肉店、カフェ、食品製造業を運営しています。詳細はこちらから

🙏よかったらシェアお願いします🙏
WRITTEN BY
うかい / 株式会社UKAI
うかい@代表取締役兼エンジニア株式会社UKAI

Nobuyuki Ukai

株式会社UKAI 代表取締役CEO。建築を専攻していたが、新卒でYahoo!Japanにエンジニアとして入社。その後、転職、脱サラ、フリーランスエンジニアを経て、田舎へ移住し、ゲストハウスの開業、法人成り。ゲストハウス2軒、焼肉店、カフェ、食品製造業を運営しています。詳細はこちらから

CONACT
入力して下さい
Slack からもどうぞ

※お気軽にどうぞ!(6月20日まで有効!お早めに)

COPYRIGHT © 2020 UKAI CO., LTD. ALL RIGHTS RESERVED.