LoginSignup
7
3

More than 1 year has passed since last update.

LineMessageAPI+ngrok+Lambdaで送られてきたメッセージをそのまま返すBotを作ってみました

Posted at

前回は、AWSで公開されているgolangのLambdaコンテナイメージの事を書きましたが、
今回はこれを拡張してLineBotを作ってみました。

前提条件

ngrokに登録済みで且つ、インストール済み
LINE Developersに登録済みでチャネルも登録済み

パッケージの構成

前回の構成で、コードを拡張しようと思ったのですが、
初回main.goをbuildしようとしたらgopkg.in/yaml.v3に関するエラーが出たので今回はPythonで試す事にしました。

├── docker
│   └── lambda-python-test
│       └── Dockerfile
├── docker-compose.yml
├── lambda
│   ├── app.py
│   └── .env
└── requirements.txt

Dockerファイル作成

新たにPythonで動かすようにしたので
こちらを参考にDockerfileを作成。

FROM public.ecr.aws/lambda/python:3.8

# Copy function code
COPY ../../lambda ${LAMBDA_TASK_ROOT}

# Install the function's dependencies using file requirements.txt
# from your project folder.

COPY requirements.txt ${LAMBDA_TASK_ROOT}
RUN pip3 install -r requirements.txt

# Set the CMD to your handler (could also be done as a parameter override outside of the Dockerfile)
CMD [ "app.handler" ]
  • requirements.txtの中身はpython-dotenvだけ。
# 環境変数
python-dotenv

Pythonのコード

from dotenv import load_dotenv

import os
import sys
import json
import urllib.request

load_dotenv() # 環境変数ファイル読み込み
CHANNEL_ACCESS_TOKEN = os.environ['CHANNEL_ACCESS_TOKEN']
CHANNEL_SECRET = os.environ['CHANNEL_SECRET']
REPLY_URL = os.environ['REPLY_URL']

def handler(event, context):
    message = event['events']

    for message in event['events']:
        url = 'https://api.line.me/v2/bot/message/reply'
        headers = {
            'Content-Type': 'application/json',
            'Authorization': 'Bearer ' + CHANNEL_ACCESS_TOKEN
        }
        body = {
            'replyToken': message['replyToken'],
            'messages': [
                {
                    'type': 'text',
                    'text': message['message']['text'],
                }
            ]
        }
        request = urllib.request.Request(url, data=json.dumps(body).encode('utf-8'), method='POST', headers=headers)
        with urllib.request.urlopen(request) as response:
            body = response.read() # ログ出すようにする
#            logger.info(res.read().decode("utf-8"))

    return {
        "statusCode": 200,
        "body": json.dumps({"status": "ok"})
    }

CHANNEL_SECRET はLine Developersの「チャネル基本設定」の下の方にあるチャネルシークレットを指定。
スクリーンショット 2022-08-14 18.31.58.png
CHANNEL_ACCESS_TOKEN はLine Developersの「Messaging API設定」の下にあるチャネルアクセストークンを指定。
チャネル作成時は無いので発行する必要があります。
スクリーンショット 2022-08-14 18.36.56.png

ngrok起動

$ ngrok http 9000
ngrok                                                                                                          

Session Status                online
Account                       xxxxxxxx (Plan: Free)
Version                       3.0.6
Region                        Japan (jp)
Latency                       -
Web Interface                 http://127.0.0.1:4040
Forwarding                    https://xxxxxxxxxxxxxxxxxx.ngrok.io -> http://localhost:9000

https://xxxxxxxxxxxxxxxxxx.ngrok.io のドメインとLambdaのパスの部分をLine DevelopersのWebhook URLに設定します。
「Webhookの利用」のチェックも確か初回は入っていなかったと思うので、こちらもチェックする。
スクリーンショット 2022-08-14 19.15.32.png

※ngrok起動時に出力されるweb Interfacehttp://127.0.0.1:4040 にアクセスすると、
 リクエストの中身を見る事ができます。(これは嬉しい!!)

動作確認

実際にリクエストをしてみます。

なんか受け付けてない言われたけど一先ず返ってきた。。。
調べてみたらLine Developers側の「応答メッセージ」なる設定をオフにしないといけなかったみたいです。
「Message API設定」→「応答メッセージ:編集」→応答メッセージをオフへ切替え。

改めて送信したらちゃんと返ってきました!

最後に

Lambdaのデバッグのやり方を調べなかったので若干ハマりました。
ngrokは非常に便利なサービスだなーと思いました!
次回はオウム返しするだけじゃなくて別の事を返すように改良しようと思います!

※訂正や補足等あればコメント等いただけますとありがたいです。
最後まで読んでいただき、ありがとうございました

参考

AWS Lambda + Python + LINE Botで傘が必要か教えてもらう

7
3
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
7
3