はじめに
AWS Cloud9 上でSAM Local
を使い、オウム返しするLINE Botを作るメモ
構成図
こんなの作ります。
手順の概要
- [LINE Developers] プロバイダー作成
- [LINE Developers] 作成したプロバイダーにチャネルを設定
- [LINE Developers] 作成したチャネルで2つの情報を取得
- チャネルアクセストークン
- チャネルシークレット
- [AWS] Cloud9環境を用意する(東京リージョン: ap-northeast-1)
- [AWS-Cloud9] Lambdaを作成する
- Function name
- Application name
- [AWS] Lambdaスクリプト更新
- [AWS] Lambdaに環境変数を設定
- LINE_CHANNEL_SECRET (チャネルシークレット)
- LINE_CHANNEL_ACCESS_TOKEN (チャネルアクセストークン)
- [AWS] API GatewayのURL呼び出し を確認
- [LINE Developers] チャネルの設定更新
- Webhook URL (← API GatewayのURL呼び出し)
- Webhookの利用 無効->有効
- 応答メッセージ 有効->無効
参考
-
LINE Messaging API × AWS Lambdaによる簡易応答システム #2-appx1: 署名検証
- 主にLambdaスクリプトを参考にさせて頂きました。
1.[LINE Developers] プロバイダー作成
LINE Developersでプロバイダーを作成します。
2.[LINE Developers] 作成したプロバイダーにチャネルを設定
先ほど作成したプロバイダーにチャネルを設定します。
Messaging APIを選択します。
3.[LINE Developers] 作成したチャネルで2つの情報を取得
チャネルシークレット、チャネルアクセストークンの情報を取得します。
チャネルアクセストークンの情報は、発行ボタンをクリックします。
4.[AWS] Cloud9環境を用意する
AWSコンソールで、Cloud9を作ります。東京リージョン(ap-northeast-1)で作成しました。
5.[AWS-Cloud9] Lambdaを作成する
SAM Localを使いLambdaを作成します。Cloud9の右側にあるλ
-> λ+
とクリックし、新規作成します。
赤枠の欄に、任意の文字列を設定しNext
ボタンをクリック
Pythonを選択しました。
API Gatewayもまとめて作成します。
デフォルト設定にしました。
Finish
ボタンをクリックすると作成が開始されます。
作成が完了すると、このような画面になります。
※余談※ [AWS] 作成したAWSリソース確認
これまでで作成したAWSリソースは、CloudFormationスタックで確認できます。2つのスタックが作られていて、最初のスタック(aws-cluod9-xxx)は、Cloud9を作成したときのスタック、次のスタック(cloud9-app1)は、Lambdaを作ったときのスタックです。
Lambdaを作ったときのスタックのリソースタブで作成されたAWSリソースを確認できます。
6.[AWS] Lambdaスクリプト更新
今あるLambdaスクリプトを全て削除し、以下のスクリプトをコピーします。
# 環境変数
# LINE_CHANNEL_SECRET チャネルシークレット
# LINE_CHANNEL_ACCESS_TOKEN チャネルアクセストークン
import json
import os
import logging
import urllib.request
import base64
import hashlib
import hmac
# ログ出力の準備
logger = logging.getLogger()
logger.setLevel(logging.INFO)
def lambda_handler(event, context):
# リクエスト内容をログ出力
logger.info(event)
###
# 環境変数からLINEチャネルシークレットを取得
channel_secret = os.environ['LINE_CHANNEL_SECRET']
# LINEチャネルシークレットを鍵として、HMAC-SHA256アルゴリズムを使用してリクエストボディのハッシュ値を算出
hash = hmac.new(channel_secret.encode('utf-8'), event['body'].encode('utf-8'), hashlib.sha256).digest()
# ハッシュ値をBase64エンコード
signature = base64.b64encode(hash)
# X-Line-Signatureを取得
xLineSignature = event['headers']['X-Line-Signature'].encode('utf-8')
# 署名の一致を検証し、不一致の場合はログ出力
if xLineSignature != signature:
logger.info('署名の不一致')
return {
'statusCode': 200,
'body': json.dumps('署名が正しくないみたいだよ。')
}
###
# 1. Webhookイベントの内容を抽出
body = json.loads(event['body'])
for event in body['events']:
# 応答用のメッセージオブジェクトのリストを定義
messages = []
# 2. Webhookイベントタイプがmessageであり、
if event['type'] == 'message':
# 3. メッセージタイプがtextの場合に、
if event['message']['type'] == 'text':
# 4. 受信したテキストの内容をメッセージオブジェクトとする
messages.append({
'type': 'text',
'text': event['message']['text']
})
# 応答メッセージのリクエスト情報を定義
url = 'https://api.line.me/v2/bot/message/reply'
headers = {
'Content-Type': 'application/json',
# 環境変数からLINEチャネルアクセストークンを取得
'Authorization': 'Bearer ' + os.environ['LINE_CHANNEL_ACCESS_TOKEN']
}
data = {
# 応答用トークンとメッセージオブジェクトを設定
'replyToken': event['replyToken'],
'messages': messages
}
request = urllib.request.Request(url, data = json.dumps(data).encode('utf-8'), method = 'POST', headers = headers)
with urllib.request.urlopen(request) as response:
# レスポンス内容をログ出力
logger.info(response.read().decode("utf-8"))
return {
'statusCode': 200,
'body': json.dumps('Hello from Lambda!')
}
lambdaスクリプトを更新したら、デプロイボタン(上向きの矢印アイコン)でデプロイします。
7.[AWS] Lambdaに環境変数を設定
AWSコンソールでLambdaを開き、LINE Developersで作成したチャネルの チャネルシークレット
とチャネルアクセストークン
を環境変数として設定します。
8.[AWS] API GatewayのURL呼び出しを確認
API GatewayのURL呼び出し
を確認します。
9.[LINE Developers] チャネルの設定更新
さきほど確認した API GatewayのURL呼び出し
をLINE Developersで作成したチャネルのWebhook URLとして設定とWebhookの利用を有効にします。さらに、応答メッセージを無効にします。
これで『オウム返しのLINE Bot』の設定が完了です。
[LINE Bot] 動作確認
作成したチャネルをQRコードから友達登録し、オウム返しするか確認します。
このように、オウム返しをすれば成功
※補足※ [AWS] うまく動かないとき
CloudWatchのロググループでエラーが発生していないか確認するといいことあるかも
今回は、これでおわり