割勘計算(立替計算)してくれるLINE botがあったら友達と遊びに行くときに便利だなーと思い、こんなものを作ってみました。
LINE botを作る=アプリ公開ということになるので、自分が使っているレンタルサーバー(Xserver)にプログラムをアップする必要があるのかと思っていました。
が、今回はHerokuを使えばアプリを1つまで無料公開できると聞いたので使ってみることに。
無料でLINE botを公開できるとは・・・!
LINE developersもHerokuも太っ腹ですね。。。
LINE bot公開までの大体の流れ
- LINE公式アカウントを「応答モード:Bot」で作成
- LINE Official Account Managerで作ります
- アカウント認証をリクエストして認証アカウントになっておくと、Bot開発時に使うMessaging APIで使える機能が増えます
- 作成したアカウントのチャネルを作る
- LINE Developersで作ります
- 実際にLINE botを使う時に話す相手となるのはこっち。
つまり、トプ画などにこだわる必要があるのはLINE Official Account Managerで作ったアカウントではなくて、ここで作るチャネル
- Herokuのアカウントを作成
- 「Heroku」で検索してアカウント登録するだけ
- 以降、とりあえずオウム返しのLINE botを作ることを目指す
- Herokuにアプリを追加
- このアプリでLINE botを開発することになる
- HerokuアプリにLINEチャネルを紐づける
- Herokuアプリにチャネルシークレットを登録する
- LINEアカウントに来たメッセージを拾うため
- Gitを使って変更内容を反映
- 今後もプログラムを更新する度にGit Pushが必要です。
- LINEチャネルのWebhook URLを設定する
- HerokuアプリのURLを設定することになる
- このアカウントにメッセージが来たらこのURLに応答方法を決めてもらうんですよ、という取り決め
- Herokuにアプリを追加
4までできれば「請求:100」と言われたら「add 100」と返す、くらいのことはできます。
参考にしたのはこちらのサイト。とりあえずオウム返しのLINE botが出来ればOKです。
ユーザー情報を取得する方法
送られてきたメッセージの内容は勿論、ユーザー名(ユーザーアカウントの表示名)やグループIDを取得することができます。
非認証アカウントでは、友達登録してくれたユーザーの情報しか取得できないようです。
従って、グループに参加しているユーザーの人数を知るためには、参加者全員に友達になってもらって何かしらのメッセージを送ってもらう必要があると。。。
割勘計算の場合、支払していない人も「請求:0」と送って参加していることを示してもらわないといけません。
1 2 3 4 5 6 7 8 9 10 11 12 13 |
@handler.add(MessageEvent, message=TextMessage) def handle_message(event): message = event.message.text #メッセージ profile = line_bot_api.get_profile(event.source.user_id) name = profile.display_name #ユーザーの表示名 group = event.source.group_id #グループID #色々処理してReplyのメッセージ文を作る #返信 line_bot_api.reply_message( event.reply_token, TextSendMessage(text=reply)) |
Herokuのデータベースを使って割勘計算
割勘計算をするためには、ユーザーが請求した金額を保存して、加算・計算できないといけません。
データベースが必要です。
Herokuのすごいところは、DBも無料で使わせてくれるところ。
PostgresというDBを使います。
ブラウザ上で見るHerokuのアプリページのResourceに、「Heroku Postgres」を追加するだけで利用開始できます。
コマンドプロンプト上で以下のコードを打てば、SQL文を書くことも可能。
1 |
heroku pg:psql |
私の割勘ボットでは、あらかじめ以下のようなテーブルを作っておいてから、LINE botの処理の中でデータのINSERTをしています。
1 2 3 4 5 6 7 8 |
CREATE TABLE split_tb ( id SERIAL NOT NULL, group_id TEXT NOT NULL, user_id TEXT NOT NULL, bill INT NOT NULL, amount INT NOT NULL, created_at TIMESTAMP ); |
MySQLしか使ったことがなかったのでちょっと混乱。
SERIALという型で自動採番の主キーを作ってもらえるみたいです。
PythonからPostgresを編集する書き方
アプリのプログラムとしてはだいぶ省略していますが、SELECT文、INSERT文、DELETE文はこんな感じで書けます。
%sに単一の項目を代入する時にも、
1 |
cur.execute("SELECT amount FROM split_tb WHERE id=%s", (id,)) |
(id,)というように最後にカンマが必要です。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 |
def get_connection(): dsn = "host=[ホスト] port=5432 dbname=[DB] user=[ユーザー] password=[パスワード]" return psycopg2.connect(dsn) #bill = いくら請求するのか #group = LINEのグループID #name = LINEの表示名 def calc(bill, group, name): with get_connection() as conn: #↓を書かないならInsertする度にCommit文を書く必要がある conn.autocommit = True with conn.cursor() as cur: #SELECT文 (このグループに関する最新のIDを取得) cur.execute("SELECT MAX(id) FROM split_tb WHERE group_id=%s",(group,)) rows = cur.fetchall() #多重リストの形で取り出される id = rows[0][0] #SELECT文2 (最新の合計金額情報がを取得) cur.execute("SELECT amount FROM split_tb WHERE id=%s", (id,)) rows = cur.fetchall() amount = rows[0][0]+bill #INSERT文 (今回請求された金額をDBに登録) data=[group,name,bill,amount,time] cur.execute("INSERT INTO split_tb (group_id, user_id, bill, amount, created_at) VALUES (%s,%s,%s,%s,%s)", data) #DELETE文 (特定のグループに関する情報を全て削除) cur.execute("DELETE FROM split_tb WHERE group_id=%s",(group,)) |
完成品はこちら
とりあえず自分の友達に使ってもらうことで立替計算のわずらわしさから解消されたい!