完全無料なローカル環境(Mac)でDiscordのBotを起動させたいので、頑張った話

どうもこんにちは、Elbas810こと鳩サブレです。
いつもライブ旅行記やらそんな話がほとんどでしたが、今回はちょっとプログラム系のお話です。こういうのはQiitaとかに書くべきなんだよな。

私、実は身内向けサーバー等々に自作のDiscord Botを導入し、管理しています。

こういう感じのやつ

元々はHerokuでのんびり運用していたのですが、Herokuの無料プラン廃止やら他のホスティングサービスの仕様変更により、使いたい時にBOTが起動していないことがチラホラ発生するように。
そこで、この際思い切ってローカル環境で運用しちゃえばいいんじゃないかと気が付き、ローカルでいい感じにBotを起動できるように改善してみました。ローカルなら、鯖落ちしてもほぼ自分の環境が原因だと分かりますしね。大事なものは肌見放さず持ちたいタイプなのです。

ということで、ローカル環境でDiscord botを常時動かせないかあれこれ奮闘してみました。



1.ローカル環境 & Botの仕様

  • Macbook Air Apple M1 2020

  • メモリ 8GB

  • OS Sonoma 14.0

プログラムはdiscord.pyを活用して作成しています。特定のスラッシュコマンドを入力すると、ランダムに文章を表示する簡単なプログラムです。
実行環境はPyenvで仮想環境を作成し、Python 3.9.12下で動かしています。

2.ローカルで手動起動出来るか確認

VSCodeのPython用拡張機能で実行できるか確認。元々Herokuで動いていたので大丈夫でしょう。

動いた〜

3.「Cron」で常時起動できるか挑戦

3−1.Cronってなんじゃ

上記の場合は、PCを起動する度に毎回操作しなくてはいけないので大変。できる限り管理を楽にするために、自動的に実行されるようにします。
どうやらMacにはスクリプトを一定の時間間隔で実行してくれる「Cron」というものが用意されているようです。正式にはMac特有の機能ではなく、Linux全般に用意されているっぽい。

ということで、Cronの設定ファイルを以下のように変更してみます。メール通知機能はいらなかったので、空欄に設定。

MAILTO=""
* * * * * /Users/hato/.pyenv/shims/python3 /Users/hato/app/jinrou/main.py

3-2.結果

これじゃあ、プログラムの重ねがけじゃないか。
PCが、非常に、重たい!!!!!!!!!!!!!!!!
…はい。何の考えもなしに作った結果、「1分おきに新しいプログラムタスクが増える自己増殖ウイルス型ジョブ」を爆誕させてしまいました。
言われてみれば、botのプログラムは一度起動するとそのままコマンド待機状態になるので、プロセスが終了することはないのです。
つまり、

  • botが起動していない場合、プログラムを起動する

  • botが起動している場合、何もしない

となるプログラムを作成する必要があるわけですね。
なお、バグだと思われたのかDiscord 公式からも注意システムメッセージがDMで送られてきました。気をつけましょう。

訳:短時間に1000回以上もレスポンス送るなんて異常だから、トークンリセットしたよ

3.監視プログラムの作成

pythonが肌に合うので、監視プログラムもpythonで作成しました。

import subprocess
import datetime

t = datetime.datetime.now()
proc2 = subprocess.run("ps aux | grep 'jinrou'",capture_output=True, text=True,shell=True)#実行中のタスク
print("出力結果")
print(proc2.stdout)
logtxt2 = ""
if('/jinrou/main.py' in proc2.stdout):#プロセスが一覧にあるか確認
 print("起動中だよ")
else:
 print("起動してないよ")
 logtxt2 = ("失敗しているよ!起動しなおしたよ!")
 command = ["python" ,"/Users/hato/app/jinrou/main.py"]
 proc = subprocess.Popen(command)  #botの起動
 print("起動完了だよ")
 logtxt = t.strftime("%Y/%m/%d %H:%M:%S") + " " 
 with open("/Users/hato/app/appcheckerlog.log", "a", encoding="utf-8") as f:
     f.write(logtxt+" | "+ logtxt2+"\n")#失敗時ログ出力

subprocessで実行中のタスクリストを取得し、パイプラインで絞り込み。
実行中のタスクにbotのメインプログラムがなければ、起動していないとみなし、実行したのちにログ出力します。本当は成功時もログを出したほうがいいんでしょうけど、1分おきにログを出力するとえぐいことになるので、一旦やめておきました。

4.監視プログラムを常時起動させる

CronにBotプログラム本体ではなく、監視プログラムを自動実行してもらうように設定して…

MAILTO=""
* * * * * /Users/hato/.pyenv/shims/python3 /Users/hato/app/appchecker.py

あとは数分待てば、動いてくれるはず。敢えてbotをオフ状態にして、ログが出るか確認。

出ている〜やった〜


生きてる〜やった〜

これでPC起動中は勝手にBotが常時起動してくれるようになりました。便利〜

★おわりに

デプロイとか気にすることなくアプリを管理できるようになり、個人的にはめちゃくちゃ楽になりました。PCそのものをシャットダウンしてしまえばbot本体も落ちてしまうので電源管理は気をつけなければいけませんが、基本PCを付けている時間のほうが長いので、大丈夫そうです。

まだまだ改善点はあるので、修正していきたいです。
DiscordのBot運用で悩む同志の助けになれば幸いです。

いいなと思ったら応援しよう!