我が家のLine_Botを作るぜ
category:code:My_Line_bot
プログラム概要
主な使用ライブラリ:flask,line-bot-sdk,gspread,oauth2client
やりたかったこと:我が家のオリジナルLine_botを作りたい。でもってgoogle-spreadsheetで返答を簡単に編集したい。
各方面、無課金にて実装できた(これ大事!)。よく見ている「いまにゅのプログラミング塾」の動画を複数参考にさせてもらってます。
こういうやつ
作成手順
1:Google Cloud Platform設定
GoogleアカウントでGCPに登録。クレジットカードの登録が必要。今回の用途(driveとsheets_API)は
登録すれば制限なく無料にて利用可能のようである(R3.7現在)。
プロジェクトを作成し、「APIとサ-ビス」より「Google Drive API」と「Sheets API」を有効化。
「APIとサ-ビス」の認証情報より、サービスアカウントを適当な名前で新規作成し、jsonファイルをダウンロードする。
スプレッドシートを作成し、「共有」ボタンよりjsonファイル内の「client_email」のアドレスを編集者として共有させる。
※スプレッドシートのURLとSheet名が後々必要になるので控えておく。
↓適当に返してほしい文字列を入れておく
2:LINE Developers設定
LINE DevelopersにLineアカウントでサインイン。
messaging-api
のページでプロバイダを新規登録する。
ここでは「チャネル基本設定」タブの「チャネルシークレット」と
「Messaging API設定」タブの「チャネルアクセストークン」を控える。
3:line-bot-sdkで実装
いよいよpythonで実装。LINE公式ライブラリの「line-bot-sdk」のpythonのGithubリポジトリより、入力をそのままオウム返し
するコードが書いてあるため借用。
#app.py
import os
import random
import pandas as pd
import gspread
from flask import Flask, request, abort
from linebot import (
LineBotApi, WebhookHandler
)
from linebot.exceptions import (
InvalidSignatureError
)
from linebot.models import (
MessageEvent, TextMessage, TextSendMessage,
)
from datetime import datetime, timedelta
from oauth2client.service_account import ServiceAccountCredentials
app = Flask(__name__)
#実際は直書きはせず、os.environでherokuの環境変数に入れる。後述。
YOUR_CHANNEL_ACCESS_TOKEN="手順2のチャネルトークン"
YOUR_CHANNEL_SECRET="手順2のチャネルシークレット"
line_bot_api = LineBotApi(YOUR_CHANNEL_ACCESS_TOKEN)
handler = WebhookHandler(YOUR_CHANNEL_SECRET)
@app.route('/')
def hello_world():
return "hello_world"
@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'
#ここまでほぼ公式のまま。ここからちょっと変更して、オウム返しでなく、スプレッドシートから返答を引き出す仕様に。
@handler.add(MessageEvent, message=TextMessage)
def handle_message(event):
reply = get_record(event.message.text)
line_bot_api.reply_message(
event.reply_token,
TextSendMessage(text=reply))
#GCPの認証して、スプレッドシートの任意のシートを返す関数。
def auth():
#手順1で用意したjsonファイルを'secret.json'という名前で同一ディレクトリに。
SP_CREDENTIAL_FILE = 'secret.json'
# APIを利用する範囲
SP_SCOPE = [
'https://spreadsheets.google.com/feeds',
'https://www.googleapis.com/auth/drive'
]
SP_SHEET_KEY = '手順1で用意したスプレッドシートのURLのd/より後から/editの前まで'
SP_SHEET = 'シート名'
credentials = ServiceAccountCredentials.from_json_keyfile_name(SP_CREDENTIAL_FILE, SP_SCOPE)
gc = gspread.authorize(credentials)
worksheet = gc.open_by_key(SP_SHEET_KEY).worksheet(SP_SHEET)
return worksheet
#auth関数で手に入れたワークシートをデータフレーム化。入力文字列に対応する返しをランダムで出してくれる関数。
def get_record(key):
worksheet = auth()
df = pd.DataFrame(worksheet.get_all_records())
reply_df = df[["入力", "返し"]].values
reply = []
for row in reply_df:
if row[0] in key:
reply.append(row[1])
return (random.choice(reply))
4:herokuへデプロイ
無料で使えるPaaSサービス、herokuでデプロイして24時間いつでも返してくれるBotに。上記のapp.pyファイルと同一ディレクトリにsecret.json
とあと二つ以下のファイルを作成。
・reqirements.txt
Flask
line-bot-sdk
pandas
gspread
oauth2client
・Procfile(テキストファイル。拡張子つけない。)
web: python app.py
herokuへ登録したのち、ターミナル上でログイン→空アプリ作成→指定してpushという流れ。
#ログイン
$ heroku login #ブラウザが立ち上がりログイン画面へ
#アプリ作成
$ heroku create 作りたいアプリ名
#アプリをgit指定
$ heroku git:remote -a アプリ名
#アドしてコミット
$ git add
$ git commit -m "My first commit"
#push
$ git push heroku main
#環境変数を設定(今回はline_tokenという変数名に)
$ heroku config:set line_token=アクセストークンの値
↓デプロイ完了したら、LineのMessaging API設定のWebhook設定に"アプリurl/callback"というURLを登録しWenhookの利用をオンにすれば準備完了。
↓返事した!最初は結構感動!!
5:ちょっと改造
スプレッドシート読み込みの復習もかねてちょっと改造。同一スプレッドシートに別のシートを作成。
↓366日分、何の記念日化を登録した「what_day」というシート。調べてみると毎日何かしらの記念日なものだ。
def auth2_whatday():
#シート名以外、上記のauth()関数と全く同じ
return worksheet
#本日日付の「月」と「日」で読み込んだワークシートを紹介。今日は何の日かを返す。
def get_whatday():
now = datetime.now() + timedelta(hours=9)
month = now.month
day = now.day
worksheet = auth2_whatday()
df = pd.DataFrame(worksheet.get_all_records())
reply_df = df[["月", "日", "内容"]].values
naiyou = []
for row in reply_df:
if row[0] == month and row[1] == day:
naiyou.append(row[2])
return (f"今日{month}月{day}日は、{naiyou[0]}ですよ~。")
#handler.addを書き換え、「何の日」、「なんの日」という文字列を受け取ったら上の関数を発動。
@handler.add(MessageEvent, message=TextMessage)
def handle_message(event):
if "何の日" in event.message.text or "なんの日" in event.message.text:
reply = get_whatday()
line_bot_api.reply_message(
event.reply_token,
TextSendMessage(text=reply))
else:
reply = get_record(event.message.text)
line_bot_api.reply_message(
event.reply_token,
TextSendMessage(text=reply))
↓日付を計算して今日は何の日か教えてくれる。
他にもおみくじ作ったりいろいろ遊べる。
学んだこと
LINE Messaging APIは、調べた感じreplyは制限なく無料で使える(R3.7月現在)。GCPも無料枠でOK。
herokuはクレカ登録なしでも月に550時間までは無料。身内で使う分には全然足りるはず。ただしsleepしてしまうため、
時間が空くと一度返信までに30秒ほどかかる。とはいえ十分遊べる。無料枠バンザイ!
月額700円程払うとスリープもなくなり常時起動出来るので、ちょっとしたお店のBotとか簡単に作れるな~と。
クラウド上のスプレッドシートを簡単にpythonから操作できるのもかなりいろいろ使えそう。