weave
module · Comms & Incident

Slack

Comprehensive Slack control plane — channels, channel members, users, user-groups + memberships, messaging (post / update / delete / react / pin), files, scheduled messages, bots, and incident-channel inventory. Snapshot/diff/apply round-trip for the operator surface.

Namespace: weave slack Env: SLACK_BOT_TOKEN
39
Commands
6
State kinds
Comms & Incident
Category
1
API docs

Setup

Configure credentials via environment variables. We recommend sourcing them through 1Password or your secrets manager rather than committing them to the shell rc.

Official API reference

weave commands for this module are checked against the vendor's published API.

Variable Description Status
SLACK_BOT_TOKENRequired for authentication.required
SLACK_USER_TOKENUser token (xoxp-…) — falls back when SLACK_BOT_TOKEN can't reach an endpoint (some files / admin scopes)optional

Sanity-check the wiring:

weave secrets check
weave slack --help
weave doctor   # reports SLACK_BOT_TOKEN status

Capabilities

What this module can do, by entity and verb. means a working CLI surface; · means not (yet) wired.

Entity findlistshowdosnapshotdiffapply
bot······
channel
channel-member···
emoji······
emoji-meta·····
file·····
incident······
message······
scheduled-message······
user·····
user-group·
user-group-channels····
user-group-members···

Commands

Every registered CLI command, grouped by verb. Each example uses placeholder arguments — substitute real values for your environment.

find (3)

find channel

read

Find a channel by name.

weave slack find channel <name>

find user

read

Find a Slack user by email or user_id.

weave slack find user <identifier>

find user-group

read

Find a user-group by handle.

weave slack find user-group <handle>

list (9)

list bots

read

List bot apps installed in the workspace.

weave slack list bots <arg>

list channel-members

read

List members of a channel.

weave slack list channel-members <arg>

list channels

read

List channels (public + private, paginated).

weave slack list channels <arg>

list emoji

read

List custom emoji on the workspace.

weave slack list emoji <arg>

list files

read

List uploaded files (paginated; filterable by channel/user).

weave slack list files <arg>

list incidents

read

List currently-open incident channels (#incident-*).

weave slack list incidents <arg>

list scheduled-messages

read

List messages scheduled for future delivery.

weave slack list scheduled-messages <arg>

list user-groups

read

List user-groups in the workspace.

weave slack list user-groups <arg>

list users

read

List workspace users (paginated).

weave slack list users <arg>

show (2)

show channel

read

Show full detail for a channel.

weave slack show channel <channel>

show user-group-members

read

Show member IDs of a user-group.

weave slack show user-group-members <handle-or-id>

do (24)

do add-to-usergroup

write

Replace a user-group's membership (Slack's API is full-replace).

weave slack do add-to-usergroup <handle-or-id>

do archive-channel

write

Archive a channel (irreversible-ish; admins can unarchive).

weave slack do archive-channel <channel>

do create-channel

write

Create a channel (public or private).

weave slack do create-channel <name>

do create-user-group

write

Create a new user-group (handle + name).

weave slack do create-user-group <handle>

do delete-file

write

Delete a file by id.

weave slack do delete-file <file-id>

do delete-message

write

Delete a message by ts.

weave slack do delete-message <arg>

do disable-user-group

write

Disable a user-group (members keep id-only assignments).

weave slack do disable-user-group <handle-or-id>

do enable-user-group

write

Re-enable a previously-disabled user-group.

weave slack do enable-user-group <handle-or-id>

do escalate-channel

write

Post a structured incident escalation banner to a channel.

weave slack do escalate-channel <channel>

do invite

write

Invite a user to a channel.

weave slack do invite <arg>

do kick

write

Kick a user from a channel.

weave slack do kick <arg>

do pin

write

Pin a message to the channel.

weave slack do pin <arg>

do post-ephemeral

write

Post an ephemeral message only one user sees.

weave slack do post-ephemeral <arg>

do post-message

write

Post a message to a channel.

weave slack do post-message <arg>

do react

write

Add a reaction to a message.

weave slack do react <arg>

do remove-from-usergroup

write

Remove a user-group's membership entirely (resolves to setting users=).

weave slack do remove-from-usergroup <handle-or-id>

do rename-channel

write

Rename a channel.

weave slack do rename-channel <channel>

do set-purpose

write

Set a channel's purpose.

weave slack do set-purpose <channel>

do set-topic

write

Set a channel's topic.

weave slack do set-topic <channel>

do unarchive-channel

write

Unarchive a previously-archived channel.

weave slack do unarchive-channel <channel>

do unpin

write

Unpin a message from the channel.

weave slack do unpin <arg>

do unreact

write

Remove a reaction from a message.

weave slack do unreact <arg>

do update-message

write

Update a previously-posted message by ts.

weave slack do update-message <arg>

do upload-file

write

Upload a file to a channel (uses files.getUploadURLExternal v2 flow).

weave slack do upload-file <path>

watch (1)

watch channel

write

Tail new messages on a channel by polling conversations.history.

weave slack watch channel <channel>
snapshot / diff / apply are generated automatically from the State Kinds declared on this module — see the State kinds section below for per-kind details. Workflow: snapshot → edit YAML → diffapply --yes (or confirm interactively; apply --dry-run previews the same diff).

State kinds

Resources this module can snapshot and diff; apply where the kind supports live writes (see Round-trip per kind). Always run diff before apply; use --yes in automation after review. Files live under .weave-state/slack/.

channels

snapshot diff apply

Every public + private channel in the workspace (rename / topic / purpose / archive). Create/delete are kept as imperative `do` verbs.

Scope
Round-trip
Full round-trip — snapshot, diff, apply.

State file skeleton

module: slack
kind: channels
items:
  - # <fields specific to this kind — see snapshot output>

