この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。
Introduction
私はクラスメソッドで、10年以上リモートワークで作業しているのですが、
メンバーとのやり取りはほとんどSlackでやっています。
しかし、仕事以外ではここ数年、Discordを使う機会が増えてきました。
どうせならbotでもつくってみたいなーと思っていたところ、よい記事があったので、
これを参考にDiscordのシンプルなbotをRustで作成してみます。
Discord?
Discordは、オープンなコミュニティの色合いが強いチャットサービスです。
テキストチャットや通話、ビデオミーティングなどの機能をもってます。
そして、botとはDiscordの拡張機能みたいなものです。
Discordサーバに任意のbotを招待することで、そのbotの機能が使えるようになります。
ちょっと前に話題になった、画像生成AIのMidjourneyもDiscordのbotとして提供されてました。
Environment
- OS : MacOS 12.4
- Rust : 1.62.1
※ M1 Mac(2020)にて動作確認
Setup Discord bot
Discordアカウントの登録
Discordのアカウントがない人は、ここで必要事項を記述して
アカウントを登録しておきましょう。
ログインしたら画面左のサーバ追加ボタンから、
bot動作確認用の適当なサーバを作成しておきます。
botを登録する
まずはbotをDiscordに登録します。
ここへアクセスし、New Applicationボタンを押して
新しいアプリケーションを作成します。
名前を適当に決め、チェックボックスにチェックをつけてCreateボタンを押す。
botのアイコンや情報について設定します。
ここでApplication IDが表示されているので、覚えておきましょう。
サイドバーのメニューから「Bot」を選択します。
ここでは表示名を決めることができます。
また、後で使用するのでReset Tokenボタンを押してトークンを覚えておきます。
そして、bot送られたメッセージから情報を取得するために、
画面下へスクロールし、「MESSAGE CONTENT INTENT」にチェックをつけ、
「Save Changes」ボタンを押して設定を保存します。
次に、下記URLをブラウザでアクセスし、botを認証します。
<Application ID>のところはさきほどコピーしたApplication IDに置き換えてください。
https://discord.com/oauth2/authorize?client_id=<Application ID>&scope=bot&permissions=8
下記画面が表示されるので、作成したサーバーを選択して「はい」を押します。
これでbotが作成されました。
bot追加のメッセージが表示され、画面右に作成したbotが出てきてます。
(オフラインですが)
bot実装前の準備
画面下の歯車アイコンから詳細設定を選択し、「開発者モード」をオンにしておきます。
↑をしておくと、サーバのコンテキストメニューからIDをコピーできたり、bot開発に役立つ機能が追加されます。
Create bot with Rust
botの登録ができたので、実装していきます。
まずは必要なツールやライブラリをインストールします。
cargo-shuttleのインストールとプロジェクト作成
cargo-shuttleはサーバレスWebプラットフォームであるshuttle上に
Webアプリケーションをデプロイするためのコマンドラインツールです。
cargo installでインストールします。
% cargo install cargo-shuttle
Serenity は、Discordのbot用ライブラリです。
下記のようにcargo-shuttleを使って、shuttleへデプロイできる
Serenityを使ったプロジェクトを作成できます。
% cargo shuttle init --serenity
コード実装
まずはプロジェクトのルートにSecrets.tomlファイルを作成し、
↓のように記述します。
DISCORD_TOKEN="<Reset Tokenで取得したトークン>"
DISCORD_GUILD_ID="<コンテキストメニュー→サーバIDをコピー でコピーしたID>"
src/lib.rsを、下記のように修正します。
use log::info;
use serenity::async_trait;
use serenity::model::gateway::Ready;
use serenity::model::prelude::*;
use serenity::prelude::*;
use serenity::model::prelude::interaction::Interaction::ApplicationCommand;
use serenity::model::interactions::*;
use shuttle_service::error::CustomError;
use shuttle_service::SecretStore;
use sqlx::PgPool;
struct Bot;
#[async_trait]
impl EventHandler for Bot {
async fn ready(&self, ctx: Context, ready: Ready) {
info!("{} is connected!", ready.user.name);
let guild_id = GuildId(<DISCORD_GUILD_ID>);
//コマンドを登録
let commands = GuildId::set_application_commands(&guild_id, &ctx.http, |commands| {
commands.create_application_command(|command| {
command.name("hello").description("Say hello")
}).create_application_command(|command| {
command.name("bye").description("Say Good Bye")
})
})
.await
.unwrap();
info!("{:#?}", commands);
}
async fn interaction_create(&self,ctx: Context,interaction: serenity::model::interactions::Interaction) {
if let ApplicationCommand(command) = interaction {
let response_content = match command.data.name.as_str() {
"hello" => "hello!!".to_owned(),
"bye" => "good bye!!".to_owned(),
command => unreachable!("Unknown command: {}", command),
};
let create_interaction_response =
command.create_interaction_response(&ctx.http, |response| {
response
.kind(InteractionResponseType::ChannelMessageWithSource)
.interaction_response_data(|message| message.content(response_content))
});
if let Err(why) = create_interaction_response.await {
eprintln!("Cannot respond to slash command: {}", why);
}
}
}
}
・・・
ready関数にhelloとbyeというコマンドを登録し、
interaction_create関数(登録したコマンドを使ったときのhook)で
コマンドに対するレスポンスを実装します。
それぞれコマンドを受け取ったら、適当なメッセージを返すだけの簡単なものです。
コードが修正できたらrunコマンドを実行してテストしてみます。
% cargo shuttle run
Finished dev [unoptimized + debuginfo] target(s) in 2.44s
DB ready can be reached at postgres://postgres:postgres@localhost:24660/postgres
Starting discord-bot on http://127.0.0.1:8000
DB ready can be reached at postgres://postgres:postgres@localhost:24660/postgres
botがオンラインになりました。
/hello,/byeと登録したコマンドを実行すると、botがメッセージを返してくれます。
なお、ローカルテストでなくshuttleにデプロイしたいならdeployコマンドを実行します。
% cargo shuttle deploy
Summary
今回はRustでDiscordのシンプルなbotを実装して
動作確認してみました。
参考にしたここでは、
このあとさらにいろいろなAPIを使ってbotを実装しているので、
興味のあるかたはチェックしてみてください。