今回はLINEbotを使って勤怠管理をしていきます!
具体的には、LINEで「出勤」「退勤」と入力すると、指定のGoogleスプレッドシートに自動でその時の時刻が書き込まれるようにします。
今回は主要なところだけ説明していくので、詳しく知りたい方は適宜自分でお調べください。
#はじめに
##必要なファイルの作成など
こちらは解説すると大変長くなってしまうので下記のYoutubeの動画に沿って行ってください
(最初の15分くらいで大丈夫です)難しいことは何もないので手順をまねていればOK👌
https://youtu.be/MHf6dideSqg
ここからはコードの解説などを行っていきます
#サンプルコード
import pandas as pd
from datetime import datetime, timedelta, timezone
import gspread
from oauth2client.service_account import ServiceAccountCredentials
import os
# タイムゾーンの生成
JST = timezone(timedelta(hours=+9), 'JST')
def auth():
SP_CREDENTIAL_FILE = 'secret.json'
SP_SCOPE = [
'https://spreadsheets.google.com/feeds',
'https://www.googleapis.com/auth/drive'
]
SP_SHEET_KEY = 'SP_SHEET_KEY'
SP_SHEET = '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
# 出勤
def punch_in():
worksheet = auth()
df = pd.DataFrame(worksheet.get_all_records())
timestamp = datetime.now(JST)
date = timestamp.strftime('%Y/%m/%d')
punch_in = timestamp.strftime('%H:%M')
df = df.append({'日付': date, '出勤時間': punch_in, '退勤時間': '00:00'}, ignore_index=True)
worksheet.update([df.columns.values.tolist()] + df.values.tolist())
# 退勤
def punch_out():
worksheet = auth()
df = pd.DataFrame(worksheet.get_all_records())
timestamp = datetime.now(JST)
punch_out = timestamp.strftime('%H:%M')
df.iloc[-1, 2] = punch_out
worksheet.update([df.columns.values.tolist()] + df.values.tolist())
from flask import Flask, request, abort
from linebot import (
LineBotApi, WebhookHandler
)
from linebot.exceptions import (
InvalidSignatureError
)
from linebot.models import (
MessageEvent, TextMessage, TextSendMessage,
)
app = Flask(__name__)
line_bot_api = LineBotApi(os.getenv('YOUR_CHANNEL_ACCESS_TOKEN'))
handler = WebhookHandler(os.getenv('YOUR_CHANNEL_SECRET'))
@app.route("/")
def hello_world():
return "hello_world"
@app.route("/callback", methods=["GET", "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):
if event.message.text == '出勤':
punch_in()
line_bot_api.reply_message(
event.reply_token,
TextSendMessage(text="出勤登録完了しました!今日もがんばりましょう!"))
elif event.message.text == '退勤':
punch_out()
line_bot_api.reply_message(
event.reply_token,
TextSendMessage(text="退勤登録完了しました!お疲れ様でした"))
else:
line_bot_api.reply_message(
event.reply_token,
TextSendMessage(text="こちらは出退勤を管理するBotです。"))
if __name__ == "__main__":
port = os.getenv("PORT")
app.run(host="0.0.0.0", port=port)
#ライブラリ
分かりやすいよう二つに分けて書きましたが、上はGoogleスプレッドシートを操作するもの。下はLINEbotで必要なものです。気になるものがあれば適宜調べてください。
import pandas as pd
from datetime import datetime, timedelta, timezone
import gspread
from oauth2client.service_account import ServiceAccountCredentials
import os
from flask import Flask, request, abort
from linebot import (
LineBotApi, WebhookHandler
)
from linebot.exceptions import (
InvalidSignatureError
)
from linebot.models import (
MessageEvent, TextMessage, TextSendMessage,
)
#googleスプレッドシートへの入力
ここからは、このauth関数を完成させている前提で進めます。まだの方はこちらを見て完成させてください。(最初の15分程度)
def auth():
SP_CREDENTIAL_FILE = 'secret.json'
SP_SCOPE = [
'https://spreadsheets.google.com/feeds',
'https://www.googleapis.com/auth/drive'
]
SP_SHEET_KEY = 'SP_SHEET_KEY'
SP_SHEET = '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
##出勤時間の入力
まず、タイムゾーンを作成しておきます。
# タイムゾーンの生成
JST = timezone(timedelta(hours=+9), 'JST')
こちらが出勤時間を入力するものです。流れとしては、指定したシートをworksheetとし、現在の時間を取得。そしてworksheetをアップデートという形です。
今回は日付と出勤時間を入力、退勤時間は00:00にしておきました。
# 出勤
def punch_in():
worksheet = auth()
df = pd.DataFrame(worksheet.get_all_records())
timestamp = datetime.now(JST)
date = timestamp.strftime('%Y/%m/%d')
punch_in = timestamp.strftime('%H:%M')
df = df.append({'日付': date, '出勤時間': punch_in, '退勤時間': '00:00'}, ignore_index=True)
worksheet.update([df.columns.values.tolist()] + df.values.tolist())
##退勤時間の入力
流れは出勤と全く同じです。
#退勤
def punch_out():
worksheet = auth()
df = pd.DataFrame(worksheet.get_all_records())
timestamp = datetime.now(JST)
punch_out = timestamp.strftime('%H:%M')
df.iloc[-1, 2] = punch_out
worksheet.update([df.columns.values.tolist()] + df.values.tolist())
しかし、退勤の場合は一箇所変更を加えればいいだけなので、
df.iloc[-1, 2] = punch_out
としています。これは-1行(すなはち、最終行)の2列目に値を入れるという意味です。
ここまででGoogleスプレッドシートへの入力は終わりです。
#LINEbotの作成
ここからはLINEbotの作成に入ります。
こちらの動画の35〜40分の部分を見ていただいてLINE Messaging APIの登録をしてください。
#応答メッセージ設定
こちらで返答するメッセージを指定します。event.message.text
で送られてきたメッセージを取得し、if文で条件分岐。
@handler.add(MessageEvent, message=TextMessage)
def handle_message(event):
if event.message.text == '出勤':
punch_in() #出勤の関数
line_bot_api.reply_message(
event.reply_token,
TextSendMessage(text="出勤登録完了しました!今日もがんばりましょう!"))
elif event.message.text == '退勤':
punch_out() #退勤の関数
line_bot_api.reply_message(
event.reply_token,
TextSendMessage(text="退勤登録完了しました!お疲れ様でした"))
else: #その他のメッセージが送られてきたとき
line_bot_api.reply_message(
event.reply_token,
TextSendMessage(text="こちらは出退勤を管理するBotです。"))
#herokuへのデプロイに必要なファイル
次の3つのファイルを作成してください。なお、この3つのファイルの名前はこの通りにしてください。
web: python line-bot1.py
Flask
line-bot-sdk
pandas
gspread
oauth2client
python-3.9.4
herokuにデプロイするファイルはこの3つと先程のコードを書いたもの、加えて最初のYoutubeのほうで作成したjsonファイルの合計5つです。
#エラーの修正
サンプルコードはすでに修正したものですが、最初に紹介した動画の通りに進めるとエラーがでましたので報告しておきます。読み飛ばしていただいてもかまいません。
##Webhook URLの設定
LINEのbot作成中にWebhook URL(https://アプリケーション名.herokuapp.com/callback)を認証させますがその時に一つエラーが起きました。
@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'
修正したものがこちら
@app.route("/callback", methods=["GET", "POST"]) #GETを追加
#まとめ
今回はLINEbotを使って出退勤の管理をできるようにしました。LINEbotを初めて作成したのですが、公式LINEみたいでなんだかワクワクします笑
細かい設定などはこちらの動画を参考にしてください。初心者向けにとても分かりやすく解説されているのでおすすめです!
それでは今回はこれで終わります。ありがとうございました!