- 日時を指定してメッセージを登録
- リマインドしてくれる
DBは使わない(用意が面倒臭いから)- そうおもっていたが、sqlite3を使うことにする(何も用意せず使えるし)
- ユーザをキーに検索したり、日付を元に検索したりしたいため。dictではちょっと辛そう
- 環境変数
IS_HEROKU
がTrueなら、Discordのチャンネルにファイルを添付して、そこにギルドのリマインダー情報を貼り付ける- 最後に実行されたギルドの所定のチャンネルに保管(チャンネルがなかったら勝手に作る
できれば人間が読める形式にしたいかも- sqlite3のdbにする。よく考えなくても、人間がよめちゃダメでしょう(DLしてsqlite3で読めばわかるけど)
- せっかくなのでAESとやらで暗号化しよう
- 1分くらいの遅延は許してもらう
- メンションはできるようにする
- メンションがあったらそれを使う
- チャンネル指定も可能(未指定は実行したチャンネル)
- チャンネルメンションを使う
$remind 2021/02/11 14:00 野菜を買ってくる
- こんな感じで登録できるようにする
- 1分に1回、自分の保持しているremindオブジェクトをさらって通知する(Taskを使う)
- ステータス(未実施、実施済)
- ギルドはどこか?
- 誰が実行したか?
- コマンド
ls
のときに他ギルド・他人の情報を表示しない
- コマンド
- 処理長引かせないために、remindは時間で昇順ソートしておくべき
- remind.remind_datetime > nowになったらそこで処理を終了
- そう思ってたけど、sqlite3ならいいか。。。
- 通知したら以下の処理を実行
- ステータスを実施済に変更
repeat
を確認。'1'の場合、repeat_interval
を確認し、次のremindを作成- python-dateutil(とソレに入ってるrrule)を使う
repeat_interval
に登録できるもの- XX分:
XXmi
- XX時間:
XXh
- X日:
Xd
- X週:
Xw
- Xヶ月:
Xm
- X年:
Xy
- 特殊
- 平日:
平日
- 休日:
休日
- 月初:
月初
- 月末:
月末
- 2文字の時のみ発動
- 曜日:
月水金
等- それぞれをrruleの
byweekday
リストに詰めて、startが翌日、endが1週間後で最初のやつを使う
- それぞれをrruleの
- 平日:
- XX分:
- create table
create table if not exists reminder_table (
id integer primary key autoincrement,
remind_datetime datetime,
guild integer,
member integer,
channel integer,
remind_message text,
status text,
mention text,
repeat_flg text,
repeat_interval text,
created_at datetime,
updated_at datetime
)
- カラムの説明(わかりにくいところのみ)
- status
- Finished: リマインド済
- Past: 過去日のため実行しないもの(insertする時に入れる)
- Progress: リマインド未済
- Canceled: キャンセルされたもの
- mention
- これをそのまま使えばメンションできる形式で保管
- repeat_flg
- 0: 繰り返さない
- 1: 繰り返す
- repeat_interval
- 上で説明したいろいろ
- status
- タイムゾーン(HerokuやRepl.itなどの海外サーバで動かした時に問題ないか?)
- なんとなく付けたらRepl.itでもローカルで動いた
- ただ、たまに処理がおかしい???時もあるような。。。
- sqlite3について
- sqlite3入門 | Python学習講座
- sqlite3 --- SQLite データベースに対する DB-API 2.0 インタフェース — Python 3.9.2 ドキュメント
- SQLiteで日付時刻を扱う際のポイント - Qiita
- 日付と時刻を取得する(date関数, time関数, datetime関数, julianday関数, strftime関数) | SQLite入門
- Python:sqlite3【SQLite データベース】 - リファレンス メモ
- SQLiteのsqlite_sequence (AUTOINCREMENT) の挙動 - キリウ君が読まないノート
- PythonでSQLite3を扱ってみる(備忘録) - Qiita
- 30分ごとに番組を作るのは面倒臭い
- プレミアム会員ではないと、延長はできない(それぞれで枠を取得する必要がある)
- 地味で面白くない放送に人はこない(動画のサムネイルってどうなっていんだろう?)
- プレミアム会員ではなくとも、本人はタイムシフト動画を閲覧できる
- ちょっとびっくり。ダウンロードはプレミアム会員のみ
- OBSでは配信と同時に録画ができるので、それでやっておけというスタンスか
- あまりに面倒臭かったのでYouTubeにした(3/14)
discord.pyとdiscord-py-slash-commandを利用して、DIscord用のリマインダーBotを一から作ってみます!!!!
プログラミング放送です。前回までニコ生でやってましたが30分ごとに枠を取り直すのが煩雑でYouTubeに来ました。DiscordのBotにあったらおもしろいアイデアは随時募集中、Botを作ってみたい方の質問等あれば答えます(答えられるなら)
今回やりたいこと:・slashコマンドの実装、タスクで定期的に実行してみる
URL1: https://hackmd.io/637kGsB3R0y2VgL7Nu5DrA?view URL2: https://scrapbox.io/maaaruuu/discord-reminderbotの設計
- settings.pyを作り、ログレベルとトークンを取得するようにした
- 公式チュートリアルのやつから、Cogを使う方法に変える方法が分からず困る
- 音声が途切れ途切れだった(OBSのノイズゲートのせい)
- Qiitaの記事をコピペし、Cog対応版を動かそうとするが動かない
- Qiitaの記事をそのままコピペすると動いた
- 結局、 動かす時のclassを変更しないままだったため
- 音声が途切れ途切れ、かつ、棒読みちゃんが謎に残響してた(OBSのノイズゲートのせい)。次回で直した
- Cogの作成に着手
- ついでに、なんとなくremind.pyを作り始めた
- sqlite3を使うことにした。DBの初期化(テーブル作成)したところ
- リマインドを作成する処理を作ろうとしたところで時間切れ
- リマインドをDBに登録(insert)する処理を記載中
- なんとなく動く気がするが、@hereや@everyoneの時、Botでどうするかわかっていない(他は<@99999>で良い)
- slashコマンド(discord)を知ったので是非使ってみたいと思ったので実装してみる
- うまくいかず。その理由は「slash = SlashCommand(bot, sync_commands=True)」が認識されていなかったため
def __init__(self, command_prefix, intents):
の中にslash = SlashCommand(self, sync_commands=True)
を追加し、動いたsimole-reminderbot.py
でとてもシンプルな構成にして動くことを確認し、それが今回のやり方だとbotとはselfに当たると気づいて解決- Pythonが普通にできる人は普通に解決できそうな気がする。。。
- slashコマンドの続き
- taskで定期的に実行させる
- listの@を無効化する
- 簡易的な日付入力を許可する
- 別チャンネルへ投稿できるようにする
- listコマンドの出力を少し整形
- AES暗号化(3分クッキング形式にする予定)
- 環境変数
KEEP_DECRYPTED_FILE
がTRUEの時のみ、復号化されたDBを残す
- 環境変数
- 繰り返しの対応(途中)
- 繰り返し間隔だけ延ばした次のリマンドが現実時間に追いつかない時、さらに次の間隔だけ延ばすようにした
- 一般的な、分〜年までの繰り返し間隔に対応(特殊なパターンについては対応していない)
- やりたいことが増えた(繰り返し回数の話、他コマンド)
- 繰り返し回数を設定するオプション
- 繰り返し回数だけ繰り返されたら、repeat_flgが'0'になり、繰り返さない
- 繰り返された回数を表示しても良いかも(繰り返しの場合。
(2)とか末尾に
)
- 他のコマンドを作ってみる(対応できず)
- リマインドを削除するコマンド
- リマインドの繰り返しフラグを'0'にするコマンド
- 特殊な繰り返し間隔について対応
- 対応済
- リマインドを削除するコマンド
- Heroku対応
- HerokuはPaasの一種。Salesforceが運営(買収したらしい)。データが1日1回は初期化される
- repl.itで動かすとremindが消えてしまう(#12)が、これはrepl.itでsqliteが使えない?ことを起因とするのかもしれない。Heroku対応をすることで直る可能性がある。
- DM対応
-
- DMでリマインダーが登録できる(リマインド先はDMのみとする)
- HerokuかReplitモード(2024年やめた)のときは、最初読み込んだ際にデフォルトのギルド+チャンネルを保管しておく
- DMにデータを保管させるとデータの読み込みに手間取りそうなため
- リマインド先をDMとするため、ギルドとチャンネルをNoneとする(Int型のため)
-
- DMへリマインドする
- ギルドとチャンネルがNoneのとき、authorを確認し、DMへリマインドする(どうなるか試すけど、メンションを常につけるなどの工夫するかも)
-
- リスト表示でオプションとして、ステータスを選べるように変更
- 時間についても、xxh(xx時間後)やxxmi(xx分後)で指定できるように変更(#23)
- 改行できるようにした(
などで指定する) - discord.py v2.0に対応
- メッセージのチェックや次回リマインド作成のお知らせは
@silent
とした @silent
やオプションでのsilent指定の対応した
- スキップコマンド(
remind-skip
)の追加 remind-list
系のスキップ対応
remind-make
のメッセージにスタンプ(Stickers)があればスタンプに変換
remind-list-xxx
の改善(検索対象を増やした)remind-cancel
の仕様変更- ギルド管理者はギルド内のリマインドもキャンセルできるようにした
- Botオーナーはすべてのリマインドもキャンセルできるようにした
/remind-id-user-delete
追加/remind-id-user-recovery
追加- BAN機能の追加(Botオーナーしか使えないもの)
- 1miでメンションつけて荒らす民が発生傾向にあったため作成したコマンド
- ギルド内BANもあとで作成する予定
- BAN機能の追加(Botオーナーしか使えないもの)
/remind-id-user-guild-delete
追加/remind-id-user-guild-recovery
追加- ギルド内BAN機能の追加(Administrator権限保持者しか使えないもの)
- 考えが浅くて発生したバグも対処(進行中のリマインドが存在しない場合BANできないバグの対処)
- ギルド内BAN機能の追加(Administrator権限保持者しか使えないもの)
/delete-own-remind
追加/delete-guild-remind
追加- 自分のremindを消すコマンド、ギルドのremindを消すコマンド(Administrator権限保持者しか使えないもの)の追加
- replit対応をやめた(keep_alive.pyを削除)
- 一部ライブラリについてアップデート(セキュリティ的な意味で)
- 最大繰り返し回数未設定の場合、繰り返し回数を付与しないように変更
- その代わり、list系で現在回数を表示するように設定
- 逐次処理ではなく、キューを使ってリマインドを処理するよう変更
- メリット: リマインド速度の向上
- デメリット: リスト反映速度の劣化、次リマインド登録速度の劣化、処理停止タイミングが繊細になった
- 他のコマンドを作ってみる
- リマインドの繰り返しフラグを'0'にするコマンド
- メンバーあてのメンションがわかりづらい(ID)ので、時間があったら名前にする(guildのget_memberを使う!)
- モンキーテスト
- 本当ならテストもコメントとかに埋め込んでいい感じするなり、GitHubとかに上げてCIでなんやかんやすると思うが、そんな知識はない!のでやらない!!
- そのため、適当に動かしてバグっぽい挙動に気づくというお猿さんみたいなことをする
- Botを登録してくださった人が色々エラー起こしてくれるので自分でやらなくて済んだかも。。。
- やはり自分で打鍵すると手加減してしまうのかも