go-notificationgo-notification
Channels/Chat

Slack

Post notifications to Slack channels via Incoming Webhooks or the chat.postMessage API.

Two ways to send

  • Incoming Webhooks — one URL, posts to one channel. Simplest to set up.
  • Bot token (chat.postMessage) — one token, can post to many channels (if invited). Needed for DMs, threads, updates.

Both are supported.

Option A — Incoming Webhook

  1. Go to https://api.slack.com/appsCreate New App → pick a workspace.
  2. Enable Incoming Webhooks.
  3. Add New Webhook to Workspace, pick a channel.
  4. Copy the webhook URL.
main.go
import "github.com/gopackx/go-notification/channel/chat/slack"

notifier.RegisterChannel(slack.New(slack.Config{
    Name:       "slack",
    WebhookURL: os.Getenv("SLACK_WEBHOOK_URL"),
}))

Option B — Bot token

  1. In the same app settings, enable Bots.
  2. Add OAuth scopes: chat:write, chat:write.public.
  3. Install the app to your workspace and copy the Bot User OAuth Token (starts with xoxb-).
  4. Invite the bot into any channel it should post to (/invite @YourBot).
main.go
notifier.RegisterChannel(slack.New(slack.Config{
    Name:           "slack",
    BotToken:       os.Getenv("SLACK_BOT_TOKEN"),
    DefaultChannel: "#alerts",
}))

Sending

main.go
import "github.com/gopackx/go-notification/channel/chat"

func (n DeployFailed) Via(u notification.Notifiable) []string {
    return []string{"slack"}
}

func (n DeployFailed) ToChat(u notification.Notifiable) *chat.Message {
    return chat.NewMessage().
        SetText("Deploy failed: " + n.Service).
        AddSlackAttachment(chat.SlackAttachment{
            Color: "danger",
            Fields: []chat.SlackField{
                {Title: "Commit", Value: n.Commit, Short: true},
                {Title: "Actor",  Value: n.Actor,  Short: true},
            },
        })
}

For routing per recipient (e.g. DM a specific user), return the user ID or channel ID from RouteNotificationFor("slack"):

main.go
func (u User) RouteNotificationFor(channel string) string {
    if channel == "slack" {
        return u.SlackUserID // "U01ABCD..." for DMs, or "#channel-name"
    }
    return ""
}

Configuration reference

A single slack.Config covers both modes: set WebhookURL for webhook mode, or BotToken for chat.postMessage API mode.

FieldTypeRequiredDescription
WebhookURLstringyes*Incoming webhook URL from the Slack app settings (webhook mode).
BotTokenstringyes*Bot User OAuth Token (xoxb-...) for API mode.
DefaultChannelstringnoFallback channel if RouteNotificationFor returns empty.
NamestringnoChannel name used by Via(). Defaults to "chat".
Timeouttime.DurationnoHTTP timeout per send. Default: 30s.

* Provide either WebhookURL (webhook mode) or BotToken (API mode).

Troubleshooting

  • channel_not_found — bot isn't invited, or channel ID is wrong. Invite with /invite @YourBot.
  • not_allowed_token_type — you passed a user token (xoxp-) where a bot token (xoxb-) was expected.
  • Webhook returns 200 but nothing appears — webhook is for a different workspace or the channel was archived.