channel-members

snapshot diff apply

Membership of a single channel (apply invite/kick).

Scope
channel
Round-trip
Full round-trip — snapshot, diff, apply.

State file skeleton

module: slack
kind: channel-members
channel: <value>
items:
  - # <fields specific to this kind — see snapshot output>

user-groups

snapshot diff apply

Every user-group: handle, name, description, default channels. Apply creates and updates; disable uses the `do disable-user-group` verb.

Scope
Round-trip
Full round-trip — snapshot, diff, apply.

State file skeleton

module: slack
kind: user-groups
items:
  - # <fields specific to this kind — see snapshot output>

user-group-members

snapshot diff apply

Members of one user-group (Slack's API is full-replace; weave materializes the desired set and PUTs it once).

Scope
user_group
Round-trip
Full round-trip — snapshot, diff, apply.

State file skeleton

module: slack
kind: user-group-members
user_group: <value>
items:
  - # <fields specific to this kind — see snapshot output>

user-group-channels

snapshot diff apply

Default channels announced to a user-group (full apply).

Scope
user_group
Round-trip
Full round-trip — snapshot, diff, apply.

State file skeleton

module: slack
kind: user-group-channels
user_group: <value>
items:
  - # <fields specific to this kind — see snapshot output>

emoji-meta

snapshot diff apply

Custom emoji NAMES (snapshot + diff only — add/remove API requires admin-scope user tokens that weave does not request).

Scope
Round-trip
Snapshot + diff (apply not wired).

State file skeleton

module: slack
kind: emoji-meta
items:
  - # <fields specific to this kind — see snapshot output>

Workflows

End-to-end recipes from operators who already run this module in production. Copy, adapt, and put under change-control.

Onboard a new team to a project channel

Create the channel, invite users, set the topic — one transaction.

weave slack do create-channel platform-alpha --yes
weave slack do set-topic    #platform-alpha --topic 'Alpha rollout coordination' --yes
weave slack do set-purpose  #platform-alpha --purpose 'Cross-functional alpha launch channel' --yes
weave slack do invite       --channel #platform-alpha --user U01ALICE --yes
weave slack do invite       --channel #platform-alpha --user U01BOB   --yes

Lockdown a compromised channel

Capture the membership for the postmortem, then archive.

weave slack list channel-members --channel #leaky-channel
weave slack snapshot channel-members --channel #leaky-channel
git add .weave-state/slack && git commit -m 'pre-archive snapshot'
weave slack do archive-channel #leaky-channel --yes

Audit user-groups quarterly

Snapshot every user-group and its membership; diff next quarter.

weave slack snapshot user-groups
weave slack list user-groups --json | jq -r '.[].handle' \
  | xargs -I{} weave slack snapshot user-group-members --user-group {}
git add .weave-state/slack && git commit -m 'user-group audit Q1'
# next quarter:
weave slack diff user-groups
weave slack diff user-group-members --user-group platform-oncall

Roll out a comms freeze

List every active channel, then broadcast a freeze notice with per-channel confirmation.

weave slack list channels --no-archived --json | jq -r '.[].id' > /tmp/channels
while read cid; do
  weave slack do post-message --channel $cid \
    --text ':snowflake: Comms freeze: no production changes until 17:00 UTC.' --yes
done < /tmp/channels

Tail an active incident channel

Stream real-time messages while you triage; Ctrl-C to stop.

weave slack list incidents
weave slack watch channel #incident-2026-05-16 --interval 3

Terraform parity

For each Terraform resource in the canonical provider, here's the equivalent live-API verb in weave. Use this as a migration cheat-sheet, not a 1:1 contract — weave deliberately stays in the live-state lane, not the desired-state lane.

Terraform resource weave equivalent
slack_conversationweave slack list/find/show channel + do create-channel/archive-channel/unarchive-channel/rename-channel/set-topic/set-purpose / snapshot channels
slack_conversation_membersweave slack list channel-members / do invite / do kick / snapshot channel-members
slack_user_groupweave slack list/find user-group / do create-user-group / do disable-user-group / do enable-user-group / snapshot user-groups
slack_usergroup_membersweave slack show user-group-members / do add-to-usergroup / snapshot user-group-members
Slack's API is full-replace; weave materializes the desired set on apply.
slack_usergroup_channelsweave slack snapshot user-group-channels
(chat.postMessage / chat.postEphemeral)weave slack do post-message / do post-ephemeral
No TF resource — these are operator verbs.
(chat.update / chat.delete)weave slack do update-message / do delete-message
No TF resource — these are operator verbs.
(reactions.add / reactions.remove)weave slack do react / do unreact
No TF resource — these are operator verbs.
(pins.add / pins.remove)weave slack do pin / do unpin
No TF resource — these are operator verbs.
(files.list / files.upload / files.delete)weave slack list files / do upload-file / do delete-file
Upload uses Slack's modern files.getUploadURLExternal v2 flow.
(chat.scheduledMessages.list)weave slack list scheduled-messages
(emoji.list / emoji.add / emoji.remove)weave slack list emoji / snapshot emoji-meta
Add/remove emoji require admin-scope user tokens — weave reads only.
(team.info / bot inventory)weave slack list bots / list incidents / watch channel
Operational verbs unique to weave — no Terraform equivalent.
(Enterprise Grid admin.* methods)Not exposed
Enterprise Grid scopes require workspace-org admin tokens; out of scope for weave.

Troubleshooting & source

Missing credentials

Run weave doctor — it reports which env vars (including SLACK_BOT_TOKEN) are set and which are blank.

Unexpected behaviour from a state apply

Re-run weave slack diff <kind> to confirm the controller's current state, then re-snapshot before the next apply. The driver always re-snapshots before diffing.