@@ -67,6 +67,219 @@ Relay mode separates Slack ingress from the OpenClaw gateway. A trusted router o
6767
6868The relay URL must use ` wss:// ` unless it targets localhost. Treat the bearer token and router route table as part of the Slack authorization boundary: routed events enter the normal Slack message handler as authorized activations. A router-provided ` slack_identity ` in the websocket ` hello ` frame can set the default outbound username and icon; an explicit identity supplied by the caller still wins. The relay connection reconnects with the same bounded backoff timing as Socket Mode and clears the router-provided identity whenever it disconnects.
6969
70+ ### Enterprise Grid org-wide installs
71+
72+ One Slack account can receive messages from every workspace covered by an
73+ Enterprise Grid org-wide installation. Choose direct Socket Mode or HTTP
74+ Request URLs; relay mode is not supported for enterprise accounts. Both
75+ least-privilege manifests below enable only the V1 ` message ` and ` app_mention `
76+ event path, immediate replies, and listener-owned status reactions.
77+
78+ #### Socket Mode
79+
80+ ``` json
81+ {
82+ "display_information" : {
83+ "name" : " OpenClaw" ,
84+ "description" : " Slack connector for OpenClaw"
85+ },
86+ "features" : {
87+ "bot_user" : { "display_name" : " OpenClaw" , "always_online" : true }
88+ },
89+ "oauth_config" : {
90+ "scopes" : {
91+ "bot" : [
92+ " app_mentions:read" ,
93+ " channels:history" ,
94+ " channels:read" ,
95+ " chat:write" ,
96+ " files:read" ,
97+ " files:write" ,
98+ " groups:history" ,
99+ " groups:read" ,
100+ " im:history" ,
101+ " im:read" ,
102+ " mpim:history" ,
103+ " mpim:read" ,
104+ " reactions:write" ,
105+ " users:read"
106+ ]
107+ }
108+ },
109+ "settings" : {
110+ "org_deploy_enabled" : true ,
111+ "socket_mode_enabled" : true ,
112+ "event_subscriptions" : {
113+ "bot_events" : [
114+ " app_mention" ,
115+ " message.channels" ,
116+ " message.groups" ,
117+ " message.im" ,
118+ " message.mpim"
119+ ]
120+ }
121+ }
122+ }
123+ ```
124+
125+ Have an Enterprise Grid Org Admin or Org Owner approve the app, install it at
126+ the organization level, and choose the workspaces the installation covers.
127+ Confirm that the app is available in every intended workspace before starting
128+ OpenClaw. Generate an app-level token with ` connections:write ` for Socket Mode,
129+ then copy the bot token from the org installation. Configure the account that
130+ uses the org-installed bot token:
131+
132+ ``` json5
133+ {
134+ channels: {
135+ slack: {
136+ enabled: true ,
137+ mode: " socket" ,
138+ enterpriseOrgInstall: true ,
139+ appToken: { source: " env" , provider: " default" , id: " SLACK_APP_TOKEN" },
140+ botToken: { source: " env" , provider: " default" , id: " SLACK_BOT_TOKEN" },
141+ dmPolicy: " open" ,
142+ allowFrom: [" *" ],
143+ groupPolicy: " allowlist" ,
144+ channels: {
145+ C0123456789 : { requireMention: true },
146+ },
147+ },
148+ },
149+ }
150+ ```
151+
152+ #### HTTP Request URLs
153+
154+ Use HTTP mode when the Gateway has a public HTTPS endpoint and does not open a
155+ Socket Mode connection. Replace the example URL with the Gateway's public
156+ ` webhookPath ` URL (default ` /slack/events ` ):
157+
158+ ``` json
159+ {
160+ "display_information" : {
161+ "name" : " OpenClaw" ,
162+ "description" : " Slack connector for OpenClaw"
163+ },
164+ "features" : {
165+ "bot_user" : { "display_name" : " OpenClaw" , "always_online" : true }
166+ },
167+ "oauth_config" : {
168+ "scopes" : {
169+ "bot" : [
170+ " app_mentions:read" ,
171+ " channels:history" ,
172+ " channels:read" ,
173+ " chat:write" ,
174+ " files:read" ,
175+ " files:write" ,
176+ " groups:history" ,
177+ " groups:read" ,
178+ " im:history" ,
179+ " im:read" ,
180+ " mpim:history" ,
181+ " mpim:read" ,
182+ " reactions:write" ,
183+ " users:read"
184+ ]
185+ }
186+ },
187+ "settings" : {
188+ "org_deploy_enabled" : true ,
189+ "event_subscriptions" : {
190+ "request_url" : " https://gateway-host.example.com/slack/events" ,
191+ "bot_events" : [
192+ " app_mention" ,
193+ " message.channels" ,
194+ " message.groups" ,
195+ " message.im" ,
196+ " message.mpim"
197+ ]
198+ }
199+ }
200+ }
201+ ```
202+
203+ Have an Enterprise Grid Org Admin or Org Owner approve the app, install it at
204+ the organization level, and choose the workspaces the installation covers.
205+ After Slack verifies the Request URL, copy the org installation's bot token and
206+ the app's ** Basic Information -> App Credentials -> Signing Secret** . Configure
207+ the enterprise account with the same Request URL path:
208+
209+ ``` json5
210+ {
211+ channels: {
212+ slack: {
213+ enabled: true ,
214+ mode: " http" ,
215+ enterpriseOrgInstall: true ,
216+ botToken: { source: " env" , provider: " default" , id: " SLACK_BOT_TOKEN" },
217+ signingSecret: {
218+ source: " env" ,
219+ provider: " default" ,
220+ id: " SLACK_SIGNING_SECRET" ,
221+ },
222+ webhookPath: " /slack/events" ,
223+ dmPolicy: " open" ,
224+ allowFrom: [" *" ],
225+ groupPolicy: " allowlist" ,
226+ channels: {
227+ C0123456789 : { requireMention: true },
228+ },
229+ },
230+ },
231+ }
232+ ```
233+
234+ At startup, OpenClaw verifies ` enterpriseOrgInstall ` with Slack ` auth.test ` .
235+ An org-installed token without the flag, or a workspace token with the flag,
236+ fails startup. Slack remains the source of truth for which workspaces have
237+ granted the installation; OpenClaw then applies the configured channel, user,
238+ DM, and mention policies to each delivered event. Enterprise V1 rejects all
239+ bot-authored ` message ` and ` app_mention ` events before dispatch, regardless of
240+ ` allowBots ` , because org installs do not provide a stable workspace-qualified
241+ bot identity for loop prevention.
242+
243+ Enterprise support is intentionally limited to direct Socket Mode or HTTP
244+ ` message ` and ` app_mention ` events and their immediate replies. Relay mode,
245+ slash commands, interactions, App Home, reaction event listeners, pins, Slack
246+ action tools, Slack-native approvals, bindings, queued or scheduled delivery,
247+ and proactive sends are unavailable for an enterprise account. Outbound
248+ acknowledgment, typing, and status reactions are supported through the
249+ listener-owned Slack client and require ` reactions:write ` ; inbound reaction
250+ notifications and reaction action tools remain unavailable.
251+
252+ Immediate replies reuse the standard Slack delivery behavior for chunks,
253+ media, metadata, identity fallback, unfurls, and receipts, but only while the
254+ validated listener-owned client remains in the active event turn. The
255+ in-memory send queue and thread-participation records are partitioned by that
256+ event's workspace; the client itself is never serialized or persisted.
257+
258+ Channel policy keys and ` dm.groupChannels ` entries must use raw stable Slack channel IDs or the
259+ ` channel:<id> ` form. OpenClaw normalizes either form to the raw channel ID for
260+ runtime matching; ` slack: ` , ` group: ` , and ` mpim: ` prefixes fail startup.
261+ User policy entries must use stable Slack user IDs; names, slugs, display names,
262+ and email addresses fail startup. IDs must use Slack's canonical uppercase
263+ prefix and body (for example, ` C0123456789 ` or ` U0123456789 ` ); lowercase and
264+ short lookalikes fail startup. Enterprise accounts cannot enable
265+ ` dangerouslyAllowNameMatching ` . Enterprise accounts may set the global
266+ ` mentionPatterns.mode ` , but ` mentionPatterns.allowIn ` and
267+ ` mentionPatterns.denyIn ` fail startup because bare Slack channel IDs are not
268+ workspace-qualified and can be reused across workspaces. Workspace installs
269+ retain the existing scoped mention-pattern behavior. Each accepted workspace
270+ gets separate routing, session, transcript, dedupe, history, and cache identity
271+ even when Slack IDs overlap. Within the ` message ` stream, ordinary user messages
272+ and user-authored ` file_share ` events are supported; other message subtypes are
273+ rejected before authorization or system-event handling.
274+
275+ Enterprise DMs must either be disabled (` dm.enabled=false ` or
276+ ` dmPolicy="disabled" ` ) or explicitly open with ` dmPolicy="open" ` and
277+ an effective account ` allowFrom ` containing the literal ` "*" ` . An empty
278+ allowlist or user-specific IDs without ` "*" ` fails startup. Pairing and
279+ per-user DM allowlists are rejected because Slack user IDs are not
280+ workspace-qualified in those authorization stores. Channel and sender policy
281+ continues to apply to channel messages.
282+
70283## Install
71284
72285``` bash
@@ -77,6 +290,10 @@ openclaw plugins install @openclaw/slack
77290
78291## Quick setup
79292
293+ The manifests in this section create a workspace-scoped installation. For an
294+ Enterprise Grid organization installation, use the dedicated
295+ [ org-wide manifest and workflow] ( #enterprise-grid-org-wide-installs ) instead.
296+
80297<Tabs >
81298 <Tab title =" Socket Mode (default) " >
82299 <Steps>
@@ -1242,6 +1459,7 @@ In a channel with `requireMention: true`, include a typed mention of the bot wit
12421459 - text chunks use `channels.slack.textChunkLimit` (default `8000`, capped at Slack's own message-length limit)
12431460 - `channels.slack.streaming.chunkMode="newline"` enables paragraph-first splitting
12441461 - file sends use Slack upload APIs and can include thread replies (`thread_ts`)
1462+ - long file captions use the first Slack-safe text chunk as the upload comment and send remaining chunks as follow-up messages
12451463 - outbound media cap follows `channels.slack.mediaMaxMb` when configured; otherwise channel sends use MIME-kind defaults from media pipeline
12461464
12471465 </Accordion >
@@ -1466,7 +1684,7 @@ Primary reference: [Configuration reference - Slack](/gateway/config-channels#sl
14661684
14671685<Accordion title =" High-signal Slack fields " >
14681686
1469- - mode/auth: ` mode ` , ` botToken ` , ` appToken ` , ` signingSecret ` , ` webhookPath ` , ` accounts.* `
1687+ - mode/auth: ` mode ` , ` enterpriseOrgInstall ` , ` botToken ` , ` appToken ` , ` signingSecret ` , ` webhookPath ` , ` accounts.* `
14701688- DM access: ` dm.enabled ` , ` dmPolicy ` , ` allowFrom ` (legacy: ` dm.policy ` , ` dm.allowFrom ` ), ` dm.groupEnabled ` , ` dm.groupChannels `
14711689- compatibility toggle: ` dangerouslyAllowNameMatching ` (break-glass; keep off unless needed)
14721690- channel access: ` groupPolicy ` , ` channels.* ` , ` channels.*.users ` , ` channels.*.requireMention `
0 commit comments