[13日目] 学校の食堂をIT化させる話　LINE Messaging APIで作る食堂IT化（後編）

こんにちは、なりかくんと申します。
この記事はなりかくん Advent Calender 2023の13日目の記事です。

この話は、1日目から始めた学校の食堂をIT化させる話の続きとなります。前回は、LINE Messaging APIとGASを使ったものについて紹介しました。今回は、LINE Messaging APIとPythonを使ってLINE Botを作りたいと思います。

# なぜPython？
まず最初に「なぜPythonになったのか。GASではだめなのか。」について簡単に説明します。前回の記事でも書きましたが、キャッシュレスシステムを導入する際にPayPay APIを利用します。そこで、PayPayのSDKを使いたいわけなんですけど、GASではSDKの導入をすることが出来ません。

そこで、数日前の記事で書いたPythonでPayPay APIを使えるSDKをそのまま流用したいと考え「じゃあLINE BotをPythonで作っちゃえばいいんだ」という結果に至りました。

# サーバーレス環境
前回から言っていますが、今回は「サーバーレス環境」を目指して作っていきたいと考えています。24時間動かすわけでもないBotを24時間動かしても無駄なだけですよね。学校の食堂では特に24時間動かす必要が無いためです。
そこで、今回は AWS の Lambda を活用していこうと思います。

## なぜAWS Lambdaなのか
なぜAWS Lambdaを採用したのかです。まずあの大手Amazon様が運営しているサービスなので信頼できる点が１点とAWSのサービスであればわからないことがあったらネットでググってすぐに情報が出てきます。
そのような点からAWS Lambdaを採用しました。

# AWS Lambdaのいい点
AWS Lambdaのいい点を何点か紹介しておきます。
## Pythonが簡単に使える
これがいいですよね。Pythonのサービスを非常に簡単に起動できます。API Gatewayなども非常にAPIとして使うことが出来るのもいい点です。
（まあ、私はAWS Lambda以外に使ったことが無いので他のサービスと比べたいい点があまりわからないです。）

## 無料枠が大きい
無料枠がでかいのもいいですよね、AWS Lambdaは100万/月リクエスト（最大 320 万秒/月）までは無料で使えるのでほぼ無料でサービス運営が出来てしまうのではないでしょうか。
また、Amazon API Gatewayに関しても無料枠が12ヶ月使えて100万件の処理まで出来ます。無料枠期間が終わっても日本円で200円程度で使えるので正直何も痛くありません。

# 実際にコード組んで作ってみる
では、実際にPythonでコードを作ってみます。まあ、叩くAPIは前回の記事と同じなのでその辺は省略します。
出来たコードの抜粋が以下のコードです。

```python
import json
import urllib.request
import os
import logging
from function.konzatu import konzatu
from function.menu import *
from function.paypay import *
logger = logging.getLogger()
logger.setLevel(logging.INFO)

def lambda_handler(event, context):
    for message_event in json.loads(event['body'])['events']:
        url = 'https://api.line.me/v2/bot/message/reply'
        headers = {
            'Content-Type': 'application/json',
            'Authorization': 'Bearer ' + os.environ['LINE_CHANNEL_ACCESS_TOKEN']
        }
        body = {
            'replyToken': message_event['replyToken'],
            'messages': []
        }
        userId = message_event["source"]["userId"]
        messageType = message_event["type"]
        if messageType == "message":
            messageTypeA = message_event["message"]["type"]
            if messageTypeA == "text":
                messageContent = message_event["message"]["text"]
                if messageContent == "メニュー":
                    body["messages"].append(menuCategory("shop"))
                # 省略
            else:
                # 例外処理
        elif messageType == "postback":
            postBackData = message_event["postback"]["data"]
            dataSplit = postBackData.split(",")
            if dataSplit[0] == "menuCategory":
                body["messages"].append(menuItemInCategory(dataSplit[1], dataSplit[2]))
            # 省略
            else:
                # 例外処理
        print(body)
        req = urllib.request.Request(url, data=json.dumps(body).encode('utf-8'), method='POST', headers=headers)
        with urllib.request.urlopen(req) as res:
            logger.info(res.read().decode("utf-8"))

    return {
        'statusCode': 200,
        'body': json.dumps('Hello from Lambda!')
    }
```

こんな感じですね、今回はデフォルトで入ってるモジュールを使いたかったのでurlib.requestやjsonなどしか使っていません。
また、各機能に関してはファイルを分けています。決済のコードなどはセキュリティの観点から公開は現時点では行いません。

今回もコードの解説はシンプルにAIに任せましょう。以下がAIの回答のコピーです。（解説放棄）

:::note

LINE Bot と話してるみたいなイメージで解説！
1. LINE からメッセージが届く:

「ご飯何食べる？」とか「メニュー見せて！」みたいなメッセージだよ。
2. Bot が内容を理解する:

メッセージの種類やキーワードをチェックして、何を聞かれてるか把握するんだ。
3. Bot がおしゃべり＆情報提供:

メニューを送ったり、ボタン付きメッセージで詳細に説明したりするよ。
ボタンを押すと、さらに詳しい情報や注文画面に移動できることもあるんだ！
4. LINE に返事する:

Botが考えたおしゃべりや情報をLINEに送り返す、友達とのチャットみたいなイメージ！
つまり、LINE Bot はあなたのメッセージを理解して、それに合ったおしゃべりや情報提供をしてくれる "LINE で話せる友達" みたいな存在なんだ！

まだわからないところがあれば、遠慮なく聞いてね！

補足:

コードには細かい技術的な部分もあるけど、基本的な流れはイメージで掴んでおけば大丈夫！
このコードは一部省略されているので、実際の機能はもっと複雑かも。
もっと詳しく知りたかったら、各関数の役割やコード全体の意味を聞いてくれたら解説するよ！
:::

# ライブラリはレイヤーを使う
AWS Lambdaを初めて使った際に、追加のライブラリどうやって入れるんだ？ってなりました。
結果としては「レイヤー」というのを使えば解決できるみたいです。

作り方はこの記事を参考にすれば出来るかと思います！

https://qiita.com/__DASHi__/items/268062f0dba0e93170f2

私は、paypayopaという名前でレイヤーを作ったので今後別のところでPayPay APIを使うことになっても再利用することが出来ます笑
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/549951/a92b3134-8f33-edf9-3703-85129f4b541b.png)

# 最後に
内部的な情報はあまり出せていませんが、とりあえずLINE Messaging APIとAWS Lambdaを使って現在は運用しています。
この記事を書いているときにLINEのLIFEというものを見つけたので、そっちで予約システムなどを作ってみたいなーなどとも思っています。

次回の記事は何を書くか決めてないので（食堂ネタが尽きてきた）、食堂IT化以外の話かもしれないですがまあ許してください。

最後までお読みいただきありがとうございました。