A user-friendly Slack SDK implementation using slack-morphism-rust.
- ✅ 依存関係整理 (slack-morphism-rust, axum)
- ✅ Socket Mode対応 (feature = "socket_mode")
- ✅ メッセージ受信
- ✅ コマンド対応
- ✅ インタラクション対応
- ✅ axumでのHTTPサーバー
- ✅ Webhookエンドポイント実装
- 📝 OAuth対応
- ✅ イベント受信
- ✅ ドキュメント整備
- ✅ API使用例
- ✅ 環境変数設定
- ✅ テスト方法
Webhookを使用してSlackイベントを受信するには、以下の手順で実行します:
- 環境変数の設定:
export SLACK_SIGNING_SECRET="your-signing-secret"
- サンプルコードの実行:
cargo run --example webhook_example
Socket Modeを使用してSlackイベントを受信するには、以下の手順で実行します:
- 環境変数の設定:
export SLACK_APP_TOKEN="xapp-..."
- サンプルコードの実行:
cargo run --example socket_mode_example --features socket_mode
イベントハンドラを実装することで、Slackイベントの処理をカスタマイズできます。
ハンドラはSlackEventHandler
トレイトを実装する必要があります。
- ハンドラの実装:
use slack_rs::{SlackEventHandler, MessageClient};
use async_trait::async_trait;
#[derive(Clone)]
struct CustomHandler;
#[async_trait]
impl SlackEventHandler for CustomHandler {
async fn handle_event(
&self,
event: SlackPushEvent,
client: &MessageClient,
) -> Result<(), Box<dyn std::error::Error>> {
// イベントの処理をここに実装
Ok(())
}
}
- ハンドラの使用:
// デフォルトパス(/push)を使用する場合
let app = create_app_with_handler(
SlackSigningSecret::new(signing_secret),
SlackApiToken::new(bot_token),
CustomHandler,
);
// カスタムパスを使用する場合
let app = create_app_with_path(
SlackSigningSecret::new(signing_secret),
SlackApiToken::new(bot_token),
CustomHandler,
"/slack/events",
);
- NoopHandler(デフォルト):
// イベントを無視するデフォルトのハンドラ
let app = create_app(SlackSigningSecret::new(signing_secret));
- カスタムハンドラ:
// イベントをカスタム処理するハンドラ
let app = create_app_with_handler(
SlackSigningSecret::new(signing_secret),
SlackApiToken::new(bot_token),
CustomHandler,
);
- URL検証:
// URL検証は自動的に処理されます
// カスタム処理が必要な場合のみ実装してください
if let SlackPushEvent::UrlVerification(_) = event {
// URL検証イベントの処理
}
- メンション:
// メンションイベントの処理例
if let SlackPushEvent::EventCallback(callback) = event {
if let SlackEventCallbackBody::AppMention(mention) = callback.event {
// メッセージの送信
client
.reply_to_thread(
mention.channel.as_ref(),
&mention.origin.ts.to_string(),
"応答メッセージ",
)
.await?;
}
}
- エラーの返却:
// エラーは`Box<dyn std::error::Error>`として返却します
if something_went_wrong {
return Err("エラーが発生しました".into());
}
- ログ出力:
// tracing クレートを使用してログを出力します
tracing::info!("イベントを受信: {:?}", event);
tracing::error!("エラーが発生: {}", error);
必要な環境変数:
SLACK_SIGNING_SECRET
: Slackアプリの署名シークレットSLACK_BOT_TOKEN
: SlackボットのトークンNGROK_AUTHTOKEN
: ngrokのトークン(開発時)NGROK_DOMAIN
: ngrokのドメイン(開発時)
以下は、メンションされた時に応答するボットの実装例です:
use slack_rs::{SlackEventHandler, MessageClient};
use async_trait::async_trait;
#[derive(Clone)]
struct MentionHandler;
#[async_trait]
impl SlackEventHandler for MentionHandler {
async fn handle_event(
&self,
event: SlackPushEvent,
client: &MessageClient,
) -> Result<(), Box<dyn std::error::Error>> {
if let SlackPushEvent::EventCallback(callback) = event {
if let SlackEventCallbackBody::AppMention(mention) = callback.event {
client
.reply_to_thread(
mention.channel.as_ref(),
&mention.origin.ts.to_string(),
"はい、呼びましたか?",
)
.await?;
}
}
Ok(())
}
}
// ハンドラの使用
let app = create_app_with_handler(
SlackSigningSecret::new(signing_secret),
SlackApiToken::new(bot_token),
MentionHandler,
);
メンションされた時のみ応答するボットを実装する例です。以下の手順で実行します:
SLACK_SIGNING_SECRET
: Slackアプリの署名シークレットSLACK_BOT_TOKEN
: SlackボットのトークンNGROK_AUTHTOKEN
: ngrokの認証トークンNGROK_DOMAIN
: ngrokの固定ドメイン(例:arriving-informally-manatee.ngrok-free.app)
- Event Subscriptionsを有効化
- Request URLを設定:
https://{NGROK_DOMAIN}/push
- URLが有効であることを確認(チャレンジレスポンスが成功すること)
- 以下のBot Event Scopesを追加:
app_mentions:read
: メンションの検知用chat:write
: メッセージ送信用
注意: 権限を更新した場合は、必ずワークスペースからBotを一度削除し、再インストールしてください。 権限の更新は再インストール後に反映されます。
.env
ファイルに環境変数を設定:
SLACK_SIGNING_SECRET=your-signing-secret
SLACK_BOT_TOKEN=xoxb-your-bot-token
NGROK_AUTHTOKEN=your-ngrok-token
NGROK_DOMAIN=your-ngrok-domain
-
チャンネルの準備:
- ボットをチャンネルに招待:
/invite @[BOT名]
- チャンネルIDの確認方法は「検証手順」セクションを参照
- ボットをチャンネルに招待:
-
サーバーを起動:
cargo run --example mention_response --features events
- 動作確認:
- Slackでボットをメンション(@)する
- ボットが「はい、呼びましたか?」と応答することを確認
- 応答はスレッド内で行われます
Slack APIの使いやすいSDKを提供するRustライブラリです。slack-morphism-rustをベースに、特にSocket Modeを使用したメッセージの受信に焦点を当てています。
- 📝 slack-morphism-rustライブラリの依存関係追加
- 📝 tokio, hyper等の基本的な依存関係の設定
- 📝 環境変数設定の仕組み作成(SLACK_TEST_APP_TOKEN等)
- ✅ メッセージ送信の基本機能実装
- ✅ テキストメッセージの送信
- ✅ リッチメッセージ(ブロックキット)の送信
- ✅ ファイル添付機能
- ✅ スレッド返信機能
- ✅ メッセージの更新・削除機能
- ✅ メッセージ送信のエラーハンドリング
- ✅ レートリミット対応
- ✅ メッセージ送信のユーティリティ関数の提供
use slack_rs::{MessageClient, SlackApiToken, SlackApiTokenValue};
use slack_morphism::blocks::{SlackBlock, SlackBlockText, SlackSectionBlock};
// クライアントの初期化
let token = std::env::var("SLACK_BOT_TOKEN").expect("SLACK_BOT_TOKEN must be set");
let token = SlackApiToken::new(SlackApiTokenValue(token));
let client = MessageClient::new(token);
// テキストメッセージの送信
let message = client.send_text("C1234567890", "基本的なテキストメッセージ").await?;
// ブロックキットを使用したメッセージ
let blocks = vec![
SlackBlock::Section(
SlackSectionBlock::new().with_text(SlackBlockText::MarkDown("*太字* _斜体_ ~取り消し線~".into()))
),
SlackBlock::Section(
SlackSectionBlock::new().with_text(SlackBlockText::Plain("プレーンテキスト".into()))
),
];
client.send_blocks("C1234567890", blocks).await?;
// スレッド返信
client.reply_to_thread("C1234567890", &message.ts.to_string(), "スレッドへの返信").await?;
// メッセージの更新と削除
let message = client.send_text("C1234567890", "このメッセージは更新されます").await?;
client.update_message("C1234567890", &message.ts.to_string(), "更新されたメッセージ").await?;
client.delete_message("C1234567890", &message.ts.to_string()).await?;
// ファイルのアップロード
let file_content = "テストファイルの内容".as_bytes().to_vec();
client.upload_file(vec!["C1234567890".to_string()], file_content, "test.txt").await?;
-
Botの設定
- 以下の権限が必要です:
channels:read
: チャンネル情報の読み取りchat:write
: メッセージの送信files:write
: ファイルのアップロード
- 重要: 権限を更新した場合は、必ずワークスペースからBotを一度削除し、再インストールしてください。 権限の更新は再インストール後に反映されます。
- 以下の権限が必要です:
-
チャンネルの準備
- チャンネルIDの確認方法:
- Slackでチャンネルを開く
- チャンネル名をクリック
- 「チャンネルの詳細」の下部にチャンネルID(例:C1234567890)が表示されます
- Botをチャンネルに招待:
/invite @[BOT名]
コマンドを使用 または- チャンネルの設定から「メンバーを追加する」でBotを追加
- チャンネルIDの確認方法:
-
環境変数の設定
export SLACK_BOT_TOKEN=xoxb-your-token
- サンプルコードの実行
cargo run --example message_sending
注意: チャンネルIDは実際のSlackワークスペースのチャンネルIDに置き換えてください。
- 📝 Socket Modeクライアントの基本構造体の定義
- 📝 Socket Modeを使用したメッセージ受信ロジックの実装
- 📝 メッセージハンドラーの実装
- 📝 エラーハンドリングの実装
- 📝 非同期処理の最適化
- 📝 Socket Mode実装のユニットテスト作成
- 📝 Socket Modeを使用したメッセージ受信のサンプルコード作成
- 📝 サンプルコードの実行テスト作成
- 📝 テストケースのドキュメント作成
-
Slack APIトークンの取得
- Slack Appを作成し、Socket Modeを有効化
- App-Level Tokenを発行(
xapp-
で始まるトークン)
-
環境変数の設定
export SLACK_TEST_APP_TOKEN=xapp-your-token-here
use slack_rs::{create_app, create_app_with_path};
use axum::{routing::get, Router};
use slack_morphism::prelude::*;
#[tokio::main]
async fn main() {
// 環境変数からSlack署名シークレットを取得
let signing_secret = std::env::var("SLACK_SIGNING_SECRET")
.expect("SLACK_SIGNING_SECRETが設定されていません");
// デフォルトパス(/push)を使用する場合
let router = Router::new()
.route("/health", get(|| async { "OK" }))
.merge(create_app(SlackSigningSecret::new(signing_secret.clone())));
// カスタムパスを使用する場合(例:/slack/events)
let router = Router::new()
.route("/health", get(|| async { "OK" }))
.merge(create_app_with_path(SlackSigningSecret::new(signing_secret), "/slack/events"));
// サーバーの起動
let addr = std::net::SocketAddr::from(([127, 0, 0, 1], 3000));
axum::Server::bind(&addr)
.serve(router.into_make_service())
.await
.unwrap();
}
// ※実装完了後に追加予定
## コンポーネント構成
### Webhookクライアント
Webhookクライアントは、Slack Events APIからのイベントを受信・処理するための主要コンポーネントです。
以下の機能を提供します:
- イベント受信エンドポイント(`/push`)
- Slack署名検証
- イベントタイプに基づく処理の振り分け
- URL検証チャレンジへの対応
### Socket Modeクライアント
Socket Modeクライアントは、Slackのリアルタイムメッセージを受信するための主要コンポーネントです。
実装完了後、こちらに具体的な使用方法と設定例を追加します。
### エラーハンドリング
エラーハンドリングの方針と実装例については、実装完了後に追加します。