PostgreSQLのデータをLINE botが取得・送信してくれるには？(python)

#目次
* 目的
* 導入
* プログラムの作成
* デプロイ
* 参考文献

# 1. 目的
* 今回はユーザのラインでの問い合わせに対してPostgreSQLのデータを取得し、送信してくれるようなシステムがあればいいなということで作ってみました。

* 家の温度や湿度をセンサで取得し、その値をPostgreSQLに格納する。
その後、家の外からでも家の中の状態をラインで把握できるといった応用例があります。

※プログラムは一例として作っています。

# 2. 導入
* LINE botはSSL通信が必須事項のため、herokuを使うと簡単に無料でアプリ作成が可能です。
また、PostgreSQLはherokuサイト内からデータ詳細など確認が可能で互換性が高いのでこちらを使用することにしました。
  * PostgreSQLの無料プランにはいくつかの制約があるので注意(１万行までなど)

* 過去に投稿したLINE Bot、herokuの導入部分は[こちら](https://qiita.com/paupau/items/ca147ba89d376ed0b0c2)

* pythonのコードとは別にherokuと接続する際に必要なrequirments.txtとProcfileが必要です。


流れとしては
ーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーー
LINE Messaging APIの登録、LINE botの作成([やり方はこちら](https://developers.line.biz/ja/docs/messaging-api/building-bot/))
↓
herokuの登録([やり方はこちら](https://blog.proglus.jp/1438/))
↓
LINE Messaging APIでWebhook URLの登録をしてherokuとLINE botを繋げる([やり方はこちら](https://developers.line.biz/ja/docs/messaging-api/building-sample-bot-with-heroku/))
↓
herokuサイト内からPostgreSQLの接続([やり方はこちら](https://creepfablic.site/2019/05/14/heroku-postgresql/#index_id0))
↓
コマンドにてSQLログイン、テーブルを作成([やり方はこちら](https://qiita.com/Shitimi_613/items/bcd6a7f4134e6a8f0621))
↓
LINEのプログラム作成

ーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーー


大まかにはこうなります。



* データベースの要素は
  id  |            time            | temp |   hum
となっていて、idは主キーとして設定しており、テーブル名はtableです。

#### PostgreSQLのdatetimeでつまづいた点
* デフォルトでUTC時間になっているので注意




# 3. プログラムの作成

* 今回はpythonでの実装になります。

* 各言語のサンプルプログラムは[こちら](https://developers.line.biz/ja/docs/messaging-api/line-bot-sdk/)


* 初めにpsycopg2のインストールをします。
pythonからPostgreSQLを扱うのに必須なライブラリです。

```python
from flask import Flask, request, abort

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

app = Flask(__name__)


line_bot_api = LineBotApi('')
handler = WebhookHandler('')


@app.route("/")
def test():
    return "ok"


@app.route("/callback", methods=['POST'])
def callback():
    # get X-Line-Signature header value
    signature = request.headers['X-Line-Signature']

    # get request body as text
    body = request.get_data(as_text=True)
    app.logger.info("Request body: " + body)

    # handle webhook body
    try:
        handler.handle(body, signature)
    except InvalidSignatureError:
        print("Invalid signature. Please check your channel access token/channel secret.")
        abort(400)

    return 'OK'

def connect(): #接続に必要(herokuサイト内から確認可)
    
    con = psycopg2.connect("host=" + "" +
                           " port=" + "5432" +
                           " dbname=" + "" +
                           " user=" + "" +
                           " password=" + "")

    return con

def select_execute(con, sql):
    with con.cursor() as cur:
        cur.execute(sql)
        rows = cur.fetchall()

    return rows

@handler.add(MessageEvent, message=TextMessage)
def handle_message(event):

if event.message.text=="温度":
            con = connect()
            sql =  'select temp from table where ID=select max(ID)'#最新の温度
            res = select_execute(con, sql)
            pec=res[0][0] #数値のみ抽出
            line_bot_api.reply_message(
                event.reply_token,
                TextSendMessage(text=f"現在の部屋の温度は" + str(pec) + f"%です"))

if event.message.text=="湿度":
            con = connect()
            sql =  'select hum from table where ID=select max(ID)'#最新の湿度
            res = select_execute(con, sql)
            pec=res[0][0] #数値のみ抽出
            line_bot_api.reply_message(
                event.reply_token,
                TextSendMessage(text=f"現在の部屋の湿度は" + str(pec) + f"%です"))
else:
            line_bot_api.reply_message(
                event.reply_token,
                TextSendMessage(text=f"入力が間違っています。もう一度入力してください"))

if __name__ == "__main__":
    app.run()


```

# 4. デプロイ
```
git add .  #変更したファイルを全てインデックスに登録

git commit -m "inital commit"  #変更したファイルをリポジトリに書き込む（"inital commit"はコメントなのでなんでも良い）

git push heroku main  #herokuにローカルで作成したファイルをpush

```
の3つでデプロイ完了です。
最新のLINE botプログラムが動作できるようになりました。

#### 最後に

今回はpythonでデータを取得、送信を実装しました。
近いうちに[PostgreSQL データをnode.jsで挿入してみる](https://qiita.com/paupau/items/7dd38ca693f21b0d8280)を投稿したいと思います。


# 5. 参考文献

[参考にさせていただいたサイト]

https://developers.line.biz/ja/docs/messaging-api/building-bot/

https://blog.proglus.jp/1438/

https://developers.line.biz/ja/docs/messaging-api/building-sample-bot-with-heroku/

https://qiita.com/yokotate/items/8f86103c8dd3bdfea4d3

https://www.i-ryo.com/entry/2020/10/20/081654#hobby-devプランとは無料だが1万行まで

https://qiita.com/Shitimi_613/items/bcd6a7f4134e6a8f0621