RustでDiscordに投稿するCLIを作ります。
実行環境
- M2 Mac
- Rust 1.76
準備
Discordの設定からwebhookを作成します。
ウェブフックURLが発行されるのでコピーします。 このURLが投稿のPOST先となります。
https://discord.com/api/webhooks/xxxxxxxx/xxx
ライブラリをインストールする
httpリクエストはreqwestを使います。POSTデータはjsonにシリアライズする必要があるのでserde_jsonもインストールしておきます。
[dependencies]
reqwest = { workspace = true, features = ["json"] }
clap = { workspace = true, features = ["derive"] }
tokio = { workspace = true, features = ["full"] }
serde = { workspace = true, features = ["derive"] }
serde_json = { workspace = true }
実装する
まずは投稿データのリクエストDTOを定義します。
#[derive(Debug, Clone, Serialize)]
struct Message {
content: String,
}
impl Message {
fn new(message: &str) -> Self {
Self {
content: message.to_string(),
}
}
}
文字列を投稿する関数を定義します。 WEBHOOK_URLには準備で作成したwebhookのURLを指定します。
async fn send_message(s: &str) -> Result<(), Box<dyn std::error::Error>> {
let mut headers = HeaderMap::new();
headers.append(
"Content-Type",
"application/json"
.parse()
.expect("application/jsonがパースできない"),
);
let message = Message::new(s);
let message = serde_json::to_vec(&message).expect("jsonにserializeできません");
let response = reqwest::Client::new()
.post(WEBHOOK_URL)
.headers(headers)
.body(Body::from(message))
.send()
.await
.expect("エラー");
if !response.status().is_success() {
tracing::error!("discordがエラーを応答しました, {:?}", response.text().await);
}
Ok(())
}
メイン関数を定義します。
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
send_message("いぇい").await
}
URLにjsonをpostするだけなのでとても簡単!