Skip to content
On this page

discord bot で todo list を作る

2023-11-18


という建前のタイトルはどうでもよくて、要するに discord や slack のような複数チャンネルが存在するようなアプリケーションでデータの永続化をする方法の1つについて書いてみる。

自分は自分の身内の discord サーバで bot を動かしているが、こういうのを作ってると、しばしばデータの永続化をしたいシーンが出てくる。RSS フィードを取りたい!かもしれないし、todo list を管理したい!かもしれないし、リマインダーを作りたい!かもしれない。

結論から言うと、それ用のチャンネル作ってそこからデータとってくれば良さそう。つまりメッセージがレコードになるということ。

補足

あんまり永続化したいデータの量が多くない想定です。

普通に考えたときの永続化

大体、永続化と調べて一番最初に出てくるのはデータベースを使うことだと思う。
ただ、課題もいくつかあって、一番大きいのは個人開発で作るものにお金をかけたくないとか、DB用意して繋いでってやるのめんどくさいとか、そういうのが真っ先に浮かぶと思う。

解決方法

冒頭で書いた通り、それ用のチャンネルを作るといい。
discord の API は任意のチャンネルの任意のテキストを取得する方法が提供されている。

例えば、自分の身内のサーバでは #db という名前のプライベートチャンネルを作り、そこに prefix をつけてデータを入れている。
todo list の内容であれば todo_messeage という prefix をつけているので、todo_message で始まるメッセージを取得することで todo list を取得することができる。

具体的なのソースコードだとこんな感じ。

// https://github.com/takurinton/c04bdbc0411b0f0fffcc8147ba10411f334da5d6c5bb8e6db9358c5f14aeb0cc/blob/main/src/commands/todo.rs#L64-L73
let messages = match db_channel
    .messages(&ctx.http, |retriever| retriever.limit(100))
    .await
{
    Ok(messages) => messages
        .into_iter()
        // todo list の一覧を取得する
        .filter(|message| message.content.starts_with("todo_message"))
        .collect::<Vec<_>>(),
    Err(_) => return "メッセージの取得に失敗しました".to_string(),
};
1
2
3
4
5
6
7
8
9
10
11
12

prefix つける方法以外だとチャンネル分けるのもあり、1チャンネルを1テーブルみたいな考え方で RDB ぽい振る舞いもできたりする。
小さく作るのであればそれでいいのではと思う。

まとめ

discord bot に限らず、slack とかでもチャンネルをデータベースとして扱うみたいなことができると思うのでこういう案は頭の片隅に入れておくと良さそう。