起動直後にtasks.loop()内でメッセージを送信しようとするとエラーが出るときの対処法

[前回の記事](https://qiita.com/_Misty_Scene/items/082423d5db64cb6dbe4f)で、デバッグ用に現在時刻とか送信予定時刻などをprint()していたのですが、思いつきで「syslogにprint()していたものをDiscordに全部送信してしまえ」と思って変えたら、エラーが発生して２日ほど苦戦しておりました。
そのときの対処法を紹介したいと思います。

# 本題
エラーを吐いていたときのコード


```py:bot.py
@tasks.loop(seconds=60)
async def loop():
    global time_set
    global tem_set

    w_list = ["月", "火", "水", "木", "金", "土", "日"]  # 進化したよ！
    now_t, now_dt = datetime.now().strftime('%H:%M'), w_list[datetime.now().weekday()]

    ch = client.get_channel(771155766056452167)
    await ch.send(f"現在の時刻：`{now_t}`／今日の曜日：`{now_dt}`／送信予定時刻：`{time_set}`／送信予定体温：`{tem_set}`")

    if now_dt != "日":  # 日曜日以外だったら送信するようにした
        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())
```
このコードを実際に動作させると、以下のようなエラーが出るんです。
最初は、IDのコピペミスかなと思っていたのですが、再度コピペしてもエラーを吐いたので何か別の要因があるのでは？と調べてみたら、[ありましたよ](https://qiita.com/coolwind0202/items/a4405be45734bd7f6cd5#attributeerror-%E5%9E%8B%E5%90%8D-object-has-no-attribute-%E5%B1%9E%E6%80%A7%E5%90%8D)！

> client.get_channel()などの関数は、BOTの準備が完了するまでNoneを返します。
例えば、プログラムの冒頭でいきなりget_channel()をしていませんか？
これを避けるには、readyイベントが発生した「後」に取得を行う必要があります。

「えっ、あ、そういえば...」となりました(泣)
俺の２日はどこいった。

```:エラー
AttributeError: 'NoType' object has no attribute 'send'
```

# 対処法
対処法は意外と簡単でした、はい。
先程の記事の`get_channel()`をする前に、`wait_until_ready()`[(リファレンス)](https://discordpy.readthedocs.io/ja/latest/api.html?highlight=wait_until_ready#discord.Client.wait_until_ready)を入れればいいだけです。

```python:bot.py
@tasks.loop(seconds=60)
async def loop():
    global time_set
    global tem_set

    w_list = ["月", "火", "水", "木", "金", "土", "日"]  # 進化したよ！
    now_t, now_dt = datetime.now().strftime('%H:%M'), w_list[datetime.now().weekday()]

    await client.wait_until_ready()
    ch = client.get_channel(771155766056452167)
    await ch.send(f"現在の時刻：`{now_t}`／今日の曜日：`{now_dt}`／送信予定時刻：`{time_set}`／送信予定体温：`{tem_set}`")

    if now_dt != "日":  # 日曜日以外だったら送信するようにした
        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())
```
あら、一発で解決()

# まとめ
- `tasks.loop`内で`get_channel()`などの関数を際にエラーが出るときは、`wait_until_ready()`を入れれば治る。

すっごいざっくりしたまとめでごめんなさい...
同じような状況に陥っている人の助けになれば、幸いです。

# 参考
- [Discord.py botが動かない場合に確かめる事](https://qiita.com/coolwind0202/items/a4405be45734bd7f6cd5)
- [await wait_until_ready()](https://discordpy.readthedocs.io/ja/latest/api.html?highlight=wait_until_ready#discord.Client.wait_until_ready)