Open64

Rustのserenityでdiscord bot作りたい

so-heyso-hey

songbirdなるものを使えばボイスチャットで無双できるらしいけどまずはチャットだけにしておく

so-heyso-hey

cargo-shuttleってなんだ?
npmみたいなもんか?(npmもよくわかっていない)

so-heyso-hey

cargo shuttleするだけである程度コード書いてたから,これをいろいろいじればいいんだな

so-heyso-hey

EventHandlerトレイトはたくさんの非同期メソッドがあって、それぞれどのタイミングで呼び出されるかが名前からわかるようになってる。
「メッセージが送られたとき」みたいな当たり前のものから「誰かがタイプしているとき」みたいなニッチなものまで用意されててすごい

so-heyso-hey

webhookとstage instanceの意味がわからん

so-heyso-hey

自分は直感で理解するタイプだからこういう説明は非常に助かる

so-heyso-hey

今までアプリの通知とかってずっと変化がないか受け取る側がチラチラ確認するもんだと思ってた
このwebhookとやらを使えば簡単なんだ

so-heyso-hey

EventHandlerのready, message, voice_state_updateあたりを使って簡単なものを作ろう

so-heyso-hey

shardってなんだ

so-heyso-hey

データベースをいくつかに水平分割して保管する仕組み、またはその分割されたそれぞれのデータベースについてを指すもの

so-heyso-hey

マクロで作られたトレイトメソッドが読めないので、--pretty=expandedで実行したい(いまパソコンを使えない)

so-heyso-hey

今のレベルではcargo expandはあんまりするもんじゃないな
分からないことがふえるだけだ

so-heyso-hey

messageで全部条件分岐するんじゃなくて,ちゃんとコマンドとして関数を定義するには#[command]を使う

so-heyso-hey

これするためにはプレフィックスとかつけないと

so-heyso-hey

色々調べているとSlash Commandsなるものがあって,これを実装するとユーザーは"/"を打つだけですべてのコマンドとその機能のリストを見ることができるらしい.
自分が利用しているbotもプレフィックスが"!"から"/"に変更していたけどこういうことか.

so-heyso-hey

そしてSerenityはこれに対応しておらず,Poiseなるライブラリは対応しているらしい.
後で使ってみる.

so-heyso-hey

serenity/examplesのownerの意味が分からん
色々検証してみたけど,そのギルドの管理者でもないし招待した人でもなさそう

so-heyso-hey
async fn voice_state_update(
    &self,
    ctx: Context,
    _old: Option<VoiceState>,
    new: VoiceState
){
    println!("voice state update");
    if let Some(channel_id) = new.channel_id {
        println!(
            "{:?}",
            channel_id
                .name((&ctx.cache, ctx.http.as_ref()))
                .unwrap_or_else(|_| "No Name".to_string())
                .await
        );
    }
}

これでボイスチャンネルに入ったタイミングでそのボイスチャンネルの名前を出力できた

so-heyso-hey

コードの見た目以上に大変な作業って多いよね...

so-heyso-hey

自らボイスチャンネルに対して操作をするのってどうやるんだ?

so-heyso-hey

voice_state_updateはボイスチャンネルに動きがないと無理だよな...

so-heyso-hey

voice_state_updateで得たvoice stateを保持しておくとかかな

so-heyso-hey
async fn message(&self, ctx: Context, msg: Message) {
    if let Some(guild_id) = msg.guild_id {
        let guild = guild_id
            .to_partial_guild((&ctx.cache, ctx.http.as_ref()))
            .get_guild((&ctx.cache, ctx.http.as_ref()));
        let voice_state = guild.voice_state;
    }
}
so-heyso-hey
if let Some(cache_ref) = msg.guild(&ctx.cache) {
    let guild = cache_ref.clone();
    let voice_state = guild.voice_state;
}

これでええんか

so-heyso-hey

EventHandlerのreadyでコマンドを設定して、概要をメッセージで送るということをしてるけど、例のコードが古いバージョンやからなんとか今のバージョンに合わせる

so-heyso-hey

今までimpl CacheHttpが想定されてる引数には(&Arc<Cache>, &Http)を渡してきたけど、ContextとかHttpでもなんとかしてくれる

so-heyso-hey

pub(crate)はそのグレード内にだけ公開したいもの

so-heyso-hey

スラッシュコマンド使いたかったらpoiseしかないのか