前提
LINE Messaging APIを用いて、チャットボット開発をしています。開発手法としてはSAMを用いて、バックエンド(具体的にはチャットボットとして応答する部分)をlambdaに書いています。このコードを実際にチャットボットとして動かすには、lambdaをローカル、もしくは本番サーバーに上げ、URLをWebhookURLとして登録してあげる必要があります。詳しくはLINE Messaging APIの公式ドキュメントを見て下さい。(https://developers.line.biz/ja/docs/messaging-api/overview/)
実現したいこと
ローカルホストURL(http://localhost:3000等)でチャットボットの挙動をテストしたい。
*ngrokを用いてローカルホストのURLをHTTPS通信のURLに変換しているので、WebhookURLを誤ってHTTP通信のURLを登録したという原因ではありません。
発生している問題
sam deploy
を用いて本番サーバーに書いたコードを上げた場合はWebhookでの通信が成功し、チャットボットとして問題なく動くのですが、ローカルでテストしたい場合、つまりsam local start-api
を用いてローカルホストのURLをWebhook用のURLとして登録しても、チャットボットとして上手く動きません。
ソースコード
基本的にはsam init
でのテンプレートの一つであるHello World Functionに付け足して書いたものですので、template.ymlはほとんど触っていません。
lambdaにあたるapp.pyのコード
python
1import os 2import json 3from linebot import (LineBotApi, WebhookHandler) 4from linebot.models import (MessageEvent, TextMessage, TextSendMessage) 5from linebot.exceptions import (LineBotApiError, InvalidSignatureError) 6 7handler = WebhookHandler(os.environ.get('CHANNEL_SECRET')) 8line_bot_api = LineBotApi(os.environ.get('ACCESS_TOKEN')) 9 10# Lambda Response 11ok_response = { 12 "isBase64Encoded": False, 13 "statusCode": 200, 14 "headers": { 15 "X-Line-Status" : "OK", 16 "Content-Type": "application/json" 17 }, 18 "body": "{}" 19} 20error_response = { 21 "isBase64Encoded": False, 22 "statusCode": 401, 23 "headers": { 24 "Content-Type": "application/json" 25 }, 26 "body": "{}" 27} 28 29 30def lambda_handler(event, context): 31 signature = event["headers"]["x-line-signature"] 32 body = event["body"] 33 print(body) 34 35 if json.loads(body)["events"]: 36 37 # When TEXT message were sent by someone 38 @handler.add(MessageEvent, message=TextMessage) 39 def message(line_event): 40 text = line_event.message.text 41 line_bot_api.reply_message(line_event.reply_token, TextSendMessage(text=text)) 42 43 else: 44 return json.dump(ok_response) 45 46 # confirms that the requests were sent from LINE platform 47 try: 48 handler.handle(body, signature) 49 50 raise Exception("Unexpected Error has occured") 51 52 except Exception as e: 53 print(e) 54 55 # When LINE Messaging API responsed error 56 except LineBotApiError as e: 57 print(e) 58 return error_response 59 60 # When Webhook signature does NOT match 61 except InvalidSignatureError as e: 62 print(e) 63 return error_response 64 65 return json.dump(ok_response)
リソース等の設定を行うtemplate.ymlファイル
YML
1AWSTemplateFormatVersion: "2010-09-09" 2Transform: AWS::Serverless-2016-10-31 3Description: > 4 python-demo 5 6 Sample SAM Template for python-demo 7 8# More info about Globals: https://github.com/awslabs/serverless-application-model/blob/master/docs/globals.rst 9Globals: 10 Function: 11 Timeout: 3 12 Environment: 13 Variables: 14 CHANNEL_SECRET: "*******************" 15 ACCESS_TOKEN: "*******************" 16 17Resources: 18 HelloWorldFunction: 19 Type: AWS::Serverless::Function # More info about Function Resource: https://github.com/awslabs/serverless-application-model/blob/master/versions/2016-10-31.md#awsserverlessfunction 20 Properties: 21 CodeUri: hello_world/ 22 Handler: app.lambda_handler 23 Runtime: python3.8 24 Events: 25 HelloWorld: 26 Type: Api # More info about API Event Source: https://github.com/awslabs/serverless-application-model/blob/master/versions/2016-10-31.md#api 27 Properties: 28 Path: /hello 29 Method: post 30 31Outputs: 32 # ServerlessRestApi is an implicit API created out of Events key under Serverless::Function 33 # Find out more about other implicit resources you can reference within SAM 34 # https://github.com/awslabs/serverless-application-model/blob/master/docs/internals/generated_resources.rst#api 35 HelloWorldApi: 36 Description: "API Gateway endpoint URL for Prod stage for Hello World function" 37 Value: !Sub "https://${ServerlessRestApi}.execute-api.${AWS::Region}.amazonaws.com/Prod/hello/" 38 HelloWorldFunction: 39 Description: "Hello World Lambda Function ARN" 40 Value: !GetAtt HelloWorldFunction.Arn 41 HelloWorldFunctionIamRole: 42 Description: "Implicit IAM Role created for Hello World function" 43 Value: !GetAtt HelloWorldFunctionRole.Arn
バージョン情報
line-bot-sdk==1.17.0
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。