AWS + Python + LINEbotでゴミ出しリマインドをする【後編】

## はじめに
この記事はタイトルの通り、【前編】の続きとなっています。
【前編】では、ゴミの日の前日にリマインドをするLINE botを作りました。
【後編】では、【前編】で作成したLINE botに、ゴミの種類をメッセージとして送信すると、収集日が返ってくる設定を加えたいと思います。例えば、「燃えるゴミ」と送信すると、「≪収集日≫毎週火曜日・金曜日」と返ってきます。

【後編】だけ見ていただいても問題ないですが、【前編】のリンクも貼っておきます。
【前編】はこちらから！
[AWS + Python + LINEbotでゴミ出しリマインドをする【前編】](
https://qiita.com/poyopoyo7254/items/193feb9605a121efea6f)


## 使用技術
・Python3.9
・LINE Messaging API
・AWS Lambda
・Amazon API Gateway


## 簡単な構成の説明
①ユーザーがメッセージを送る
②指定したURL(API GatewayのURL)に、Webhookイベントオブジェクトを含むHTTPS POSTリクエストが送信される（簡単に言うと、指定したURL宛てに「こんなメッセージが届いたよ」という通知がされるイメージです）
③API GatewayがLambda関数を呼び出す
④Lambda関数は受け取ったメッセージに応じて、異なるレスポンスを返す
![line-gabage-reply.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2735282/3f6e076c-65db-8ee7-f10a-6782fc43fb3e.png)


## 手順

### Lambda関数作成

今回もline-bot-sdk-pythonを使ってコードを作っていきます。そのため、Lambdaレイヤーの設定が必要です。
下記コードの「チャネルアクセストークン」と「チャネルシークレット」は、[LINE Developers](https://developers.line.biz/ja/)で確認できます。
「燃えるゴミ」と送っても「燃えるごみ」と送っても反応するようにif文の記述をしています。if文はかなり長いので一部だけ抜粋しています。

```python:line-bot-gabage-reply.py

from linebot import (LineBotApi, WebhookHandler)
from linebot.models import (MessageEvent, TextMessage, TextSendMessage)
from linebot.exceptions import (LineBotApiError, InvalidSignatureError)

line_bot_api =  LineBotApi(channel_access_token = "チャネルアクセストークン")
handler = WebhookHandler(channel_secret = "チャネルシークレット")

def lambda_handler(event, context):
  signature = event["headers"]["x-line-signature"]
  body = event["body"]

  @handler.add(MessageEvent, message=TextMessage)
  def message(line_event):
    receive = line_event.message.text

    if (receive == "燃えるゴミ") or (receive == "燃えるごみ"):
      send = "【収集日】毎週火曜日と金曜日\n【排出方法】指定袋(黄色)で出す"
    elif (receive == "びん") or (receive == "ビン") or (receive == "瓶") or (receive == "空きびん") or (receive == "空きビン") or (receive == "空き瓶"):
      send = "【収集日】第2・第4水曜日\n【排出方法】指定袋(白)で出す"
    else:
      send = "その言葉には応答できません。応答できる文字についてはホームの投稿を確認してください。"

    line_bot_api.reply_message(line_event.reply_token, TextSendMessage(text=send))

  try:
    handler.handle(body, signature)
  except LineBotApiError as e:
    return {
      "statusCode" : 500,
      "body" : "Error"
    }
  except InvalidSignatureError as e:
    return {
      "statusCode" : 500,
      "body" : "Error"
    }    

  return {
    "statusCode" : 200,
    "body" : "ok"
  }

```
コードの書き方については下記サイトを参考にしました。
[AWS Lambdaを利用したLINEbotハンズオン](https://cloud5.jp/aws-lambda_line-api/)


### API Gatewayの設定

①　API Gatewayのコンソールから「APIを作成」を選択する
![api-gateway01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2735282/bd4f7edd-ce54-72e5-5a2e-b04e0696eb4e.png)

②　「REST API」を選択し、「構築」を選択する
![api-gateway02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2735282/19ab9250-d7ae-e2c1-599b-17beecf90242.png)

③　「プロトコルを選択する」
　「REST」・「新しいAPI」を選択し、「API名」に名前を入力して、「APIの作成」を押します。
![api-gateway03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2735282/65258aac-3d73-0aad-dd15-db4a8de327dd.png)

④　「アクション」から「リソースの作成」を選択する
![api-gateway04.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2735282/108727bb-299f-f755-f72e-ade98e866bd6.png)

⑤　「新しい子リソース」
　「リソース名」に名前を入力し、「API Gateway CORSを有効にする」をチェックして、「リソースの作成」を押す
![api-gateway05.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2735282/ad34ef12-b778-6dd8-853f-6d6c08712921.png)

⑥　「アクション」から「メソッドの作成」を選択する
![api-gateway06.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2735282/28a8a1fd-2eb2-c571-91f5-c5a91c0989dc.png)

⑦　メソッドのセットアップ
　メソッドは「POST」を選択し、「統合タイプ」は「Lambda関数」を選び、「Lambdaプロキシ統合の使用」にチェックをして、「Lambda関数」にリプライ用の関数を入力し、「デフォルトタイムアウトの使用」にチェックを入れ、「保存」を押す。
![api-gateway07.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2735282/6dfb5180-1b62-51ed-0093-6a4ce47bdcb5.png)

⑧　「API Gatewayに、Lambda関数を呼び出す権限を与えようとしています」でOKを押す
![api-gateway08.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2735282/ac93f533-e9f5-ce88-5891-df7956ebc3de.png)

⑨　「アクション」から「APIのデプロイ」を選択する
![api-gateway09.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2735282/f0cc758e-b738-98ea-fd66-740bcd3c633d.png)

⑩　「APIのデプロイ」
　「デプロイされるステージ」は「[新しいステージ]」を選び、「ステージ名」に名前を入れ、「デプロイ」を押す。
![api-gateway10.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2735282/457a7f53-ffc9-bedb-70e5-477463266fa9.png)

⑪　「ステージ」
　「demo」＞「/」＞「/items」＞「POST」を選択し、「URLの呼び出し」に表示されたURLをコピーする。
![api-gateway11.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2735282/8ae927d7-1395-b22b-6f90-d78bc04b84f4.png)




### LINE DeveloppersでMessaging APIの設定

　先ほどAPI GatewayでコピーしたURLを、LINE DevelopersのWebhook設定の「Webhook URL」に入力し、「Webhookの利用」をチェックする。
![line-webhook.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2735282/7a7546d5-4c71-f5de-9b0c-e2101682f618.png)

これですべての手順が終わりです！


## 完成図
　「燃えるゴミ」と送ると、収集日と排出方法が返されました。
![line-reply.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2735282/797051fb-3f61-0673-8724-bf975816fcfc.png)


## 感想

　当初はゴミの日の前日に定期的にリマインドを送る設定だけを考えていましたが、どうせなら返信してくれる機能も欲しいなと急遽追加実装してみました。一度設定した後からでも柔軟に変えられるのがいいですね。


## 参考資料
・[API GatewayとLambda(Python)でLINE BOT(Messaging API)開発 [前編]](https://qiita.com/w2or3w/items/1b80bfbae59fe19e2015)
・[AWS Lambda + Python + LINE Botで傘が必要か教えてもらう](https://qiita.com/taku-0728/items/c80bcf65aba318ac6db0)