slack Documentation

Go library by @slack-go focused on go, golang. Includes documentation and AI agent context with 5.0k stars.

4,972 stars Go Go 10 files ยท ~14,796 tokens #go#golang#slack
RAW Doc

Technical Documentation: slack-go/slack

โ„น๏ธ Provenance: Multi-Tier Ingestion ยท CodeWiki Reference

Overview (`README.md`)

Slack API in Go [](https://pkg.go.dev/github.com/slack-go/slack) [](https://github.com/slack-go/slack/actions/workflows/test.yml)

You can chat with us on the #slack-go, #slack-go-ja Slack channel on the Gophers Slack.

This library supports most if not all of the api.slack.com REST
calls, as well as the Real-Time Messaging protocol over websocket, in
a fully managed way.

Project Status

There is currently no major version released.
Therefore, minor version releases may include backward incompatible changes.

See Releases for more information about the changes.

Go Versions supported

We support the same versions of Go as the officially supported Go versions (see Go
Release Policy
).

Installing

*go get*

bash
go get -u github.com/slack-go/slack

Example

Getting all groups

golang
import (
    "fmt"

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

func main() {
    api := slack.New("YOUR_TOKEN_HERE")
    // If you set debugging, it will log all requests to the console
    // Useful when encountering issues
    // slack.New("YOUR_TOKEN_HERE", slack.OptionDebug(true))
    groups, err := api.GetUserGroups(slack.GetUserGroupsOptionIncludeUsers(false))
    if err != nil {
        fmt.Printf("%s\n", err)
        return
    }
    for _, group := range groups {
        fmt.Printf("ID: %s, Name: %s\n", group.ID, group.Name)
    }
}

Getting User Information

golang
import (
    "fmt"

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

func main() {
    api := slack.New("YOUR_TOKEN_HERE")
    user, err := api.GetUserInfo("U023BECGF")
    if err != nil {
        fmt.Printf("%s\n", err)
        return
    }
    fmt.Printf("ID: %s, Fullname: %s, Email: %s\n", user.ID, user.Profile.RealName, user.Profile.Email)
}

HTTP retries

Retries are off by default. Use OptionRetry(n) for 429-only retries, or OptionRetryConfig(cfg) for full control (connection, 429, opt-in 5xx). With a custom client, pass retry options after OptionHTTPClient. See package slack doc for handler details.

golang
api := slack.New("YOUR_TOKEN_HERE", slack.OptionRetry(3))

Minimal Socket Mode usage:

See https://github.com/slack-go/slack/blob/master/examples/socketmode/socketmode.go

Minimal RTM usage:

As mentioned in https://api.slack.com/rtm - for most applications, Socket Mode is a better way to communicate with Slack.

See https://github.com/slack-go/slack/blob/master/examples/websocket/websocket.go

Minimal EventsAPI usage:

See https://github.com/slack-go/slack/blob/master/examples/eventsapi/events.go

Socketmode Event Handler (Experimental)

When using socket mode, dealing with an event can be pretty lengthy as it requires you to route the event to the right place.

Instead, you can use SocketmodeHandler much like you use an HTTP handler to register which event you would like to listen to and what callback function will process that event when it occurs.

See ./examples/socketmode_handler/socketmode_handler.go

Contributing

You are more than welcome to contribute to this project. Fork and
make a Pull Request, or create an Issue if you see any problem.

Before making any Pull Request please run the following:

text
make pr-prep

This will check/update code formatting, linting and then run all tests

License

BSD 2 Clause license


Overview (`examples/README.md`)

Slack Examples

This directory contains examples demonstrating how to use the slack-go library for various Slack API operations.

Development Guidelines

Environment Variables vs Command Line Arguments

When developing examples, follow these patterns for handling different types of data:

Environment Variables (Sensitive Data)

Use environment variables for sensitive information that should not be exposed in command history or process lists:

  • Tokens: SLACK_BOT_TOKEN, SLACK_APP_TOKEN, SLACK_USER_TOKEN
  • Secrets: SLACK_SIGNING_SECRET
  • URLs with credentials: webhook URLs, etc.

Pattern:

go
token := os.Getenv("SLACK_BOT_TOKEN")
if token == "" {
    fmt.Fprintf(os.Stderr, "SLACK_BOT_TOKEN environment variable is required\n")
    os.Exit(1)
}

// Optional: Validate token format
if !strings.HasPrefix(token, "xoxb-") {
    fmt.Fprintf(os.Stderr, "SLACK_BOT_TOKEN must be a bot token (xoxb-)\n")
    os.Exit(1)
}

Common environment variables:

  • SLACK_BOT_TOKEN - Bot user OAuth token (starts with xoxb-)
  • SLACK_APP_TOKEN - App-level token (starts with xapp-)
  • SLACK_USER_TOKEN - User OAuth token (starts with xoxp-)
  • SLACK_SIGNING_SECRET - For webhook signature verification

Command Line Arguments (Non-Sensitive Data)

Use command line flags for operational parameters that are safe to expose:

  • IDs: channel IDs, user IDs, team IDs
  • Configuration: timeouts, limits, modes
  • Options: boolean flags, enum values

Pattern:

go
import "flag"

var (
    channelID = flag.String("channel", "", "Channel ID (required)")
    userID    = flag.String("user", "", "User ID (required)")
    verbose   = flag.Bool("verbose", false, "Enable verbose logging")
)

func main() {
    flag.Parse()

    if *channelID == "" {
        fmt.Fprintf(os.Stderr, "Error: -channel flag is required\n")
        os.Exit(1)
    }

    if *userID == "" {
        fmt.Fprintf(os.Stderr, "Error: -user flag is required\n")
        os.Exit(1)
    }

    // Use the flags
    fmt.Printf("Operating on channel %s with user %s\n", *channelID, *userID)
}

Error Handling Standards

Environment variable errors:

  • Use fmt.Fprintf(os.Stderr, ...) for error output
  • Include clear variable name in error message
  • Exit with os.Exit(1) for missing required variables

Command line argument errors:

  • Use fmt.Fprintf(os.Stderr, ...) for error output
  • Include flag name in error message
  • Exit with os.Exit(1) for missing required flags

Security Considerations

  1. Never hardcode sensitive values in example code
  2. Think of validating required environment variables before using them
  3. Use token format validation when applicable (e.g., xoxb- prefix for bot tokens)
  4. Keep sensitive data out of command line arguments to prevent exposure in process lists

This pattern ensures consistent security practices across all examples and makes them easier to understand and use safely.


Overview (`slacktest/README.md`)

slacktest

This package was originally copied from https://github.com/lusis/slack-test for historical reasons.
It is currently in use with some modifications.

The license of this package is as follows.


Copyright 2018 @lusis

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.


Overview (`examples/block_element_fields/README.md`)

Verify interactive element fields

This example posts one test message and listens for interactions through Socket Mode. It tests eight fields on buttons, checkboxes, conversation multi-selects, and rich text inputs. It leaves the message in the channel for comparison between users.

Configure the app

  • Export SLACK_BOT_TOKEN (xoxb-, bot scope chat:write) and SLACK_APP_TOKEN (xapp-, app-level scope connections:write). The repository's .envrc can supply them.
  • Enable Socket Mode and Interactivity & Shortcuts. No request URL or event subscriptions are needed.
  • Install the app, then invite its bot to the test channel. Reinstall after changing scopes.
  • Stop other Socket Mode processes for the same app during this test, so they cannot receive its interactions.

These fields do not require an org-level user token or Enterprise Grid. The Slackbot prompt path requires Slackbot AI access for the person who clicks the button. Any app can send agent_prompt; it does not require the agent app manifest feature. Without that user access, Slack sends the normal interaction instead. See the button reference.

Run

From the repository root, use an existing test channel and your own user ID:

sh
go run ./examples/block_element_fields -channel C0123456789 -user U0123456789

The default -case all posts all message elements together. Keep the process running while you interact with them. Add -debug for library diagnostics. To isolate a rejection, rerun with -case button, -case agent, -case checkboxes, or -case modal. Each run posts one message; -user is only required for all, button, and checkboxes.

After Submit, the modal closes and the program prints the selected conversation and entered text in the terminal.

Check each field

Field Check in Slack
Button accessibility_label As the -user user, focus Visible test button with a screen reader. It should announce Verify the button accessibility label.
Button visible_to_user_ids The -user user should see Visible test button. A different member of the same channel should not see it. Click it and confirm a field_check_button action appears in the output.
Button agent_prompt Click Test Slackbot prompt. With Slackbot AI access, Slackbot should open with the test prompt. Without access, the output should show the field_check_agent fallback action. The fallback alone does not test the AI path.
Button agent_prompt_display On the resulting Slackbot message, check for Verify Block Kit prompt fields. Expand the message to inspect the full prompt.
Checkboxes visible_to_user_ids Only the -user user should see Visible test checkbox. Toggle it and confirm the field_check_checkboxes action. Compare with a second channel member.
Multi-select default_to_current_conversation While viewing the test channel, click Open input tests. The modal should already select that channel. Leave it unchanged, submit, and check includes launch channel=true.
Rich text input min_lines Open the modal and check that its empty editor shows two visible lines.
Rich text input max_lines Enter at least six lines. The editor should grow to four visible lines, then scroll. Submit and check that the output still contains all entered text. These fields set visible height, not a limit on submitted lines.

The multi-select behavior is documented in the conversation multi-select reference. The editor height behavior is documented in the rich text input reference.

Read the output

The program prints outgoing blocks, raw chat.postMessage and views.open response bodies, and Socket Mode envelopes before the library parses them. Tokens, response URLs, trigger IDs, and credential-bearing WebSocket URLs are redacted. No HTTP request headers are logged. Payloads still contain workspace IDs and content entered in the modal.

For each field Slack returns, Go preserved=true confirms that decoding and re-encoding retained the returned value. A decoding error or Go preserved=false stops the example with a nonzero exit status. If Slack omits a field, the example reports it as unverified. Values that Slack changes remain visible for comparison with the outgoing blocks; the example does not treat them as a Go decoding failure. Request acceptance alone does not prove retention or correct UI behavior. Complete the table above.

Paste back the per-field output, any response_metadata.messages errors, and the UI observations. Include whether the clicking user had Slackbot AI access. Press Ctrl-C when finished.


Overview (`examples/blocks/README.md`)

Block Examples

The examples provided replicate the template examples provided by slack. The template builder can be found at https://api.slack.com/tools/block-kit-builder.

Due to the nature how slack expects different components to be configured, building complex block using the provided functions can be very verbose, but allows for maximum flexibility.

The examples below should cover implementing most supported block elements.

For additional information on Blocks, see the Block Kit website.

Using examples with the Block Kit Builder website

When generating examples, they will be printed to the screen as a complete message that is meant to be sent back to slack as a direct response, or throuogh the ResponseURL provided. To test your examples in the Block Kit Builder, you must take the contents of the blocks property and paste the results into the builder.

For example, when printing a simple header, the output will be

text
{
    "replace_original": false,
    "delete_original": false,
    "blocks": [
        {
            "type": "section",
            "text": {
                "type": "plain_text",
                "text": "Example Header Text"
            }
        },
        {
            "type": "divider"
        }
    ]
}

To preview this block on the builder website, you should copy just the contents of the blocks:

text
[
    {
        "type": "section",
        "text": {
            "type": "plain_text",
            "text": "Example Header Text"
        }
    },
    {
        "type": "divider"
    }
]

Example 1 - Approval

The first example demonstrates usage of Sections, Fields and Action buttons. You can view the Approval Example on the block kit builder website. This example can be generated with the function named exampleOne.

Example 2 - Approval - With Images

The second example adds additional complexity by introducing images as accessories to main blocks of text. You can view this Approval Example with Images on the block kit builder website. This example can be generated with the function named exampleTwo.

Example 3 - Notifications

This example shows how to add actions to your block that will trigger an interactive message to your application. You can view the rendered example for Notifications on the block builder website. Refer to the function exampleThree for details on how this block can be generated.

Example 4 - Polls

The Polls example displays results and allows the end user to vote, displaying a count and images of recent voters. You can view the rendered Poll Example on the block kit builder website. Refer to the function named exampleFour for more information on generating this block type.

Example 5 - Search Results

This example introduces overflow elements, allowing you to populate a select style dropdown with fields. These fields can be static, loaded from an external source. You can view the rendered Search Results Example on the block kit builder website. Refer to the function named exampleFive for more information on generating this block.

Example 6 - Search Results with Options and Actions

Using a combination of overflow elements containing selectable options and actions, this examples allows you to prompt the user with multiple actions in a single response. You can view the rendered Search Results with Actions example on the block kit builder website. Refer to the function named exampleSix for more information on building this block.

Context Actions Example

This example demonstrates the context_actions block, which is designed for interactive feedback elements like thumbs up/down buttons and icon-based actions. This block type is particularly useful for AI-generated content where you want to collect user feedback.

The example shows two use cases:

  • Using feedback buttons combined with an icon button (delete action)
  • Using simple feedback buttons with accessibility labels

You can view the rendered example on the block kit builder site.

Refer to the function named contextActionsExample for more information. For additional
details on the context_actions block, see the Slack API documentation.


Overview (`examples/eventsapi/README.md`)

Events Example

This is a very simple example but should give you a glimpse of how to use the events API.

How to enable this

  1. Disable socket mode in the app if it's enabled: this will reveal the Request URL.

  2. Set up the events Request URL in a way that matches the endpoint in
    events.go.

    You can find this here.

  3. Set up the events you want to be subscribed to.

  4. Copy the bot token and signing secret and set up the environment variables (per code).

  5. Run the example:

    bash
    go run events.go

Overview (`examples/lists/README.md`)

Lists example

This program calls all 12 Slack Lists methods.
Each action runs against a real workspace. It prints the raw response before decoding,
then the relevant typed fields. Use -debug for Slack client logs.

Setup

  1. Use a paid Slack workspace with Lists enabled.
  2. In the app's OAuth & Permissions page, add lists:read and lists:write
    to the bot token scopes or user token scopes.
  3. Install or reinstall the app after changing scopes.
  4. Set SLACK_BOT_TOKEN to the installed app's bot token (xoxb-). Alternatively,
    set SLACK_USER_TOKEN to a user token (xoxp-). If both are set, the bot token wins.
  5. For an existing list, use a token whose acting user or bot can access that list.

These methods do not require an org token, Enterprise Grid, an agent app, event
subscriptions, Socket Mode, or interactivity configuration. The program calls the
Web API directly; no message or command in Slack is needed to trigger it.

Read and export actions need lists:read. Write actions need lists:write.
The update action also reads the item back, so it needs both scopes.
See Slack's create,
list items, and
export references.

Create and edit items

Run commands from the repository root. Create a list with a text column named
Task and a checkbox column named Done:

sh
go run ./examples/lists -action create -name 'slack-go Lists example'

The output gives the list ID and both column IDs. Replace F_LIST, Col_TASK,
and Col_DONE below with those values. Add an item:

sh
go run ./examples/lists -action add -list F_LIST -column Col_TASK -text 'Review the Lists API'

Replace Rec_ITEM with the returned item ID. Edit its text, check the checkbox,
then clear it. Each update reads the item back:

sh
go run ./examples/lists -action update -list F_LIST -item Rec_ITEM -column Col_TASK -text 'Review complete'
go run ./examples/lists -action update -list F_LIST -item Rec_ITEM -column Col_DONE -checked=true
go run ./examples/lists -action update -list F_LIST -item Rec_ITEM -column Col_DONE -checked=false

The decoded checkbox should change from true to false. Compare it with the
raw slackLists.items.info response. Open the list in Slack to check the text and
checkbox visually. With a bot token, use grant below to give yourself access.

Read and paginate

sh
go run ./examples/lists -action info -list F_LIST -item Rec_ITEM
go run ./examples/lists -action list -list F_LIST -limit 2
go run ./examples/lists -action list -list F_LIST -limit 2 -cursor 'RETURNED_CURSOR'
go run ./examples/lists -action list -list F_LIST -limit 2 -all

Add at least three items to check pagination with a page size of two. A nonempty
Next cursor means another page is available. -all follows cursors until Slack
returns an empty cursor. Add -archived to read archived items. The list action
also prints the list's column IDs, which is useful for an existing list.

Rename and share

sh
go run ./examples/lists -action rename -list F_LIST -name 'Reviewed tasks'
go run ./examples/lists -action grant -list F_LIST -user U_USER -access write
go run ./examples/lists -action grant -list F_LIST -channel C_CHANNEL -access read
go run ./examples/lists -action revoke -list F_LIST -channel C_CHANNEL

Use either -user or -channel; each accepts comma-separated IDs. Access levels
are read, write, and owner. owner transfers ownership to a user and requires
the current owner's token. See access rules.

Export

sh
go run ./examples/lists -action export -list F_LIST
go run ./examples/lists -action download -list F_LIST -job Le_JOB

Replace Le_JOB with the job ID from export. download prints the status and
download URL. If the job is not complete, run download again later.

For JSON exports, use the same format and inclusion flags on both calls:

sh
go run ./examples/lists -action export -list F_LIST -format json -threads -attachments
go run ./examples/lists -action download -list F_LIST -job Le_JOB -format json -threads -attachments

Add -archived to export to include archived items. The example returns the
download URL; it does not fetch the exported file.

Remove sample items

sh
go run ./examples/lists -action delete -list F_LIST -item Rec_ITEM
go run ./examples/lists -action delete-multiple -list F_LIST -items Rec_SECOND,Rec_THIRD

These actions delete the specified items. Remove the sample list itself in Slack.

Report results

Send the command, raw response, decoded output, and any Slack response messages
for a failed action. For a successful run, compare the IDs, cell values, and
pagination cursor in both outputs. Do not include tokens or private list contents.


Overview (`examples/manifests/README.md`)

Manifest examples

This example shows how to interact with the
new manifest endpoints. These endpoints require a special set
of tokens called configuration tokens. Refer to
the relevant documentation for how to create these tokens.

For examples on how to use configuration tokens, see the tokens example.

Usage info

The manifest endpoints allow you to configure your application programmatically instead of manually creating
a manifest.yaml file and uploading it on your Slack application's dashboard.

A manifest should follow a specific structure and has a handful of required fields. These are describe in
the manifest documentation, but Slack additionally returns very
informative error messages for malformed templates to help you pin down what the issue is. The library itself does not
attempt to perform any form of validation on your manifest.

Note that each configuration token may only be used once before being invalidated. Again refer to the tokens example
for more information.

Available methods

  • Slack.CreateManifest()
  • Slack.DeleteManifest()
  • Slack.ExportManifest()
  • Slack.UpdateManifest()

Example details

The example code here only shows how to update an application using a manifest. The other available methods are either
identical in usage or trivial to use, so no full example is provided for them.

The example doesn't rotate the configuration tokens after updating the manifest. You should almost always do this.
Your access token is invalidated after sending a request, and rotating your tokens will allow you to make another
request in the future. This example does not do this explicitly as it would just repeat the tokens example. For sake of
simplicity, it only focuses on the manifest part.


Overview (`examples/rich_text_fields/README.md`)

Rich-text field checks

This example tests each added rich-text field against a real Slack workspace. It posts one
message per field, prints the raw response before the library decodes it, and checks whether
the library preserves the returned fields. Use a channel intended for tests.

Setup

Export SLACK_BOT_TOKEN with a bot token (xoxb-) that has chat:write, and invite the bot
to the channel. The repository's .envrc can supply this variable. Reinstall the app after
changing scopes. Posting needs no Socket Mode, event subscriptions, agent app configuration,
Enterprise Grid organization, or paid plan. Some metadata may be generated by Slack or apply
only to particular features; API acceptance does not prove that Slack uses it.

Reading an existing message also needs the history scope for its conversation type:
channels:history, groups:history, im:history, or mpim:history. The bot must have access
to that conversation.

Post the checks

From the repository root, after loading .envrc:

sh
go run ./examples/rich_text_fields -channel C123 -user U123

This checks color and date styles, date timezone, channel and user from_llm, and the four
link flags (unsafe, from_llm, is_slack_url, truncated). Missing case-specific flags
produce a SKIP line. Each case can also run alone:

sh
go run ./examples/rich_text_fields -channel C123 -case date-timezone
go run ./examples/rich_text_fields -channel C123 -case channel-tab -tab TAB_ID
go run ./examples/rich_text_fields -channel C123 -case emoji-url \
  -emoji CUSTOM_EMOJI_NAME -emoji-url https://HOST/PATH/emoji.png
go run ./examples/rich_text_fields -channel C123 -case broadcast-style

Use an actual tab ID from the target channel for -tab. Use a custom emoji name and its public
asset URL for the emoji check. The emoji url field comes from Slack's
official Node types
and is intended for custom emoji shared across workspaces.

The broadcast case posts @here, which can notify active channel members. It is excluded from
-case all unless you add -allow-broadcast. To run every case:

sh
go run ./examples/rich_text_fields -channel C123 -user U123 -tab TAB_ID \
  -emoji CUSTOM_EMOJI_NAME -emoji-url https://HOST/PATH/emoji.png -allow-broadcast

Use -case list to list cases. Add -json to print the outgoing blocks without calling Slack,
or -debug for Slack client logs.

Read a real payload

If Slack rejects or removes a field on posting, inspect a message produced by the Slack feature
that uses it. The read action checks the selected message's top-level blocks:

sh
go run ./examples/rich_text_fields -action read \
  -url https://WORKSPACE.slack.com/archives/C123/p1720710212123456

Alternatively, pass -channel C123 -ts 1720710212.123456. This uses
conversations.history, so choose a channel message rather than a thread reply.

Interpret the output

  • ACCEPTED means chat.postMessage succeeded.
  • RETURNED ... present=true unchanged=true means Slack returned the value sent for that field.
  • RETURNED ... present=false means Slack omitted it. This does not prove a decoding bug.
  • DECODE ... preserved=true means the typed library retained the field Slack returned.
  • DECODE CHECK FAILED or preserved=false identifies a library decoding problem and produces
    a nonzero exit status. API failures also produce a nonzero status, after the other cases run.
  • SKIP means the case did not run. Supply the indicated flags to complete it.

Check the posted messages in Slack for visible styles, date formatting and tab navigation.
Metadata can have no visible effect. Paste back the case names, RETURNED and DECODE lines,
and any Slack errors with their response messages. Raw output can contain message content.

The field definitions are in Slack's element reference.


Overview (`examples/tokens/README.md`)

Tokens examples

The refresh token endpoint can be used to update
your configuration tokenset. These tokens may only be used **once
** before being invalidated, and are only valid for up to 12 hours.

Once a token has been used, or before it expires, you can use the RotateTokens() method to obtain a fresh set to use
for the next request. Depending on your use-case you may want to store these somewhere for a future run, so they are
only returned by the method call. If you wish to update the tokens inside the active Slack client, this can be done
using UpdateConfigTokens().


--- METRICS ---