A comprehensive Rust SDK for the Slack API with support for both standard OAuth tokens and stealth mode authentication.
- Multiple authentication methods: OAuth tokens (xoxp, xoxb) and stealth mode (xoxc/xoxd)
- Complete API coverage: 25 API modules covering all major Slack functionality
- Real-time messaging via WebSocket (RTM API and Socket Mode)
- Block Kit builders for rich message layouts
- Strongly typed requests and responses
- Built on tokio for async/await support
- Automatic rate limit detection
Add to your Cargo.toml:
[dependencies]
slacko = "0.2"
tokio = { version = "1", features = ["full"] }use slacko::{SlackClient, AuthConfig};
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
// Using a bot token
let client = SlackClient::new(AuthConfig::bot("xoxb-your-token"))?;
// Post a message
client.chat().post_message("#general", "Hello from Rust!").await?;
// List channels
let channels = client.conversations().list().await?;
for channel in channels.channels {
println!("#{}", channel.name.unwrap_or_default());
}
Ok(())
}use slacko::{SlackClient, AuthConfig};
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
let client = SlackClient::new(
AuthConfig::stealth("xoxc-your-token", "xoxd-your-cookie")
)?;
let user = client.auth().test().await?;
println!("Authenticated as {}", user.user);
Ok(())
}# OAuth mode
export SLACK_BOT_TOKEN=xoxb-...
# or
export SLACK_TOKEN=xoxp-...
# Stealth mode
export SLACK_XOXC_TOKEN=xoxc-...
export SLACK_XOXD_COOKIE=xoxd-...let client = SlackClient::new(AuthConfig::from_env()?)?;// Post message
client.chat().post_message("#general", "Hello!").await?;
// Reply in thread
client.chat().post_reply("#general", "1234567890.123456", "Reply").await?;
// Update message
client.chat().update_message("#general", "1234567890.123456", "Updated").await?;
// Delete message
client.chat().delete_message("#general", "1234567890.123456").await?;// List channels
let channels = client.conversations().list().await?;
// Create channel
client.conversations().create("new-channel", false).await?;
// Get history
let history = client.conversations().history("C12345678").await?;
// Invite users
client.conversations().invite("C12345678", &["U12345678"]).await?;// List users
let users = client.users().list().await?;
// Get user info
let user = client.users().info("U12345678").await?;
// Set presence
client.users().set_presence("away").await?;// Upload file
client.files().upload(content, "file.pdf", Some(&["C12345678"])).await?;
// List files
let files = client.files().list().await?;// Add reaction
client.reactions().add("C12345678", "1234567890.123456", "thumbsup").await?;
// Remove reaction
client.reactions().remove("C12345678", "1234567890.123456", "thumbsup").await?;// Search messages
let results = client.search().messages("query").await?;
// Search files
let files = client.search().files("filename").await?;// Connect and listen for messages
client.rtm().start(|message| {
println!("Received: {:?}", message.text);
}).await?;Socket Mode allows receiving events via WebSocket without exposing a public HTTP endpoint.
Requires an app-level token (xapp-...).
// Listen for events, interactive payloads, and slash commands
client.socket_mode().start(|event| {
match event.payload {
SocketModePayload::EventsApi(payload) => {
println!("Event: {:?}", payload.event);
}
SocketModePayload::Interactive(payload) => {
println!("Interaction: {}", payload.interaction_type);
}
SocketModePayload::SlashCommand(payload) => {
println!("Command: {} {}", payload.command, payload.text.unwrap_or_default());
}
_ => {}
}
None // Optional response payload
}).await?;
// With automatic reconnection
client.socket_mode().start_with_reconnect(|event| {
// Handle events...
None
}).await?;use slacko::{MessageBuilder, SectionBlock, TextObject, ActionsBlock, ButtonElement};
let blocks = MessageBuilder::new()
.add_header(HeaderBlock::new("Status Update"))
.add_section(
SectionBlock::new(TextObject::markdown("*Build succeeded*"))
)
.add_divider()
.add_actions(
ActionsBlock::new()
.add_button(ButtonElement::new("view", "View Details"))
)
.build();
client.chat().post_message_with_blocks("#general", "Build update", blocks).await?;| Module | Description |
|---|---|
admin |
Enterprise Grid administration |
apps |
App management and permissions |
auth |
Authentication verification |
bookmarks |
Channel bookmarks |
calls |
Slack Calls integration |
chat |
Messages and threads |
conversations |
Channels, DMs, and groups |
dialog |
Legacy dialogs |
dnd |
Do Not Disturb settings |
emoji |
Custom emoji |
files |
File uploads and management |
oauth |
OAuth token exchange |
openid |
OpenID Connect authentication |
pins |
Pinned messages |
reactions |
Emoji reactions |
reminders |
Reminders |
rtm |
Real-time messaging (legacy) |
socket_mode |
Socket Mode for WebSocket events |
search |
Message and file search |
stars |
Starred items |
team |
Team information |
usergroups |
User groups |
users |
User information and presence |
views |
Modals and App Home |
workflows |
Workflow Builder |
use slacko::SlackError;
match client.chat().post_message("#general", "Hello").await {
Ok(response) => println!("Sent: {}", response.ts),
Err(SlackError::RateLimitExceeded { retry_after }) => {
println!("Rate limited, retry after {} seconds", retry_after);
}
Err(SlackError::ApiError { method, message }) => {
println!("API error in {}: {}", method, message);
}
Err(e) => println!("Error: {}", e),
}- Create a Slack App at https://api.slack.com/apps
- Add required OAuth scopes under "OAuth & Permissions"
- Install the app to your workspace
- Copy the Bot Token (xoxb-...) or User Token (xoxp-...)
Use the included browser extension for easy token extraction:
- Load the extension from
browser-extension/in Chrome (chrome://extensions > Load unpacked) - Navigate to your Slack workspace in the browser
- Click the extension icon and copy the tokens
Or extract manually:
- Open Slack in your browser
- Open Developer Tools (F12)
- Go to Application > Cookies, find the
dcookie (xoxd value) - Go to Network tab, find any API request with
tokenparameter (xoxc value)
# Set up credentials
cp .env.example .env
# Edit .env with your tokens
# Run tests
cargo test --testsMIT License. See LICENSE for details.