🤖
[Rust] DiscordのBOT作成 < serenity > - ⑤
ボタンの作成と応答
押されたボタンの名前を返す
- 下記のようなボタンを作成し、押されたボタンの名前を返す
押されたボタンの名前を返す
ソースコード
- このサンプルではボタンを各々作成しているが、ボタンの数が多い場合は列挙型などでまとめると管理しやすい
main.rs
use serenity::builder::{CreateActionRow, CreateButton}; // アクション関係のモジュール
use serenity::model::application::component::ButtonStyle; // ボタンのスタイル
use std::time::Duration; // タイムアウト用
~~~~~~~~~~中略~~~~~~~~~~
if msg.content == "!btn" {
//----------ボタンAの作成----------
let mut btn_a = CreateButton::default();
btn_a.custom_id("Circle")
.emoji('\u{2b55}')
.label("マル")
.style(ButtonStyle::Primary);
//----------ボタンBの作成----------
let mut btn_b = CreateButton::default();
btn_b.custom_id("Cross")
.emoji('\u{274c}')
.label("バツ")
.style(ButtonStyle::Primary);
//----------アクションにボタンAとボタンBを追加----------
let mut btns = CreateActionRow::default();
btns.add_button(btn_a)
.add_button(btn_b);
//----------メッセージ(ボタン)の送信----------
let m = msg.channel_id.send_message(&ctx, |m| {
m.content("ボタンを選択してください")
.components(|c| c.add_action_row(btns))
})
.await
.expect("エラー");
//----------インタラクションとタイムアウトの設定----------
let mi = match m
.await_component_interaction(&ctx)
.timeout(Duration::from_secs(10))
.await
{
Some(interaction) => interaction,
None => {
m.delete(&ctx).await.expect("エラー");
msg.reply(&ctx, "タイムアウト").await.expect("エラー");
return
}
};
//----------ボタンAの作成----------
m.delete(&ctx).await.expect("エラー");
match &*mi.data.custom_id {
"Circle" => msg.reply(&ctx.http, "マル").await.expect("エラー"),
"Cross" => msg.reply(&ctx.http, "バツ").await.expect("エラー"),
_ => {
println!("エラー");
return
}
};
}
クレートの設定
-
serenity
のfeatures
内に"collector"
を追加する
Cargo.toml
serenity = { version = "0.11.5", default-features = false, features = ["cache", "client", "collector", "gateway", "rustls_backend", "model"] }
ソースコード解説
ボタンの作成
-
CreateButton::default()
- ボタンのオブジェクトを作成する
- ボタンのオブジェクトを作成する
-
.custom_id()
- ボタンのID(名前)を設定する
- ボタンのID(名前)を設定する
-
.emoji()
- ボタン上に表示する絵文字を設定する
- ボタン上に表示する絵文字を設定する
-
.label()
- ボタン上に表示するテキストを設定する
- ボタン上に表示するテキストを設定する
-
.style()
- ボタンのスタイルを設定する
ボタンの作成
let mut btn_a = CreateButton::default();
btn_a.custom_id("Circle")
.emoji('\u{2b55}')
.label("マル")
.style(ButtonStyle::Primary);
- ボタンのスタイルには以下のようなものがある
ボタンのスタイル
.style(ButtonStyle::Primary);
.style(ButtonStyle::Secondary);
.style(ButtonStyle::Success);
.style(ButtonStyle::Danger);
ボタンのスタイル
アクションにボタンを追加
-
CreateActionRow::default()
- アクションのオブジェクトを作成する
- アクションのオブジェクトを作成する
-
.add_button()
- アクションのオブジェクトに作成したボタンを追加する
アクションにボタンを追加
let mut act = CreateActionRow::default();
act.add_button(btn_a)
.add_button(btn_b);
メッセージ(ボタン)の送信
- ボタンの送信には
.send_message()
を使う
-
.components()
-
.send_message()
で送信するテキスト以外のコンポーネント(ここではボタン)をセットする
-
-
.add_action_row()
- コンポーネントにアクションのオブジェクトを追加する
メッセージ(ボタン)の送信
let m = msg.channel_id.send_message(&ctx, |m| {
m.content("ボタンを選択してください")
.components(|c| c.add_action_row(act))
})
.await
.expect("エラー");
インタラクションとタイムアウトの設定
-
.await_component_interaction()
- 送信したメッセージ(ここではボタン)に対してのインタラクション(ユーザーがボタンを押す動作)を待つ
- 送信したメッセージ(ここではボタン)に対してのインタラクション(ユーザーがボタンを押す動作)を待つ
-
.timeout()
- インタラクションの待機時間を設定する
-
Duration::from_secs(10)
によって10秒が設定される
- インタラクションが時間内に行われた場合、
Some(interaction)
が返されmi
にインタラクション結果(interaction
)を取り込む - インタラクションがタイムアウトした場合、
None
が返されNone => { }
を実行する
インタラクションとタイムアウトの設定
let mi = match m
.await_component_interaction(&ctx)
.timeout(Duration::from_secs(10))
.await
{
Some(interaction) => interaction,
None => {
m.delete(&ctx).await.expect("エラー");
msg.reply(&ctx, "タイムアウト").await.expect("エラー");
return
}
};
インタラクションに対する応答
-
.delete()
を使用して送信したメッセージ(ここではボタン)を削除し、押されたボタンのID(mi.data.custom_id
)に合わせたリプライを返す
インタラクションに対する応答
m.delete(&ctx).await.expect("エラー");
match &*mi.data.custom_id {
"Circle" => msg.reply(&ctx.http, "マル").await.expect("エラー"),
"Cross" => msg.reply(&ctx.http, "バツ").await.expect("エラー"),
_ => {
println!("エラー");
return
}
};
Discussion