Skip to content

Repository files navigation

SlackKit

SlackKit Logo

CIVersionLicensePlatformSwiftDependencies

Swift package for sending messages to Slack via Incoming Webhooks with full support for Block Kit.

Also check out MattermostKit - A companion package for sending messages to Mattermost with Slack-compatible attachments.

Features

  • Modern Swift API - Built with Swift 6, async/await, and strict concurrency
  • Type-Safe - Full Codable support with compile-time safety
  • Block Kit - Complete support for Slack's Block Kit API
  • Flexible - Send simple text messages or rich interactive messages

Requirements

  • macOS 12.0+
  • iOS 15.0+
  • tvOS 15.0+
  • watchOS 8.0+
  • Swift 6.0+

Installation

Swift Package Manager

Add SlackKit to your Package.swift file:

dependencies:[.package(url:"https://github.com/diegotl/SlackKit.git", from:"1.0.0")]

Or add it directly in Xcode:

  1. File → Add Package Dependencies
  2. Enter the repository URL
  3. Select the version rule

Quick Start

import SlackKit
// Create a webhook client
letclient=trySlackWebhookClient.create(
webhookURLString:"https://hooks.slack.com/services/YOUR/WEBHOOK/URL")
// Send a simple message
tryawait client.send(Message(text:"Hello, Slack!"))

Convenience Builder API

SlackKit includes a builder API for cleaner, more readable message construction:

// Clean, declarative syntax
letmessage=Message{Header("Deployment Complete!")Section("Build *#123* was deployed to *production*")Divider()SectionBlock(
fields:[.markdown("*Environment:*\nProduction"),.markdown("*Version:*\nv2.4.1")])}tryawait client.send(message)

Usage

Simple Text Message

letmessage=Message(text:"Deployment completed successfully!")tryawait client.send(message)

Message with Blocks

letmessage=Message{Header("Deployment Complete!")Section(markdown:"Build *#123* was deployed to *production*")Divider()Section{Field.markdown("*Environment:*\nProduction")Field.markdown("*Version:*\nv2.4.1")Field.markdown("*Duration:*\n5m 32s")Field.markdown("*Status:*\n:white_check_mark: Success")}}tryawait client.send(message)

With custom username and icon:

letmessage=Message(
username:"DeployBot",
iconEmoji:":rocket:"){Header("Deployment Complete!")Section("Build *#123* was deployed to *production*")Divider()}tryawait client.send(message)

Message with Actions

letmessage=Message(text:"Approval required for production deployment"){Section("Deploy to production?")Actions{ButtonElement(text:.plainText("Approve"), style:.primary, value:"approve")ButtonElement(text:.plainText("Reject"), style:.danger, value:"reject")}}tryawait client.send(message)

Message with Attachments (Legacy)

letmessage=Message(
text:"Build results",
attachments:[Attachment(
color:"good",
title:"Build #123",
text:"Succeeded in 5m 32s",
fields:[AttachmentField(title:"Branch", value:"main", short:true),AttachmentField(title:"Commit", value:"abc123", short:true)])])tryawait client.send(message)

Threaded Message

letmessage=Message(
text:"This is a threaded reply",
threadTimestamp:"1234567890.123456")tryawait client.send(message)

Block Types

Section Block

Text sections with optional fields:

Section("Some *formatted* text")
// Or with markdown
Section(markdown:"Some *formatted* text")

With fields using the result builder:

Section{Field.markdown("*Field 1*\nValue 1")Field.plainText("Field 2")}

Header Block

Large header text:

Header("Important Announcement")

Divider Block

Horizontal line divider:

Divider()

Image Block

Display an image:

Image(url:"https://example.com/image.png", altText:"An example image")

Actions Block

Interactive buttons:

Actions{ButtonElement(text:.plainText("Click Me"), actionID:"button_1", value:"button_value", style:.primary)}

The builder also supports conditionals and loops:

Actions{ButtonElement(text:.plainText("Approve"), actionID:"approve", value:"yes")if needsReview {ButtonElement(text:.plainText("Request Review"), actionID:"review", value:"review")}foroptionin options {ButtonElement(text:.plainText(option), actionID:"opt_\(option)", value: option)}}

Context Block

Contextual information with text and images:

// Simple text context
Context("Created by @john","2 minutes ago")
// Or with elements using the builder
Context{TextContextElement(text:"Created by @john")ImageContextElement(imageURL:"https://example.com/avatar.png", altText:"Avatar")}

Input Block (Modals)

Input blocks for collecting user input in modals:

Input(
label:"Task description",
element:PlainTextInputElement(placeholder:"Enter task details...", multiline:true))

Interactive Elements

Button

ButtonElement(
text:.plainText("Click Me"),
actionID:"button_1",
value:"button_value",
style:.primary
)

Select Menu

StaticSelectElement(placeholder:.plainText("Choose an option")){Option(text:.plainText("Option 1"), value:"opt1")Option(text:.plainText("Option 2"), value:"opt2")}

Multi-Select Menu

MultiStaticSelectElement(placeholder:.plainText("Select options"), maxSelectedItems:3){Option(text:.plainText("Option 1"), value:"opt1")Option(text:.plainText("Option 2"), value:"opt2")}

Date Picker

DatePickerElement(
actionID:"date_picker_1",
placeholder:.plainText("Select a date"))

Users Select

UsersSelectElement(
placeholder:.plainText("Select a user"),
initialUser:"U1234567890")

Conversations Select

ConversationsSelectElement(
placeholder:.plainText("Select a conversation"),
filter:ConversationFilter(
include:[.public,.private],
excludeBotUsers:true))

Text Objects

Plain Text

TextObject.plainText("Simple text", emoji:true)

Markdown

TextObject.markdown("*Bold* and `code`")

Error Handling

do{tryawait client.send(message)}catchSlackError.invalidURL(let url){print("Invalid URL: \(url)")}catchSlackError.invalidResponse(let code,let body){print("HTTP \(code): \(body ??"No body")")}catchSlackError.rateLimitExceeded(let retryAfter){print("Rate limited. Retry after \(retryAfter) seconds")}catchSlackError.encodingError(let error){print("Failed to encode message: \(error)")}catchSlackError.networkError(let error){print("Network error: \(error)")}

Contributing

Contributions are welcome! Please feel free to submit a Pull Request.

License

This project is licensed under the MIT License - see the LICENSE file for details.

Acknowledgments

Resources

About

Send beautiful Slack messages from Swift. Webhooks, Block Kit, and async/await.

Resources

Stars

4 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages