swift-slack

2027.1.0-beta.3

Swift library for building Slack Apps powered by swift-openapi-generator with automating schema updates
ainame/swift-slack

What's New

2027.1.0-beta.3

2026-10-16T09:13:59Z

This beta adds typed Slack Code channel helpers, top-level message streaming and more resilient streaming and Socket Mode delivery. It builds on beta.1's Java-derived models and Block Kit additions and beta.2's agent APIs and streaming; APIs may still change before the January 2027 release.

Summary

  • Slack Code channels. Typed helpers configure properties, commands and HTML, diff, Block Kit, canvas and pull-request views. The Codex agent demo uses persistent worktrees, restores Codex conversations, uploads files and publishes artifacts with scoped Git permissions and Slack approvals - #255
  • More resilient delivery. Streaming supports top-level messages, preserves buffered content on local cancellation, bounds request sizes and stops when Slack ends the session. Socket Mode reports connection errors and accepts larger events - #255

Warning

Upgrading from beta.2: BlockActionsPayload.team is now optional so organization-installed apps can handle button interactions with team: null. Use optional chaining or unwrap it before accessing workspace information - #255

Upgrading from earlier versions also requires the migration described in the beta.1 and beta.2 notes below and Migrating to Java-derived models.

Added

  • Added typed CodeChannel request values and helpers for properties, commands and HTML, diff, Block Kit, canvas and pull-request views, returning Slack warnings and throwing on unsuccessful responses - #255
  • streamMessage supports top-level replies by omitting threadTs, and StreamingMessage.SessionStopped lets apps abandon buffered content and retries when Slack ends the session - #255

Fixed

  • BREAKING: Accepted team: null in Block Kit button interactions from organization-installed apps, allowing approval and other action handlers to run. BlockActionsPayload.team is now optional; use optional chaining or unwrap it before accessing workspace information - #255
  • Reported Slack's Socket Mode connection error instead of hiding it behind a missing-URL error, restored bot authentication after failed connection requests, and accepted Socket Mode frames up to 1 MiB instead of rejecting large events at 16 KiB - #255
  • Cancelled cooperative Sendable streaming inputs immediately on delivery failure, allowing apps to stop idle producers and pending questions - #255
  • Preserved unsent streaming content and closing blocks when local cancellation occurs during batching or a rate-limit delay, and bounded aggregate markdown and blocks per streaming request, including final flushes - #255

Maintenance

  • The Codex agent demo creates and reuses Code channels, publishes artifacts and diffs, uploads worktree files into the current channel with image references for Block Kit views, and shares archive summaries with linked origin threads. Persistent Git worktrees and topic branches now restore the same checkout and Codex conversation after restart, validate recovery state, and show repository, branch and checkout context. Scoped Git permissions permit topic commits, with Slack approvals for additional permissions; old independent clones are preserved with migration and cleanup guidance. The demo also restores conversation context, avoids repeated handoffs after naming/setup failures, deduplicates events, interrupts Codex directly on channel-wide Stop even during blocked output, and clears processing status after cleanup while preserving archived sessions - #255

swift-slack

swift-slack logo

Build Slack apps in Swift.
Typed Web API, Bolt-style routing, and a SwiftUI-style Block Kit DSL.

Swift 6.2+ Platforms: macOS | Linux GitHub Release Build Status Documentation MIT License

Get started · Examples · Documentation · Releases

Tip

2027.1.0-beta.3 is available for testing ahead of the January 2027 release. Changes from 2026.x include:

  • Web API response and event models generated from upstream java-slack-sdk, with decoding checked against its recorded payloads.
  • Additional Block Kit blocks and elements, including cards, carousels and alerts.
  • Agent conversation APIs and events, plus typed Slack Code channel helpers.
  • AsyncSequence message streaming into threads and Code channels, demonstrated in the Codex agent demo.

Beta.3 adds Code channel support and streaming and Socket Mode fixes. See the changelog for details.

APIs may still change. SwiftPM does not select the beta from a 2026.x requirement:

.package(url: "https://github.com/ainame/swift-slack.git", from: "2027.1.0-beta.3")

Existing apps should read Migrating to Java-derived models and the changelog for breaking changes. When upgrading from beta.2, note that BlockActionsPayload.team is now optional.

import SlackKit

let router = Router()

// Reply when someone mentions your app
router.onEvent(AppMentionEvent.self) { context, _, event in
    guard let channel = event.channel, let user = event.user else { return }
    try await context.say(text: "Hi <@\(user)>! 👋", channel: channel)
}

