The project is in a healthy, maintained state
Discord bot adapter for the ChatSDK framework
2005
2006
2007
2008
2009
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
2025
2026
 Dependencies

Runtime

>= 0.1
~> 1.3
~> 2.0
 Project Readme

ChatSDK Ruby — One Ruby gem. Every channel.

CI MIT License Gem Version

Beta — This SDK is experimental and under active development. APIs may change between minor versions. Not recommended for production use yet.

Unified Ruby SDK for building chat bots across Slack, Microsoft Teams, Google Chat, Mattermost, Discord, Telegram, Twilio SMS/MMS, Facebook Messenger, WhatsApp, X, Linear, and more. Write your bot logic once, deploy everywhere.

Inspired by and built upon the API design of Vercel's Chat SDK (TypeScript). This is an independent Ruby implementation — not a fork — with idiomatic Ruby patterns, a block-based cards DSL, and adapters tailored for the Ruby ecosystem.

Installation

Add the core gem and one or more adapters to your Gemfile:

gem "chat_sdk"
gem "chat_sdk-slack"
gem "chat_sdk-teams"
gem "chat_sdk-gchat"
gem "chat_sdk-mattermost"
gem "chat_sdk-discord"
gem "chat_sdk-telegram"
gem "chat_sdk-twilio"
gem "chat_sdk-messenger"
gem "chat_sdk-whatsapp"
gem "chat_sdk-x"
gem "chat_sdk-linear"
gem "chat_sdk-state-redis"
gem "chat_sdk-state-pg"
gem "chat_sdk-state-mysql"

Usage

require "chat_sdk"
require "chat_sdk/slack"
require "chat_sdk/state/redis"

bot = ChatSDK::Chat.new(
  user_name: "mybot",
  adapters: {
    slack: ChatSDK::Slack::Adapter.new(
      bot_token: ENV["SLACK_BOT_TOKEN"],
      signing_secret: ENV["SLACK_SIGNING_SECRET"]
    )
  },
  state: ChatSDK::State::Redis.new(url: ENV["REDIS_URL"])
)

bot.on_new_mention do |thread, message|
  thread.subscribe
  thread.post("Hello! I'm listening to this thread.")
end

bot.on_subscribed_message do |thread, message|
  thread.post("You said: #{message.text}")
end

Mount webhooks in Rails:

# config/routes.rb
mount Bot.webhooks[:slack], at: "/webhooks/slack"

Or plain Rack:

# config.ru
map("/webhooks/slack") { run Bot.webhooks[:slack] }

See the Getting Started guide for a full walkthrough.

Features

  • Event handlers — mentions, messages, reactions, button clicks, slash commands
  • Streaming — stream LLM responses with progressive message editing and throttled updates
  • Cards DSL — Ruby block-based interactive cards (Block Kit, Adaptive Cards, Google Chat Cards)
  • Actions — handle button clicks and dropdown selections
  • Modals — form dialogs with text inputs, dropdowns, and validation
  • Slash commands — handle /command invocations
  • Emoji & reactions — cross-platform emoji reactions
  • Direct messages — initiate DMs programmatically
  • Ephemeral messages — user-only visible messages
  • Concurrency — distributed locking with configurable conflict policies (drop, force, callable)

Cards DSL

Replace JSX with Ruby blocks:

thread.post(ChatSDK.card(title: "Incident #4821", subtitle: "SEV1 — API latency") do
  text "Triggered by *Datadog* at 14:02 UTC"
  fields do
    field "Service", "ingest-api"
    field "On-call", "@quentin"
  end
  divider
  actions do
    button "Acknowledge", id: "incident:ack", style: :primary, value: "4821"
    button "Resolve", id: "incident:resolve", style: :danger, value: "4821"
    link_button "Runbook", url: "https://rootly.com/runbooks/api-latency"
    select id: "severity", placeholder: "Severity" do
      option "SEV1", value: "sev1"
      option "SEV2", value: "sev2"
    end
  end
end)

Cards render natively on each platform — Slack Block Kit, Teams Adaptive Cards, Google Chat Card V2.

Escape Hatches

Three tiers of access — use the normalized API or drop down when you need platform-specific control:

# Tier 1 — normalized (cross-platform)
thread.post("hello")

# Tier 2 — adapter contract (still normalized message format)
bot.adapter(:slack).post_message(channel_id: "C123", message: msg)

# Tier 3 — raw platform client
bot.adapter(:slack).client.chat_postMessage(channel: "#ops", text: "raw")

Adapters

Feature Slack Teams GChat Mattermost Discord Telegram Twilio Messenger WhatsApp X Linear
Post/Edit/Delete ✓/✗/✓ ✓/✗/✗ ✓/✗/✗ ✓/✗/✓
Ephemeral
Reactions
File uploads
Modals
Streaming
DMs
History
Typing

Platform clients:

  • Slack — wraps slack-ruby-client
  • Teams — raw Faraday client (no Ruby Bot Framework SDK exists)
  • GChat — wraps google-apps-chat-v1
  • Mattermost — raw Faraday client wrapping the Mattermost REST API
  • Discord — raw Faraday client wrapping the Discord REST API v10 with Ed25519 signature verification
  • Telegram — raw Faraday client wrapping the Telegram Bot API with webhook secret token verification and inline keyboard rendering
  • Twilio — raw Faraday client wrapping the Twilio REST API with HMAC-SHA1 signature verification for SMS/MMS messaging
  • Messenger — raw Faraday client wrapping the Facebook Messenger Send API with HMAC-SHA256 signature verification and Generic/Button template rendering
  • WhatsApp — raw Faraday client wrapping the WhatsApp Business Cloud API with HMAC-SHA256 signature verification and interactive message rendering
  • X -- raw Faraday client wrapping the X API v2 with HMAC-SHA256 webhook signature verification for tweets, DMs, and likes
  • Linear -- raw Faraday client wrapping the Linear GraphQL API with HMAC-SHA256 webhook signature verification for issue comment threading

AI Coding Agents

For agent-readable documentation, see llms.txt (page index).

Documentation

Full documentation is available in the docs/ directory.

Contributing

See CONTRIBUTING.md for guidance. For security vulnerabilities, see SECURITY.md.

Acknowledgments

Thanks to the Vercel team for creating the original Chat SDK (MIT). Their elegant API design — normalized events, pluggable adapters, cards abstraction, and streaming model — is what made this Ruby port possible. We're grateful for their work and the open source community around it.

License

MIT — see LICENSE.

Made by Rootly