LoginSignup
2

More than 3 years have passed since last update.

毎朝自動で体温を入力・送信してくれるプログラムを作る【備忘録】

Last updated at Posted at 2020-10-26

はじめに

初投稿です。
今回は、学校で毎日GoogleFormsで体温入力等をしないといけなくなって、めんどくs....
いや、入力する時間がないので、毎日6:00〜8:30の間にランダムで送信してくれて、しかも体温も36.4~36.6の間のどれかを送信してくれるプログラムを作ってみました。

実行環境

本題

作成にあたって、こちらの記事を参考にしながら作りました。
あと、GoogleFormの質問の識別番号の取得は今回は割愛します。

jsonファイルの作成

form_urlには、送信をしたFormのURLを入れ、entryの中には、取得した質問の識別番号を入れていきます。
質問の数に合わせて、ans_7みたいに増やしていってください。
outputの中には、質問に対する答えを書いていきます。ans_1ans_4は毎日値が変わるので適当に値を入れてください。
ここでは、適当にNoneと入れています。

cfg.json

{
    "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チャンネルに送信していきます。
完成したプログラムはこんな感じになっています。

bot.py
# -*- 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に上げているので、使用する際はご自由に....
最後の方、かなり解説を省略したんですが、参考になれば幸いです。

※完全にネタ投稿です。実際に実行させるかさせないかは自己責任でお願いします。それによって先生に怒られたとしても責任は負いません。

参考

Google Form自動回答Botでクソアンケートに勝つ(Python3)

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2