// Handle a slash command
router.onSlashCommand("/echo") { context, payload in
    try await context.ack()
    try await context.say(text: "Echo: \(payload.text)", channel: payload.channelId)
}

let app = SlackApp(
    configuration: .init(appToken: appToken, token: token),
    router: router,
    mode: .socketMode() // no public URL needed
)

try await app.run()

Features

Use as much of the stack as you need:

  • SlackClient: a standalone Web API client for scripts, CLIs, and CI jobs. No app runtime required.
  • SlackKit: a Bolt-style app framework for interactive apps, with routing, acknowledgements, Socket Mode, and HTTP. It includes the Web API client.

Highlights:

  • Over 260 typed Web API methods. Call chat.postMessage, views.open, conversations.history, and more with Swift request and response models.
  • Over 90 typed Events API payloads. Register router.onEvent(AppMentionEvent.self) and receive a decoded struct, not a JSON dictionary.
  • Socket Mode or HTTP. Connect over WebSocket without a public endpoint, or receive signed HTTP requests in production.
  • SwiftUI-style Block Kit DSL. Compose messages, modals, and App Home tabs from reusable Swift views.
  • Swift 6 concurrency. async/await handlers, Sendable types, and swift-service-lifecycle integration.
  • macOS and Linux. CI runs the test suite on Linux, so the same app deploys to servers and containers.

The Web API client is generated with swift-openapi-generator, so it works with any transport from that ecosystem, such as AsyncHTTPClient or URLSession.

Get started

Build a bot that replies to /echo using Socket Mode, without a public HTTP endpoint. Requires Swift 6.2+ and macOS 14+ or Linux, plus a Slack workspace where you can install apps.

Only need Web API calls? Jump to Use the Web API client.

1. Create your Slack app

In Slack app settings:

  1. Create an app and enable Socket Mode.
  2. Under Basic Information, create an app-level token with the connections:write scope.
  3. Under OAuth & Permissions, add the bot scopes commands and chat:write.
  4. Under Slash Commands, create /echo with a short description and a usage hint such as [message].
  5. Install the app to your workspace and copy its Bot User OAuth Token.

2. Create a Swift package

mkdir EchoBot
cd EchoBot
mkdir -p Sources/EchoBot

Save this as Package.swift:

// swift-tools-version: 6.2
import PackageDescription

let package = Package(
    name: "EchoBot",
    platforms: [.macOS(.v14)],
    dependencies: [
        .package(
            url: "https://github.com/ainame/swift-slack.git",
            from: "2027.1.0-beta.3"
        )
    ],
    targets: [
        .executableTarget(
            name: "EchoBot",
            dependencies: [
                .product(name: "SlackKit", package: "swift-slack")
            ]
        )
    ]
)

Save this as Sources/EchoBot/main.swift:

import Foundation
import SlackKit

let environment = ProcessInfo.processInfo.environment
guard let token = environment["SLACK_OAUTH_TOKEN"],
      let appToken = environment["SLACK_APP_LEVEL_TOKEN"] else {
    fatalError("Set SLACK_OAUTH_TOKEN and SLACK_APP_LEVEL_TOKEN")
}

let router = Router()

router.onSlashCommand("/echo") { context, payload in
    try await context.ack()
    try await context.say(text: "Echo: \(payload.text)", channel: payload.channelId)
}

let app = SlackApp(
    configuration: .init(appToken: appToken, token: token),
    router: router,
    mode: .socketMode()
)

try await app.run()

3. Run it

export SLACK_OAUTH_TOKEN="xoxb-your-bot-token"
export SLACK_APP_LEVEL_TOKEN="xapp-your-app-level-token"
swift run EchoBot

Invite the bot to a channel, then type /echo Hello from Swift there. The bot replies with Echo: Hello from Swift.

Coming from Bolt

If you have built Slack apps with Bolt for JavaScript or Python, the same concepts apply. A Router registers handlers in place of app, and each handler receives a context with ack(), say(), and the Web API client. Events are acknowledged automatically, as in Bolt.

Bolt for JavaScript swift-slack
app.event('app_mention', ...) router.onEvent(AppMentionEvent.self) { ... }
app.command('/echo', ...) router.onSlashCommand("/echo") { ... }
app.shortcut('callback_id', ...) router.onGlobalShortcut("callback_id") { ... }
app.action('action_id', ...) router.onAction("action_id") { ... }
app.view('callback_id', ...) router.onViewSubmission("callback_id") { ... }
app.options('action_id', ...) router.onBlockSuggestion("action_id") { ... }
await ack() / await say(...) try await context.ack() / try await context.say(...)
client.chat.postMessage({...}) context.client.chatPostMessage(body: .json(...))
socketMode: true mode: .socketMode()

Examples

Build Explore
Translate messages using flag reactions or shortcuts DeepL translator
Compose interactive messages, modals, and an App Home Block Kit DSL app
Reply to slash commands publicly or privately Echo bot
Handle typed Slack events and interactions Router example
Load external select menu options as the user types External select

Browse all examples for more patterns.

Build reusable Block Kit views

Add the SlackBlockKitDSL product to your target to compose messages and modals with result builders:

.product(name: "SlackBlockKitDSL", package: "swift-slack")
import SlackBlockKitDSL
import SlackKit

let approval = Section {
    Text("Ready to ship?").type(.mrkdwn)
}
.accessory(
    Button("Approve").actionId("approve").style(.primary)
)

struct WelcomeModal: SlackModalView {
    var title: TextObject { "Welcome" }
    var submit: TextObject? { "Continue" }

    var blocks: [Block] {
        Header { Text("Getting Started") }
        Section { Text("Welcome to our app!") }
        Input {
            PlainTextInput()
                .actionId("name_field")
                .placeholder("Enter your name")
        } label: {
            Text("Your Name")
        }
    }
}

Prefer constructing models directly? Use SlackBlockKit. See the Block Kit DSL guide for both styles.

Use the Web API client

Use SlackClient for direct API access. Add the AsyncHTTPClient transport package to your dependencies and its OpenAPIAsyncHTTPClient product alongside SlackClient in your target. Other transports from the Swift OpenAPI ecosystem also work.

import OpenAPIAsyncHTTPClient
import SlackClient

let slack = Slack(
    transport: AsyncHTTPClientTransport(),
    configuration: .init(token: token)
)

try await slack.client.chatPostMessage(
    body: .json(.init(
        channel: "#general",
        text: "Hello from Swift!"
    ))
)

See the Web API example for token configuration and a complete entry point.

Configure your app

The default package traits include the Web API, events, and Socket Mode. For smaller builds, select only the traits you need:

.package(
    url: "https://github.com/ainame/swift-slack.git",
    from: "2027.1.0-beta.3",
    traits: ["SocketMode", "Events", "WebAPI_Chat", "WebAPI_Views"]
)

SocketMode also enables WebAPI_Apps. For HTTP apps, enable HummingbirdHTTPAdapter and pass a HummingbirdAdapter to SlackApp using mode: .http(adapter). You can also implement HTTPServerAdapter for another server framework.

Events API handlers are acknowledged automatically. Slash commands, block actions, shortcuts, and view handlers must call context.ack(), as in the quickstart.

Contributing

Issues and pull requests are welcome. If a Web API method or event is missing or decodes incorrectly, open an issue with the payload you received.

To work on the SDK itself, use the Swift and Ruby versions in .swift-version and .ruby-version, plus a C compiler for the tree-sitter Java grammar. The development toolchain currently uses Swift 6.4; the package manifest's minimum is Swift 6.2.

git clone --recursive https://github.com/ainame/swift-slack.git
cd swift-slack
bundle install
make generate
swift test

Run make update when intentionally advancing the upstream reference data. See AGENTS.md for the source layout, generator workflow, and contribution checks.

For an agent-reviewed upstream update, invoke $slack-upstream-sync using the repository's sync skill. It reviews both vendor deltas, checks generated and handwritten models, and prepares a PR. The upstream record distinguishes vendor pins from reviewed coverage. The same Make targets remain available for manual updates; make generate alone regenerates from the currently checked-out vendor snapshots.

Scheduled Codex runs require full access, authenticated Git/GitHub access, and an isolated worktree based on current origin/main. Keep the computer and app running. Test the skill manually before enabling the schedule. GitHub Actions continues to test PRs; the Schema Update workflow is a manual fallback and should not run while an agent sync is running or awaiting review.

Web API request parameters come from slack-ruby/slack-api-ref. Response and event models are translated from the model classes of Slack's Java SDK and generated with swift-openapi-generator. Properties other than ok on responses and _type on events are optional, because Slack omits fields depending on the method, the object, and the workspace. Every generated method and event is checked against the Java SDK's recorded payloads (make check-fixtures).

License

MIT. See LICENSE and THIRD_PARTY_NOTICES.md for upstream attribution.

This is an unofficial, community-maintained project, not affiliated with Slack Technologies, LLC.

Description

  • Swift Tools 6.2.0
View More Packages from this Author

Dependencies

Last updated: Sun Oct 25 2026 23:16:56 GMT-0900 (Hawaii-Aleutian Daylight Time)