初心者がGAE無料枠でDiscord BOTを安定動作させるまでのキセキ

# １．毎週投稿している希望調査を自動化したい
FF14の青魔LSのDiscordで、今週はみんながどのコンテンツに行きたいか？を下みたいな投稿とリアクションでふんわり調査していたのですが、
![スクリーンショット 2024-01-19 183111.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3679605/a5f87b91-c884-12de-2d56-71f643eafa60.png)
+ そもそも投稿するのを忘れる
+ 日付が変わるくらいで、あとは毎回同じコピペ
+ リアクションをポチポチするのも地味にめんどくさい
+ 自分の希望をポチできない
+ 投稿を忘れる

ので、自動化したかったのです。
Discord WebHookでGAS（Google App Script）から投稿するのが簡単そう！
と思ったけど、できるのは投稿だけで、リアクションはBOTでなければ難しいらしい。

【むむむ。】

とりあえず簡単に実装できる定期投稿はWebHook+GASで実装できたものの、ポチポチもなんとかしたかったので、仕方なく何かでBOTを作ることに。

# ２．どうやったらDiscord BOTを作れるのかな？
という思いでQiitaを検索して、最初に参考にさせていただいたのが次の記事です。
+ [Discord BotをGAEで無料でホストするためのTipsをいくつか](https://qiita.com/dairappa/items/f516e4eb50c4d8c36167)
+ [Herokuが有料化するのでdiscord botをGAEに移した](https://qiita.com/dairappa/items/f516e4eb50c4d8c36167)

以上の記事から、
+ GAE（Google App Engine）を強く推されている気がしたので、GAEにしようー。
+ QiitaでDiscord BOTの例は、Node.jsかpythonが多そう！ JavaScriptもpythonも全く知らない[^1]けど、LLM遊びのために環境があったpythonにしようかな。
+ pythonならdiscord.pyなのかな。
+ GAEはウェブページがいるので、pythonだったらFlaskでいいのかな？
+ warmupは、googleのサンプルコードを使わせてもらおう。
+ GASの定期投稿に反応してリアクションするBOTにしよう。
+ cronは様子見。（warmup だけでもいいんじゃね？みたいな）

[^1]:pythonをどれくらい知らなかったかというと、インデントが括弧の代わりになってる、ということすら知らなかった。可読性だけのものと思ってたのでびっくりしました。

で、実装直後の喜びの私がこちら↓

![スクリーンショット 2024-01-19 193242.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3679605/0d42174c-2ab6-ec5e-ece1-04241c3dc5b7.png)

# ３．BOTは動いたけど、なんか調子が悪かった
GAEでBOTは動いてて、翌週も投稿に対してリアクションはしてくれてたのだけど、
+ たまにリアクションが2重になってる
+ たまにリアクションしてくれない、途中で消えてる
+ warmupが毎回エラーになってる（py_testだから？？）
+ BOTと同時に起動しているはずのFlaskのウェブページにアクセスできない（応答がない）

GAEのインスタンスの稼働状況を見てみると、しょっちゅう消えてはwarmupで戻って、また消えて・・・を繰り返してる？
![スクリーンショット 2024-01-19 193658.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3679605/724f3485-273d-6ad2-fb70-e4bf1e9d0c53.png)

やってなかったけど、cronでルートを叩けばいいのかな？
と思って10分ごとに設定してみると、毎回エラーになっていることに気づく。

やっぱりウェブページが出ないのがダメだよねー
と真面目にコードを見直すことに。

Windows Copilotなどに質問すると、BOTを動かすのにThreadを使うような例を提示してくれて。
いやいや、Copilotさんご冗談をー。Qiitaでそんな例見たことないけどー？
なーんて思いながら、Qiitaを眺めていた時に見つけたのが次の記事
+ [[記事]Discord Pythonボットを２４時間起動します。](https://qiita.com/Mamiyanonoka/items/69c967cd3af9bb057a88)

なるほど、BOTが動きっぱなし[^2]だと、ウェブページのFlaskが止まっちゃうからFlaskを別のスレッドにするのかー！うちでもやってみようー！
[^2]:discordbot.pyの一番最後にbot.runしてて、Flaskのapp.runまでたぶんたどり着いてなかった

⇒　なんかだめ。

これでも良さそうなのになーなんでかなー？って思いながら、Qiitaを見ていると見つけたのが次の記事

+ [Google App Engine (GAE)でウェブサイトを公開してみた](https://qiita.com/kaiyo_yume/items/3b5669cb34af1d173a2b)

えええ？（衝撃）
GAEでは、Flaskのapp.runはいらない・・・？
じゃあBOTはどうしたら・・・

ハッ！
BOTの方をThreadで動かすのか！（今更）

という試行錯誤の結果できたmain.pyというキメラをここに晒しておきます。
正直恥ずかしい・・・。

<details><summary>main.py</summary>

```python:main.py

import threading
import os
from flask import Flask
from discordbot import bot



#app = Flask(__name__)
app = Flask(' ')

#token = ""

@app.route("/")
def main():
    return "<html>Hello</html>"

@app.route("/_ah/warmup")
def warmup():
    return "", 200, {}


"""
def run():
    #app.run(host="127.0.0.1", port=8080, debug=True)
    #app.run(host="127.0.0.1", port=8080)
    app.run()
"""

def keep_alive():
    server = threading.Thread(target=run_bot)
    #server = threading.Thread()
    server.start()

def run_bot():
    bot.run(os.getenv('ENV_VAR_SECRET'))

keep_alive()
#bot.run(os.getenv('ENV_VAR_SECRET'))

```
</details>

1/17の夕方から、この恥ずかしいコードにしてるのですが、ウェブページも表示されて、インスタンスも1つ消えずに残る形で安定しているように思ってます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3679605/92c13c7f-e6c5-37cd-5ecd-28cec549db51.png)

botのコードやapp.yaml、requirements.txt は、どうとでもなるし、皆さんが作りたいように作るだろうから、書きません！（恥ずかしいから）

# ４．無料がいいんだけど、デプロイごとに5円くらいお金かかるのは、なんでなんー？
時間は前後しますが、毎回デプロイする度に、ちょびっとずつお金が発生してて。
なんでかなー？？って思ったら
+ [ちょっと待って！そのGCP、本当に無料枠？](https://qiita.com/99no_exit/items/b36f74170df4dbdaa9ba)

そうかーasiaはだめだったのかー
というわけで、us-west1とかにしたような気がします。

# ５．最後に
恥ずかしながらコードを晒したのは、
+ GAEでDiscord BOTが動作している例が少ないような気がしたこと
+ 私が恥ずかしキメラコードにたどり着くまでに結構苦労したこと
+ Qiitaの記事にたくさん助けられたこと
+ [FF14のBOTを動かしていたけどherokuが有料になるからやめます](https://qiita.com/6futjs9g9xi2r/items/68fc7ea242ed064c5a72)というような記事も見つけてしまって、FF14 Disocrd BOT、もっとやってこうゼ！って思ったこと

あたりからです。
~~Gitとかのコード管理を使ってないので綺麗にするのもめんどくさかった~~

GAEでDiscord BOTを動かすときの参考になれば、うれしいです！