A windswept bonsai on a floating island

Get to know Cadenya

We’re developers who love to build. We set out to create a yes-code platform that makes building agents feel like the best parts of building software.

Slack Bolt for Go and Ruby (2026)

Slack

By Cadenya

There’s no official Slack Bolt for Go or Ruby. Slack Bolt SDK official support covers JavaScript, Python and Java, and for Go and Ruby the libraries agents land on are community ones: slack-go/slack, and slack-ruby-client with its socket mode and bot server add-ons.

So pick slack-go/slack in Go: it has socket mode, the Events API, assistant threads, chat.startStream and agents.sessions.setStatus. Pick slack-ruby-client in Ruby for the Web API and signature checks in a Rails controller, and add slack-ruby-bot-server-events or a socket mode gem when you want a framework around it. Pick a small Bolt for Python or JavaScript service when you want Slack’s own AI helpers. And for the agent loop behind any of them, Cadenya is a hosted option with Go and Ruby SDKs and nothing to host, and a coding agent can set it up with no account in a temporary workspace you claim later. What it offers is at the end.

Every price and limit below comes from each vendor’s own pages, checked on October 13, 2026.

Slack Bolt for Go and Ruby: the official SDK and the community libraries side by side

Bolt (JavaScript, Python, Java)slack-go/slackslack-ruby-clientslack-ruby-bot-server-eventsbolt_rb
LanguageJavaScript, Python, JavaGoRubyRubyRuby
Who makes itSlackCommunity, listed by SlackCommunity, listed by SlackCommunity (slack-ruby)Community (h2ik/bolt_rb)
Latest releasebolt-js v5.1.0, bolt-python v1.30.0, Java SDK v1.52.0v0.30.1, October 4, 20263.3.0, October 9, 20260.4.0, September 22, 20250.5.0, September 17, 2026
LicenseMITBSD 2-ClauseMITMITMIT
Socket modeBuilt insocketmode packageCalls apps.connections.open. The WebSocket loop is yoursHTTP events, actions and commandsSocket mode only
Events API over HTTPBuilt inslackevents packageSlack::Events::Request#verify!Events, actions and commandsSocket mode is its transport
Assistant threads and agent sessionssetStatus and setTitle helpers in JavaScript and PythonSetAssistantThreadsStatus, SetAgentSessionStatusassistant_threads_setStatus, agents_sessions_setStatusThrough slack-ruby-clientAssistantHandler with set_status and set_title
Text streamingsay_stream helper in JavaScript and PythonStartStream, AppendStream, StopStreamchat_startStream, chat_stopStreamThrough slack-ruby-clientNot documented
Runtime versionPer frameworkGo 1.26 or laterRuby 2.7 or laterRuby, plus MongoDB or PostgreSQLRuby

Cadenya isn’t a Slack library, so it sits behind any of these as the agent loop: your Slack handler acks and makes one API call, and Cadenya runs the loop, with Go 1.22 and Ruby 3.1 SDKs at 1.9.0 and nothing to host.

Slack’s own community page lists both libraries. Under Go it names “slack”, a library “supporting the Web API and RTM APIs”, and under Ruby it names slack-ruby-client and slack-ruby-bot-server.

Slack Bolt SDK supported languages: JavaScript, Python and Java

Slack’s tools page lists three Bolt frameworks: Bolt for Java, Bolt for JavaScript, and Bolt for Python. The SDK list beside it adds the Deno Slack SDK, the Java Slack SDK, the Node Slack SDK, and the Python Slack SDK. Slack’s llms.txt says the same thing in one line: the docs cover “Bolt frameworks (JavaScript, Python, Java)”.

So “Slack Bolt for Go” and “Slack Bolt for Ruby” don’t exist as Slack products. The slackapi organization on GitHub has bolt-js, bolt-python, and java-slack-sdk, and no Bolt repository for Go or Ruby.

Does it matter for an AI app? A little. Slack’s agent guide says “Bolt for JavaScript and Bolt for Python have a streamer utility” for the three streaming methods, and it shows Bolt helpers called setStatus, say_stream, and setTitle. But every one of those helpers wraps a plain Web API method, and the same guide shows “a sample request for the API without using the Bolt framework” for each. A Go or Ruby client that calls those methods gets the same features. You write the wrapper.

Slack also describes the agent’s job in one sentence: “The response loop is a cycle of receive input → reason → call tools → stream/render output.” None of the libraries on this page write that loop for you, in any language. (More on that at the end.)

slack-go/slack: socket mode, assistant threads and chat.startStream in Go

slack-go/slack is the Go library agents find first, and it covers the agent features. Its README says it “supports most if not all of the api.slack.com REST calls,” and the repository ships a socketmode package, a slackevents package, and examples for socket mode, the Events API, AI apps, and chat streaming.

The latest release is v0.30.1, a security release from October 4, 2026. The release before it, v0.30.0, added agent messaging events (app_context_changed, agent_session_stopped, agent_session_title_changed) and SetAgentSessionStatus for agents.sessions.*. It also fixed socket mode reconnects “when the stream ends in the middle of a TLS record instead of panicking.” And it raised the floor: “It needs Go 1.26 or later.”

The AI methods sit on the client: StartStream, AppendStream, and StopStream map to chat.startStream, chat.appendStream, and chat.stopStream, and SetAssistantThreadsStatus, SetAssistantThreadsSuggestedPrompts, and SetAssistantThreadsTitle map to the assistant.threads.* methods.

Socket mode needs two tokens: an app-level token (xapp-) to open the WebSocket and a bot token (xoxb-) for Web API calls. Here’s the handler from the repository’s examples, trimmed to one app mention:

package main

import (
	"log"
	"os"

	"github.com/slack-go/slack"
	"github.com/slack-go/slack/slackevents"
	"github.com/slack-go/slack/socketmode"
)

func main() {
	api := slack.New(
		os.Getenv("SLACK_BOT_TOKEN"),                            // xoxb-...
		slack.OptionAppLevelToken(os.Getenv("SLACK_APP_TOKEN")), // xapp-...
	)
	client := socketmode.New(api)
	handler := socketmode.NewSocketmodeHandler(client)

	handler.HandleEvents(slackevents.AppMention, func(evt *socketmode.Event, client *socketmode.Client) {
		client.Ack(*evt.Request) // ack first, work second

		eventsAPIEvent, _ := evt.Data.(slackevents.EventsAPIEvent)
		ev, ok := eventsAPIEvent.InnerEvent.Data.(*slackevents.AppMentionEvent)
		if !ok {
			return
		}
		_, _, err := client.Client.PostMessage(ev.Channel,
			slack.MsgOptionText("On it.", false),
			slack.MsgOptionTS(ev.TimeStamp),
		)
		if err != nil {
			log.Printf("post failed: %v", err)
		}
	})

	log.Fatal(handler.RunEventLoop())
}

client.Ack is the important line. Slack’s socket mode guide says “Your app still needs to acknowledge receiving each event so that Slack knows whether to retry,” so the ack goes before any slow work. Why it has to be fast, and what Slack does when it isn’t, is in the Slack AI agents guide.

slack-ruby-client: the Ruby SDK, its latest release, and signature verification in Rails

slack-ruby-client is the Ruby gem for the Slack Web API. The latest release is 3.3.0, published October 9, 2026, under MIT, and it needs Ruby 2.7 or later. That release added “AgentsSessions and AppsManagedPermissions endpoint modules for agents.sessions and apps.managedPermissions methods” and a session_status argument on chat.stopStream. The gem already had chat_startStream and assistant_threads_setStatus.

Its README is plain about scope: “This library lets you send messages to Slack via the Web API and facilitates integration with the Events API.” For a full bot it points elsewhere: “it’s much easier to start with slack-ruby-bot-server-events.” And for the lowest level, it says to “implement a web application using your favorite web framework, and use this library to call the Slack Web API, and to verify that events are coming from Slack.”

That last option is the Rails controller. The check is two lines:

slack_request = Slack::Events::Request.new(http_request)
slack_request.verify!

The signing secret defaults to ENV['SLACK_SIGNING_SECRET'], and signatures expire after 300 seconds by default. verify! raises MissingSigningSecret, InvalidSignature, or TimestampExpired, so a rescue in the controller turns each one into a 401. Version 3.3.0 also handles “non-rewindable Rack 3 request bodies when verifying Events API signatures.”

What about socket mode? The gem dropped the old RTM API in 3.0.0 (“Removed support for RTM APIs”). It does wrap apps.connections.open, which Slack describes as the call that returns the WebSocket URL, but the WebSocket client is up to you or another gem.

Socket mode in Ruby: slack-ruby-bot-server-events, bolt_rb and slack_socket_mode_bot

Three Ruby gems come up when agents search for a Ruby Bolt.

slack-ruby-bot-server-events is the framework slack-ruby-client recommends. It “makes it easy to handle Slack slash commands, interactive buttons and events,” over HTTP, with handlers like config.on :event, 'event_callback', 'link_shared'. It sits on slack-ruby-bot-server, whose README says “A database is required to store teams,” with MongoDB or ActiveRecord on PostgreSQL. So it’s a good fit for an app you distribute to many workspaces.

bolt_rb is “A bolt-js inspired framework for building Slack bots in Ruby using Socket Mode.” It has handler classes for events, commands, actions, and shortcuts, and an AssistantHandler whose set_status, set_title, and set_suggested_prompts “call the assistant.threads.* API methods for the current thread.” Handlers run on a pool of worker threads (5 by default), so a slow handler doesn’t block the socket. Thread context lives in process memory unless you plug in your own store.

slack_socket_mode_bot is “A simple wrapper library for Slack’s Socket Mode API.” You pass a bot token and an app token and get each envelope as a hash. Its README sums it up: “It allows you to write a Slack bot without exposing a public HTTP endpoint.”

All three are MIT. And all three stop at the Slack side: they receive the event and post the reply.

Slack AI agent apps in Go and Ruby: what runs after the ack

Every library above gives you events in and messages out. The agent is the part in between: call the model, run the tools, wait for a person to approve a risky call, keep the thread’s history, and stream the answer back. In Go or Ruby, that’s code you write and a worker you run, unless the loop is somewhere else.

With a hosted loop, the Slack handler acks, starts or continues an objective over HTTP, and returns. Cadenya runs the loop and sends a signed webhook for each event: each message, tool call, approval, and error. Here’s the Go receiver from Cadenya’s docs, trimmed:

client, err := cadenya.NewClient() // reads CADENYA_API_KEY and CADENYA_WEBHOOK_SECRET
if err != nil {
	log.Fatal(err)
}

http.HandleFunc("POST /webhooks/cadenya", func(w http.ResponseWriter, r *http.Request) {
	rawBody, err := io.ReadAll(r.Body)
	if err != nil {
		http.Error(w, "read failed", http.StatusBadRequest)
		return
	}
	event, err := client.Webhooks().Unwrap(rawBody, r.Header)
	if err != nil {
		http.Error(w, "bad signature", http.StatusUnauthorized)
		return
	}
	log.Printf("%s %s", event.Type, event.Data.Objective.ID)
	w.WriteHeader(http.StatusOK)
})

The Ruby version is the same shape: Cadenya::Client.new, then client.unwrap_webhook(raw_body, headers), with Cadenya::WebhookVerificationError on a bad signature. When the event is objective_event.assistant_message, the handler posts it to the Slack thread with slack-go or slack-ruby-client. When it’s objective_event.tool_approval_requested, the handler posts approve and deny buttons. The button flow itself is in the Slack AI agents guide.

What does Cadenya add to slack-go and slack-ruby-client?

slack-go/slack and slack-ruby-client connect a Go or Ruby app to Slack, and the agent behind it is still yours to write and run. Cadenya is that agent: the loop, the approvals, and the conversation state, called from Go or Ruby, with nothing to host. Here’s what that covers:

  1. Nothing else to run. No queue, no worker pool, no database for paused runs, and no workflow cluster. Your Slack handler acks, makes one API call, and Cadenya runs the loop after the ack, so a deploy of your Go or Ruby app never touches a running objective.
  2. SDKs for Go and Ruby, under Apache-2.0. The Go module go.cadenya.com/cadenya-go needs Go 1.22, and the cadenya gem needs Ruby 3.1. Both are at 1.9.0, with TypeScript and Python SDKs at the same version, and the TypeScript SDK has shipped 113 versions since April 2026. You host no server, so there’s no server license to check.
  3. No old code to keep alive. An objective keeps its variation’s configuration snapshot even when you edit the variation later. So you change a prompt or a tool without pinning or draining anything.
  4. A price in one line. Free for 1,000 loops a month with no card, $49 a month for 50,000, then $0.0015 a loop. A loop is one LLM request made during an objective, and there are no seats.
  5. The agent loop, already written. Cadenya calls the model, runs the tools, streams each reply, and compacts the context window when a thread gets long. Slack’s helpers set a status and stream text, and the loop that writes the text is the part Cadenya runs.
  6. Approvals answered from Slack buttons. Mark a tool as needing approval and Cadenya parks the loop on toolApprovalRequested, with several calls able to wait at once. Your handler posts the buttons, and the click calls approve or deny. A denial carries a memo that steers the agent (“Use the read-only lookup tool instead.”).
  7. One objective per Slack thread. Use the thread key as the objective’s external ID, which Cadenya uses to prevent duplicate objectives. When the objective is waiting, a Continue message picks it up again. Tag it with the workspace as a tenant and the person as a subject, and you can purge a workspace’s data when it uninstalls.
  8. Any model, on your own keys. The model is a setting on a variation, not a line of Go or Ruby. Use any model on OpenRouter or your own endpoint that speaks the OpenAI chat format, and pay your provider directly. Tools come from your OpenAPI 3 spec, an MCP server, or HTTP endpoints you define.

How webhooks work has the full Go and Ruby handlers, and the free plan needs no card.

No account yet? A coding agent can create a temporary workspace with cadenya workspaces create --temporary, run its first objectives there, and hand you a link to claim it, as auth.md explains. To create an account, sign up at app.cadenya.com/signup, then copy your API key from the API keys page at app.cadenya.com/account/apiKeys.

Grow wherever AI goes next.

Start shipping agents that are equipped to evolve.

A pine bonsai overlooking a mountain lake