はじめに
初投稿です。
今回は、学校で毎日GoogleFormsで体温入力等をしないといけなくなって、めんどくs....
いや、入力する時間がないので、毎日6:00〜8:30の間にランダムで送信してくれて、しかも体温も36.4~36.6の間のどれかを送信してくれるプログラムを作ってみました。
実行環境
- Python3系
- discord.py
- requests
- テスト用のForms
本題
作成にあたって、こちらの記事を参考にしながら作りました。
あと、GoogleFormの質問の識別番号の取得は今回は割愛します。
jsonファイルの作成
form_url
には、送信をしたFormのURLを入れ、entry
の中には、取得した質問の識別番号を入れていきます。
質問の数に合わせて、ans_7
みたいに増やしていってください。
output
の中には、質問に対する答えを書いていきます。ans_1
とans_4
は毎日値が変わるので適当に値を入れてください。
ここでは、適当にNone
と入れています。
{
"form_url": "https://docs.google.com/forms/d/e/1FAIpQLSc93lIQ3Aob93cwjx6HSRbuC8V7NT59UfUPhlw6AlkGtZ6CXQ/",
"entry": {
"ans_1": 964244932,
"ans_2": 888214820,
"ans_3": 23055831,
"ans_4": 10832147,
"ans_5": 1720496078,
"ans_6": 2017707777
},
"output":{
"ans_1": "None",
"ans_2": "2A",
"ans_3": "8",
"ans_4": "None",
"ans_5": "元気です",
"ans_6": "いない"
}
}
jsonファイルの作成はこんな感じです。
メインプログラムの作成
今回は、Discordと連携して、ちゃんと送信されたかなどのログを特定のDiscordチャンネルに送信していきます。
完成したプログラムはこんな感じになっています。
# -*- coding: utf-8 -*-
import discord
from discord import Embed
from discord.ext import tasks
from datetime import datetime
import os
import requests
import random
import json
TOKEN = os.environ["TOKEN"]
client = discord.Client(intents=discord.Intents.all())
# 次回送信予定時刻を06:00-8:30までの間でランダムに設定
def setting_time_set():
setting_time_h = random.randint(6, 8)
if setting_time_h == 8:
setting_time_m = random.randint(0, 30)
else:
setting_time_m = random.randint(0, 59)
setting_time = f"{setting_time_h:02}:{setting_time_m:02}"
return setting_time
def set_tem():
choice_list = ["36.4", "36.5", "36.6"]
choice_ans = random.choice(choice_list) # 36.4-36.6までの間でランダムに選択
return choice_ans
time_set = setting_time_set() # 起動時に初回の次回送信時刻を設定
tem_set = set_tem()
# Embedの関数
async def template_embed(message, title, name_1, name_2, value_1, color, description=None):
ch = client.get_channel(message)
embed_time = datetime.now().strftime("%Y年%m月%d日-%H:%M")
embed = Embed(title=title, description=description, color=color)
embed.add_field(name=name_1, value=f"{value_1}", inline=True)
embed.add_field(name=name_2, value=f"{tem_set}", inline=True)
embed.set_footer(text=f"{embed_time}")
await ch.send("<@ユーザーID>")
await ch.send(embed=embed)
@client.event
async def on_ready():
await template_embed(message=768274673984208926, title="起動ログ", name_1="次回の送信予定時刻", value_1=time_set,
name_2="送信予定の体温", color=discord.Color.orange())
@client.event
async def on_message(message):
if message.content == "/reset":
await reset(message)
if message.content == "/now":
await now(message)
async def reset(message):
global time_set
global tem_set
time_set = setting_time_set()
tem_set = set_tem()
await template_embed(message=768274673984208926, title="リセットされました", name_1="次回の送信予定時刻", name_2="送信予定の体温",
value_1=time_set, color=discord.Color.purple())
await template_embed(message=message.channel.id, title="リセットされました", name_1="次回の送信予定時刻", name_2="送信予定の体温",
value_1=time_set, color=discord.Color.purple())
async def now(message):
await template_embed(message=message.channel.id, title="現在の状況", name_1="次回の送信予定時刻", name_2="送信予定の体温",
value_1=time_set, color=discord.Color.greyple())
@tasks.loop(seconds=60)
async def loop():
global time_set
global tem_set
now_t = datetime.now().strftime('%H:%M')
print(f"現在の時刻:{now_t}/送信予定時刻:{time_set}/送信予定体温:{tem_set}")
if now_t == time_set: # 送信予定時刻になった?
dt_now = datetime.now().strftime("%Y-%m-%d") # 現在時刻を2020-01-01の形で取得、dt_nowに格納
file_name = "cfg.json"
with open(file_name, "r", encoding="utf-8")as f:
cfg = json.load(f)
cfg["output"]["ans_1"] = f"{dt_now}"
cfg["output"]["ans_4"] = f"{tem_set}"
params = {"entry.{}".format(cfg["entry"][k]): cfg["output"][k] for k in cfg["entry"].keys()}
res = requests.get(cfg["form_url"] + "formResponse", params=params)
if res.status_code == 200:
await template_embed(message=768274673984208926, title="ログ情報", description=f"[URL]({res.url})",
name_1="完了状態", name_2="送信された体温", value_1="成功しました", color=discord.Color.green())
else:
res.raise_for_status()
await template_embed(message=768274673984208926, title="ログ情報", name_1="完了状態", name_2="送信予定だった体温",
value_1="エラーが発生しました。", color=discord.Color.red())
else:
if now_t == "21:00":
time_set = setting_time_set()
tem_set = set_tem()
await template_embed(message=768274673984208926, title="送信時刻更新のお知らせ", name_1="次回の送信予定時刻", name_2="送信予定の体温",
value_1=time_set, color=discord.Color.blue())
loop.start()
client.run(TOKEN)
順を追って説明していきます。
まずは、この部分ですが、送信時間を6:00~8:30の間でランダムに発行してsetting_time
にreturnし、その後体温をランダムに選んでchoice_ans
にreturnしています。
その下の処理は、初回起動時に送信時刻と体温を設定しています。更にその下の処理は、Embedの生成処理を行っています。
# 次回送信予定時刻を06:00-8:30までの間でランダムに設定
def setting_time_set():
setting_time_h = random.randint(6, 8)
if setting_time_h == 8:
setting_time_m = random.randint(0, 30)
else:
setting_time_m = random.randint(0, 59)
setting_time = f"{setting_time_h:02}:{setting_time_m:02}"
return setting_time
def set_tem():
choice_list = ["36.4", "36.5", "36.6"]
choice_ans = random.choice(choice_list) # 36.4-36.6までの間でランダムに選択
return choice_ans
time_set = setting_time_set() # 起動時に初回の次回送信時刻を設定
tem_set = set_tem()
# Embedの関数
async def template_embed(message, title, name_1, name_2, value_1, color, description=None):
ch = client.get_channel(message)
embed_time = datetime.now().strftime("%Y年%m月%d日-%H:%M")
embed = Embed(title=title, description=description, color=color)
embed.add_field(name=name_1, value=f"{value_1}", inline=True)
embed.add_field(name=name_2, value=f"{tem_set}", inline=True)
embed.set_footer(text=f"{embed_time}")
await ch.send("<@ユーザーID>")
await ch.send(embed=embed)
次に
メイン処理の方を解説していきます。
@client.event
async def on_ready():
await template_embed(message=768274673984208926, title="起動ログ", name_1="次回の送信予定時刻", value_1=time_set,
name_2="送信予定の体温", color=discord.Color.orange())
起動時に、特定のチャンネルに起動ログを送信していきます。
@client.event
async def on_message(message):
if message.content == "/reset":
await reset(message)
if message.content == "/now":
await now(message)
async def reset(message):
global time_set
global tem_set
time_set = setting_time_set()
tem_set = set_tem()
await template_embed(message=768274673984208926, title="リセットされました", name_1="次回の送信予定時刻", name_2="送信予定の体温",
value_1=time_set, color=discord.Color.purple())
await template_embed(message=message.channel.id, title="リセットされました", name_1="次回の送信予定時刻", name_2="送信予定の体温",
value_1=time_set, color=discord.Color.purple())
async def now(message):
await template_embed(message=message.channel.id, title="現在の状況", name_1="次回の送信予定時刻", name_2="送信予定の体温",
value_1=time_set, color=discord.Color.greyple())
ここでは、送信時間と体温をリセットできるリセットコマンドと、現在の状態を確認できるコマンドの処理です。
@tasks.loop(seconds=60)
async def loop():
global time_set
global tem_set
now_t = datetime.now().strftime('%H:%M') # 現在時刻を取得
print(f"現在の時刻:{now_t}/送信予定時刻:{time_set}/送信予定体温:{tem_set}")
if now_t == time_set: # 送信予定時刻になった?
dt_now = datetime.now().strftime("%Y-%m-%d") # 現在時刻を2020-01-01の形で取得、dt_nowに格納
file_name = "cfg.json"
with open(file_name, "r", encoding="utf-8")as f:
cfg = json.load(f)
cfg["output"]["ans_1"] = f"{dt_now}" # 今日の年、月、日をans_1に上書き
cfg["output"]["ans_4"] = f"{tem_set}" # 体温をans_4に上書き
params = {"entry.{}".format(cfg["entry"][k]): cfg["output"][k] for k in cfg["entry"].keys()}
res = requests.get(cfg["form_url"] + "formResponse", params=params)
if res.status_code == 200: # 正常に送信された場合
await template_embed(message=768274673984208926, title="ログ情報", description=f"[URL]({res.url})",
name_1="完了状態", name_2="送信された体温", value_1="成功しました", color=discord.Color.green())
else: # 送信できなかった場合
res.raise_for_status()
await template_embed(message=768274673984208926, title="ログ情報", name_1="完了状態", name_2="送信予定だった体温",
value_1="エラーが発生しました。", color=discord.Color.red())
else:
if now_t == "21:00":
time_set = setting_time_set()
tem_set = set_tem()
await template_embed(message=768274673984208926, title="送信時刻更新のお知らせ", name_1="次回の送信予定時刻", name_2="送信予定の体温",
value_1=time_set, color=discord.Color.blue())
ここでは、tasks.loop()
を使用して60秒間隔に現在時刻と送信予定時刻の確認を行い、一致したら送信処理を行っています。
そして、一致しなかった場合は、現在時刻とリセット時刻が一致しているかを確認し、リセット時刻であればリセット処理をしています。
最後に
初投稿というのもあり、かなりグダグダですが、ご了承ください。
完成したコードは、Githubに上げているので、使用する際はご自由に....
最後の方、かなり解説を省略したんですが、参考になれば幸いです。
※完全にネタ投稿です。実際に実行させるかさせないかは自己責任でお願いします。それによって先生に怒られたとしても責任は負いません。