AWS Cloud9でオウム返しLINE Botを作る


はじめに

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の利用 無効->有効
    • 応答メッセージ 有効->無効

参考

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スクリプトを全て削除し、以下のスクリプトをコピーします。

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のロググループでエラーが発生していないか確認するといいことあるかも

今回は、これでおわり