@openclaw/slack 2026.9.1 → 2026.9.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{action-runtime-DND4Pyp2.js → action-runtime-DftQWpI4.js} +4 -4
- package/dist/action-runtime.runtime-rHI3UAh4.js +2 -0
- package/dist/{actions-fh66A6lc.js → actions-CFkvEv1d.js} +3 -3
- package/dist/api.js +9 -9
- package/dist/{approval-handler.runtime-D7d8sKM0.js → approval-handler.runtime-BeILKdw4.js} +31 -15
- package/dist/{channel-4m8IAdMD.js → channel-CmOuxbOD.js} +24 -23
- package/dist/channel-config-api.js +1 -1
- package/dist/channel-plugin-api.js +1 -1
- package/dist/{channel-type-3-SqEMVc.js → channel-type-BWt2CRaI.js} +2 -2
- package/dist/{channel.setup-t_ghLGb_.js → channel.setup-D5z1ReaT.js} +8 -3
- package/dist/{config-schema-bP3eV2ra.js → config-schema-JDx_f9Zb.js} +2 -2
- package/dist/{directory-live-q32AW7N1.js → directory-live-BuBPHmju.js} +1 -1
- package/dist/{monitor-Chwu_SiZ.js → monitor-DI07pfJl.js} +3 -3
- package/dist/{outbound-adapter-BB8wAjm5.js → outbound-adapter-B5QyTRpJ.js} +3 -2
- package/dist/{pipeline.runtime-BklS_NEj.js → pipeline.runtime-BdIwZgm4.js} +567 -733
- package/dist/{policy-D7PKkiet.js → policy-Bh5TOqII.js} +2 -2
- package/dist/{probe-gj5yQgN2.js → probe-Biy--yhL.js} +42 -10
- package/dist/{provider-Do50wMWn.js → provider-DoaUvAM4.js} +5583 -4921
- package/dist/{relay-source-DWuduiJ2.js → relay-source-D4uecp68.js} +1 -1
- package/dist/{replies-Dc6WVh_Q.js → replies-DENuTcPO.js} +4 -3
- package/dist/reply-blocks-PRkhyAN7.js +790 -0
- package/dist/{resolve-channels-CU7Bg5Ka.js → resolve-channels-DQGV2VrE.js} +1 -1
- package/dist/{resolve-users-DrhttvRQ.js → resolve-users-DRGt_Q4I.js} +1 -1
- package/dist/runtime-api.js +10 -10
- package/dist/{scopes-B9HRguDe.js → scopes-CZzeGdWV.js} +1 -1
- package/dist/{send-Djswy6lf.js → send-DElUcgIs.js} +10 -10
- package/dist/{send.runtime-__WVTWLQ.js → send.runtime-C8D6cKGm.js} +1 -1
- package/dist/{group-policy-BKjMqT-8.js → session-status-BynwcZSO.js} +169 -799
- package/dist/setup-plugin-api.js +1 -1
- package/dist/{setup-surface-DO0e-MMS.js → setup-surface-B1_gpGBl.js} +4 -4
- package/dist/{shared-DEQBEKBL.js → shared-CNQsWJT7.js} +2 -2
- package/dist/{slash-dispatch.runtime-C3B4h5ZM.js → slash-dispatch.runtime-DhsXavSY.js} +1 -1
- package/node_modules/typebox/build/format/json_pointer.d.mts +2 -2
- package/node_modules/typebox/build/format/json_pointer.mjs +2 -2
- package/node_modules/typebox/build/format/json_pointer_uri_fragment.d.mts +2 -2
- package/node_modules/typebox/build/format/json_pointer_uri_fragment.mjs +2 -2
- package/node_modules/typebox/build/format/relative_json_pointer.d.mts +2 -2
- package/node_modules/typebox/build/format/relative_json_pointer.mjs +2 -2
- package/node_modules/typebox/build/system/memory/assign.mjs +2 -1
- package/node_modules/typebox/build/system/memory/create.mjs +3 -4
- package/node_modules/typebox/build/system/memory/discard.mjs +2 -2
- package/node_modules/typebox/build/system/memory/freeze.d.mts +4 -0
- package/node_modules/typebox/build/system/memory/freeze.mjs +6 -0
- package/node_modules/typebox/build/system/memory/update.mjs +3 -2
- package/node_modules/typebox/package.json +1 -1
- package/node_modules/undici/lib/dispatcher/balanced-pool.js +4 -2
- package/node_modules/undici/lib/dispatcher/client-h1.js +12 -4
- package/node_modules/undici/lib/dispatcher/client-h2.js +70 -14
- package/node_modules/undici/lib/dispatcher/client.js +6 -2
- package/node_modules/undici/lib/handler/cache-handler.js +21 -5
- package/node_modules/undici/lib/handler/retry-handler.js +42 -7
- package/node_modules/undici/lib/interceptor/cache.js +20 -1
- package/node_modules/undici/lib/interceptor/decompress.js +146 -14
- package/node_modules/undici/lib/interceptor/dump.js +10 -23
- package/node_modules/undici/lib/web/eventsource/eventsource-stream.js +245 -150
- package/node_modules/undici/lib/web/websocket/connection.js +1 -1
- package/node_modules/undici/lib/web/websocket/permessage-deflate.js +5 -0
- package/node_modules/undici/lib/web/websocket/stream/websocketstream.js +8 -10
- package/node_modules/undici/package.json +1 -1
- package/node_modules/undici/types/interceptors.d.ts +2 -0
- package/openclaw.plugin.json +3 -3
- package/package.json +6 -6
- package/skills/_vendor/slack-skills-plugin.LICENSE +21 -0
- package/skills/_vendor/slack-skills-plugin.json +31 -0
- package/skills/block-kit/SKILL.md +37 -0
- package/skills/block-kit/references/official-block-kit.md +257 -0
- package/skills/block-kit/references/official-common-patterns.md +385 -0
- package/skills/slack/SKILL.md +1 -1
- package/dist/action-runtime.runtime-CEhbmS-Z.js +0 -2
- package/dist/conversation-binding-route-Vee8Dgbf.js +0 -115
|
@@ -0,0 +1,385 @@
|
|
|
1
|
+
# Common Block Kit Patterns
|
|
2
|
+
|
|
3
|
+
> Starting scaffolds for frequent use cases — copy one and customize rather than building from scratch.
|
|
4
|
+
> They were valid when written, but the live docs (the skill's **Source of Truth**) remain authoritative for field schemas, and Block Kit evolves. Confirm any field you change against the component's doc page, and re-run the customized payload through `blocks.validate` (Step 5) before shipping.
|
|
5
|
+
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
## Approval Message [M]
|
|
9
|
+
|
|
10
|
+
A notification with context and Approve/Reject buttons.
|
|
11
|
+
|
|
12
|
+
```json
|
|
13
|
+
{
|
|
14
|
+
"channel": "C0123456789",
|
|
15
|
+
"text": "New request from Jane awaiting approval",
|
|
16
|
+
"blocks": [
|
|
17
|
+
{
|
|
18
|
+
"type": "header",
|
|
19
|
+
"text": { "type": "plain_text", "text": "New Approval Request" }
|
|
20
|
+
},
|
|
21
|
+
{
|
|
22
|
+
"type": "section",
|
|
23
|
+
"text": {
|
|
24
|
+
"type": "mrkdwn",
|
|
25
|
+
"text": "*Requester:* <@U0123456789>\n*Type:* Access request\n*Details:* Production database read access"
|
|
26
|
+
}
|
|
27
|
+
},
|
|
28
|
+
{ "type": "divider" },
|
|
29
|
+
{
|
|
30
|
+
"type": "actions",
|
|
31
|
+
"block_id": "approval_actions",
|
|
32
|
+
"elements": [
|
|
33
|
+
{
|
|
34
|
+
"type": "button",
|
|
35
|
+
"text": { "type": "plain_text", "text": "Approve" },
|
|
36
|
+
"style": "primary",
|
|
37
|
+
"action_id": "approve_btn",
|
|
38
|
+
"value": "request_123"
|
|
39
|
+
},
|
|
40
|
+
{
|
|
41
|
+
"type": "button",
|
|
42
|
+
"text": { "type": "plain_text", "text": "Reject" },
|
|
43
|
+
"style": "danger",
|
|
44
|
+
"action_id": "reject_btn",
|
|
45
|
+
"value": "request_123"
|
|
46
|
+
}
|
|
47
|
+
]
|
|
48
|
+
}
|
|
49
|
+
]
|
|
50
|
+
}
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
**Customization points:** Header text, section fields, button values, adding a confirmation dialog to the Reject button.
|
|
54
|
+
|
|
55
|
+
---
|
|
56
|
+
|
|
57
|
+
## Simple Form Modal [V]
|
|
58
|
+
|
|
59
|
+
A modal with text input, select menu, and optional checkbox.
|
|
60
|
+
|
|
61
|
+
```json
|
|
62
|
+
{
|
|
63
|
+
"type": "modal",
|
|
64
|
+
"callback_id": "feedback_form",
|
|
65
|
+
"title": { "type": "plain_text", "text": "Submit Feedback" },
|
|
66
|
+
"submit": { "type": "plain_text", "text": "Submit" },
|
|
67
|
+
"close": { "type": "plain_text", "text": "Cancel" },
|
|
68
|
+
"blocks": [
|
|
69
|
+
{
|
|
70
|
+
"type": "input",
|
|
71
|
+
"block_id": "category_block",
|
|
72
|
+
"label": { "type": "plain_text", "text": "Category" },
|
|
73
|
+
"element": {
|
|
74
|
+
"type": "static_select",
|
|
75
|
+
"action_id": "category_select",
|
|
76
|
+
"placeholder": { "type": "plain_text", "text": "Choose a category" },
|
|
77
|
+
"options": [
|
|
78
|
+
{ "text": { "type": "plain_text", "text": "Bug Report" }, "value": "bug" },
|
|
79
|
+
{ "text": { "type": "plain_text", "text": "Feature Request" }, "value": "feature" },
|
|
80
|
+
{ "text": { "type": "plain_text", "text": "General Feedback" }, "value": "general" }
|
|
81
|
+
]
|
|
82
|
+
}
|
|
83
|
+
},
|
|
84
|
+
{
|
|
85
|
+
"type": "input",
|
|
86
|
+
"block_id": "description_block",
|
|
87
|
+
"label": { "type": "plain_text", "text": "Description" },
|
|
88
|
+
"element": {
|
|
89
|
+
"type": "plain_text_input",
|
|
90
|
+
"action_id": "description_input",
|
|
91
|
+
"multiline": true,
|
|
92
|
+
"placeholder": { "type": "plain_text", "text": "Tell us more..." }
|
|
93
|
+
}
|
|
94
|
+
},
|
|
95
|
+
{
|
|
96
|
+
"type": "input",
|
|
97
|
+
"block_id": "urgency_block",
|
|
98
|
+
"label": { "type": "plain_text", "text": "Priority" },
|
|
99
|
+
"element": {
|
|
100
|
+
"type": "radio_buttons",
|
|
101
|
+
"action_id": "urgency_select",
|
|
102
|
+
"options": [
|
|
103
|
+
{ "text": { "type": "plain_text", "text": "Low" }, "value": "low" },
|
|
104
|
+
{ "text": { "type": "plain_text", "text": "Medium" }, "value": "medium" },
|
|
105
|
+
{ "text": { "type": "plain_text", "text": "High" }, "value": "high" }
|
|
106
|
+
]
|
|
107
|
+
},
|
|
108
|
+
"optional": true
|
|
109
|
+
}
|
|
110
|
+
]
|
|
111
|
+
}
|
|
112
|
+
```
|
|
113
|
+
|
|
114
|
+
**Customization points:** Title, callback_id, input types, options list, adding/removing input blocks.
|
|
115
|
+
|
|
116
|
+
---
|
|
117
|
+
|
|
118
|
+
## Notification Alert [M]
|
|
119
|
+
|
|
120
|
+
An alert banner with description and timestamp context.
|
|
121
|
+
|
|
122
|
+
```json
|
|
123
|
+
{
|
|
124
|
+
"channel": "C0123456789",
|
|
125
|
+
"text": "Alert: Deployment failed for api-gateway",
|
|
126
|
+
"blocks": [
|
|
127
|
+
{
|
|
128
|
+
"type": "alert",
|
|
129
|
+
"text": { "type": "plain_text", "text": "Deployment failed for api-gateway" },
|
|
130
|
+
"level": "error"
|
|
131
|
+
},
|
|
132
|
+
{
|
|
133
|
+
"type": "section",
|
|
134
|
+
"text": {
|
|
135
|
+
"type": "mrkdwn",
|
|
136
|
+
"text": "The deployment to *production* failed during the health check phase.\n\n*Error:* `Connection timeout after 30s`\n*Commit:* `a1b2c3d`"
|
|
137
|
+
}
|
|
138
|
+
},
|
|
139
|
+
{
|
|
140
|
+
"type": "context",
|
|
141
|
+
"elements": [
|
|
142
|
+
{
|
|
143
|
+
"type": "mrkdwn",
|
|
144
|
+
"text": "Triggered by <@U0123456789> | <!date^1700000000^{date_short} at {time}|Nov 14, 2023>"
|
|
145
|
+
}
|
|
146
|
+
]
|
|
147
|
+
},
|
|
148
|
+
{
|
|
149
|
+
"type": "actions",
|
|
150
|
+
"elements": [
|
|
151
|
+
{
|
|
152
|
+
"type": "button",
|
|
153
|
+
"text": { "type": "plain_text", "text": "View Logs" },
|
|
154
|
+
"url": "https://logs.example.com/deploy/456",
|
|
155
|
+
"action_id": "view_logs_btn"
|
|
156
|
+
},
|
|
157
|
+
{
|
|
158
|
+
"type": "button",
|
|
159
|
+
"text": { "type": "plain_text", "text": "Retry" },
|
|
160
|
+
"style": "primary",
|
|
161
|
+
"action_id": "retry_deploy_btn"
|
|
162
|
+
}
|
|
163
|
+
]
|
|
164
|
+
}
|
|
165
|
+
]
|
|
166
|
+
}
|
|
167
|
+
```
|
|
168
|
+
|
|
169
|
+
**Customization points:** Level (`info`, `warning`, `error`, `success`), description text, action buttons.
|
|
170
|
+
|
|
171
|
+
---
|
|
172
|
+
|
|
173
|
+
## Dashboard Home Tab [H]
|
|
174
|
+
|
|
175
|
+
A welcome dashboard with metrics fields and quick-action buttons.
|
|
176
|
+
|
|
177
|
+
```json
|
|
178
|
+
{
|
|
179
|
+
"type": "home",
|
|
180
|
+
"blocks": [
|
|
181
|
+
{
|
|
182
|
+
"type": "header",
|
|
183
|
+
"text": { "type": "plain_text", "text": "Welcome to AppName" }
|
|
184
|
+
},
|
|
185
|
+
{
|
|
186
|
+
"type": "section",
|
|
187
|
+
"text": { "type": "mrkdwn", "text": "Here's your overview for today:" }
|
|
188
|
+
},
|
|
189
|
+
{
|
|
190
|
+
"type": "section",
|
|
191
|
+
"fields": [
|
|
192
|
+
{ "type": "mrkdwn", "text": "*Open Tickets:*\n12" },
|
|
193
|
+
{ "type": "mrkdwn", "text": "*Resolved Today:*\n5" },
|
|
194
|
+
{ "type": "mrkdwn", "text": "*Avg Response:*\n2.4 hrs" },
|
|
195
|
+
{ "type": "mrkdwn", "text": "*SLA Status:*\n:white_check_mark: On Track" }
|
|
196
|
+
]
|
|
197
|
+
},
|
|
198
|
+
{ "type": "divider" },
|
|
199
|
+
{
|
|
200
|
+
"type": "actions",
|
|
201
|
+
"elements": [
|
|
202
|
+
{
|
|
203
|
+
"type": "button",
|
|
204
|
+
"text": { "type": "plain_text", "text": "New Ticket" },
|
|
205
|
+
"style": "primary",
|
|
206
|
+
"action_id": "new_ticket_btn"
|
|
207
|
+
},
|
|
208
|
+
{
|
|
209
|
+
"type": "button",
|
|
210
|
+
"text": { "type": "plain_text", "text": "My Queue" },
|
|
211
|
+
"action_id": "my_queue_btn"
|
|
212
|
+
},
|
|
213
|
+
{
|
|
214
|
+
"type": "button",
|
|
215
|
+
"text": { "type": "plain_text", "text": "Settings" },
|
|
216
|
+
"action_id": "settings_btn"
|
|
217
|
+
}
|
|
218
|
+
]
|
|
219
|
+
}
|
|
220
|
+
]
|
|
221
|
+
}
|
|
222
|
+
```
|
|
223
|
+
|
|
224
|
+
**Customization points:** Metrics fields, action buttons, adding image blocks or additional sections.
|
|
225
|
+
|
|
226
|
+
---
|
|
227
|
+
|
|
228
|
+
## Confirmation with Dialog [M]
|
|
229
|
+
|
|
230
|
+
An action button with a confirmation dialog attached (prevents accidental clicks).
|
|
231
|
+
|
|
232
|
+
```json
|
|
233
|
+
{
|
|
234
|
+
"channel": "C0123456789",
|
|
235
|
+
"text": "Server shutdown requested",
|
|
236
|
+
"blocks": [
|
|
237
|
+
{
|
|
238
|
+
"type": "section",
|
|
239
|
+
"text": { "type": "mrkdwn", "text": "Are you sure you want to shut down *prod-server-01*?" }
|
|
240
|
+
},
|
|
241
|
+
{
|
|
242
|
+
"type": "actions",
|
|
243
|
+
"elements": [
|
|
244
|
+
{
|
|
245
|
+
"type": "button",
|
|
246
|
+
"text": { "type": "plain_text", "text": "Shut Down" },
|
|
247
|
+
"style": "danger",
|
|
248
|
+
"action_id": "shutdown_btn",
|
|
249
|
+
"value": "prod-server-01",
|
|
250
|
+
"confirm": {
|
|
251
|
+
"title": { "type": "plain_text", "text": "Confirm Shutdown" },
|
|
252
|
+
"text": {
|
|
253
|
+
"type": "plain_text",
|
|
254
|
+
"text": "This will immediately terminate the server. Active connections will be dropped."
|
|
255
|
+
},
|
|
256
|
+
"confirm": { "type": "plain_text", "text": "Shut Down" },
|
|
257
|
+
"deny": { "type": "plain_text", "text": "Cancel" },
|
|
258
|
+
"style": "danger"
|
|
259
|
+
}
|
|
260
|
+
}
|
|
261
|
+
]
|
|
262
|
+
}
|
|
263
|
+
]
|
|
264
|
+
}
|
|
265
|
+
```
|
|
266
|
+
|
|
267
|
+
**Customization points:** Confirmation title/text (title max 100 chars, text max 300 chars, confirm/deny max 30 chars), button style.
|
|
268
|
+
|
|
269
|
+
---
|
|
270
|
+
|
|
271
|
+
## Data Table [M]
|
|
272
|
+
|
|
273
|
+
A structured table for displaying tabular data. Only one table block per message.
|
|
274
|
+
|
|
275
|
+
```json
|
|
276
|
+
{
|
|
277
|
+
"channel": "C0123456789",
|
|
278
|
+
"text": "Team sprint summary",
|
|
279
|
+
"blocks": [
|
|
280
|
+
{
|
|
281
|
+
"type": "header",
|
|
282
|
+
"text": { "type": "plain_text", "text": "Sprint Summary" }
|
|
283
|
+
},
|
|
284
|
+
{
|
|
285
|
+
"type": "table",
|
|
286
|
+
"column_settings": [{ "is_wrapped": true }, { "align": "center" }, { "align": "right" }],
|
|
287
|
+
"rows": [
|
|
288
|
+
[
|
|
289
|
+
{ "type": "raw_text", "text": "Name" },
|
|
290
|
+
{ "type": "raw_text", "text": "Status" },
|
|
291
|
+
{ "type": "raw_text", "text": "Points" }
|
|
292
|
+
],
|
|
293
|
+
[
|
|
294
|
+
{ "type": "raw_text", "text": "Auth refactor" },
|
|
295
|
+
{ "type": "raw_text", "text": "In Progress" },
|
|
296
|
+
{ "type": "raw_text", "text": "5" }
|
|
297
|
+
],
|
|
298
|
+
[
|
|
299
|
+
{ "type": "raw_text", "text": "API docs update" },
|
|
300
|
+
{ "type": "raw_text", "text": "Done" },
|
|
301
|
+
{ "type": "raw_text", "text": "2" }
|
|
302
|
+
],
|
|
303
|
+
[
|
|
304
|
+
{ "type": "raw_text", "text": "Bug #1234" },
|
|
305
|
+
{ "type": "raw_text", "text": "Blocked" },
|
|
306
|
+
{ "type": "raw_text", "text": "3" }
|
|
307
|
+
]
|
|
308
|
+
]
|
|
309
|
+
}
|
|
310
|
+
]
|
|
311
|
+
}
|
|
312
|
+
```
|
|
313
|
+
|
|
314
|
+
**Customization points:** Column settings (alignment: `left`/`center`/`right`, wrapping: `is_wrapped`), row data, cell type (`raw_text` for plain content, `rich_text` for formatted content with links/emoji/mentions). Max 100 rows, max 20 cells per row. First row is the header. Only one table block per message.
|
|
315
|
+
|
|
316
|
+
---
|
|
317
|
+
|
|
318
|
+
## Settings Modal with Multiple Input Types [V]
|
|
319
|
+
|
|
320
|
+
A modal combining different input types for a settings/preferences form.
|
|
321
|
+
|
|
322
|
+
```json
|
|
323
|
+
{
|
|
324
|
+
"type": "modal",
|
|
325
|
+
"callback_id": "settings_modal",
|
|
326
|
+
"title": { "type": "plain_text", "text": "Notification Settings" },
|
|
327
|
+
"submit": { "type": "plain_text", "text": "Save" },
|
|
328
|
+
"close": { "type": "plain_text", "text": "Cancel" },
|
|
329
|
+
"blocks": [
|
|
330
|
+
{
|
|
331
|
+
"type": "input",
|
|
332
|
+
"block_id": "channel_block",
|
|
333
|
+
"label": { "type": "plain_text", "text": "Notification Channel" },
|
|
334
|
+
"element": {
|
|
335
|
+
"type": "conversations_select",
|
|
336
|
+
"action_id": "channel_select",
|
|
337
|
+
"default_to_current_conversation": true
|
|
338
|
+
}
|
|
339
|
+
},
|
|
340
|
+
{
|
|
341
|
+
"type": "input",
|
|
342
|
+
"block_id": "frequency_block",
|
|
343
|
+
"label": { "type": "plain_text", "text": "Digest Frequency" },
|
|
344
|
+
"element": {
|
|
345
|
+
"type": "static_select",
|
|
346
|
+
"action_id": "frequency_select",
|
|
347
|
+
"options": [
|
|
348
|
+
{ "text": { "type": "plain_text", "text": "Real-time" }, "value": "realtime" },
|
|
349
|
+
{ "text": { "type": "plain_text", "text": "Hourly" }, "value": "hourly" },
|
|
350
|
+
{ "text": { "type": "plain_text", "text": "Daily" }, "value": "daily" }
|
|
351
|
+
],
|
|
352
|
+
"initial_option": { "text": { "type": "plain_text", "text": "Daily" }, "value": "daily" }
|
|
353
|
+
}
|
|
354
|
+
},
|
|
355
|
+
{
|
|
356
|
+
"type": "input",
|
|
357
|
+
"block_id": "events_block",
|
|
358
|
+
"label": { "type": "plain_text", "text": "Notify me about" },
|
|
359
|
+
"element": {
|
|
360
|
+
"type": "checkboxes",
|
|
361
|
+
"action_id": "events_checkboxes",
|
|
362
|
+
"options": [
|
|
363
|
+
{ "text": { "type": "plain_text", "text": "New deployments" }, "value": "deploys" },
|
|
364
|
+
{ "text": { "type": "plain_text", "text": "Failed builds" }, "value": "failures" },
|
|
365
|
+
{ "text": { "type": "plain_text", "text": "PR reviews needed" }, "value": "reviews" }
|
|
366
|
+
]
|
|
367
|
+
}
|
|
368
|
+
},
|
|
369
|
+
{
|
|
370
|
+
"type": "input",
|
|
371
|
+
"block_id": "quiet_hours_block",
|
|
372
|
+
"label": { "type": "plain_text", "text": "Quiet hours start" },
|
|
373
|
+
"element": {
|
|
374
|
+
"type": "timepicker",
|
|
375
|
+
"action_id": "quiet_start",
|
|
376
|
+
"initial_time": "22:00",
|
|
377
|
+
"placeholder": { "type": "plain_text", "text": "Select time" }
|
|
378
|
+
},
|
|
379
|
+
"optional": true
|
|
380
|
+
}
|
|
381
|
+
]
|
|
382
|
+
}
|
|
383
|
+
```
|
|
384
|
+
|
|
385
|
+
**Customization points:** Input types, options, initial values, adding `hint` text to inputs, marking fields as `optional`.
|
package/skills/slack/SKILL.md
CHANGED
|
@@ -17,4 +17,4 @@ Use the `message` tool with `channel: "slack"`. The tool schema lists the action
|
|
|
17
17
|
- When multiple Slack accounts are configured, pass `accountId` rather than guessing.
|
|
18
18
|
- Confirm destructive deletes when the target or intent is unclear.
|
|
19
19
|
|
|
20
|
-
Slack formatting, mentions,
|
|
20
|
+
Slack formatting, mentions, and available actions are described automatically by the current `message` tool hints. Follow those hints instead of maintaining a second action catalog here.
|
|
@@ -1,115 +0,0 @@
|
|
|
1
|
-
import { a as parseSlackTarget } from "./target-parsing-PbxGDbr9.js";
|
|
2
|
-
import "./targets-7FexXJ62.js";
|
|
3
|
-
import { resolveConfiguredBindingRoute, resolveRuntimeConversationBindingRoute } from "openclaw/plugin-sdk/conversation-runtime";
|
|
4
|
-
//#region extensions/slack/src/account-reply-mode.ts
|
|
5
|
-
function normalizeSlackChatType(raw) {
|
|
6
|
-
const value = raw?.trim().toLowerCase();
|
|
7
|
-
if (!value) return;
|
|
8
|
-
if (value === "direct" || value === "dm") return "direct";
|
|
9
|
-
if (value === "group" || value === "channel") return value;
|
|
10
|
-
}
|
|
11
|
-
function resolveSlackReplyToMode(account, chatType) {
|
|
12
|
-
const normalized = normalizeSlackChatType(chatType ?? void 0);
|
|
13
|
-
if (normalized && account.replyToModeByChatType?.[normalized] !== void 0) return account.replyToModeByChatType[normalized] ?? "off";
|
|
14
|
-
return account.replyToMode ?? "off";
|
|
15
|
-
}
|
|
16
|
-
//#endregion
|
|
17
|
-
//#region extensions/slack/src/conversation-binding-route.ts
|
|
18
|
-
const slackRouteBindingConfigCache = /* @__PURE__ */ new WeakMap();
|
|
19
|
-
function slackTargetDefaultKindForPeer(kind) {
|
|
20
|
-
return kind === "direct" ? "user" : "channel";
|
|
21
|
-
}
|
|
22
|
-
function slackTargetKindMatchesPeer(peerKind, targetKind) {
|
|
23
|
-
if (targetKind === "user") return peerKind === "direct";
|
|
24
|
-
return peerKind === "channel" || peerKind === "group";
|
|
25
|
-
}
|
|
26
|
-
function normalizeSlackRouteBindingPeer(peer) {
|
|
27
|
-
const rawId = peer.id.trim();
|
|
28
|
-
if (!rawId || rawId === "*") return peer;
|
|
29
|
-
const target = (() => {
|
|
30
|
-
try {
|
|
31
|
-
return parseSlackTarget(rawId, { defaultKind: slackTargetDefaultKindForPeer(peer.kind) });
|
|
32
|
-
} catch {
|
|
33
|
-
return;
|
|
34
|
-
}
|
|
35
|
-
})();
|
|
36
|
-
if (!target || !slackTargetKindMatchesPeer(peer.kind, target.kind)) return peer;
|
|
37
|
-
const normalizedId = target.teamId ? `team:${target.teamId}:${target.kind}:${target.id}` : target.id;
|
|
38
|
-
return normalizedId === peer.id ? peer : {
|
|
39
|
-
...peer,
|
|
40
|
-
id: normalizedId
|
|
41
|
-
};
|
|
42
|
-
}
|
|
43
|
-
function normalizeSlackRouteBindingConfig(cfg) {
|
|
44
|
-
const bindings = cfg.bindings;
|
|
45
|
-
const cached = slackRouteBindingConfigCache.get(cfg);
|
|
46
|
-
if (cached && cached.bindingsRef === bindings) return cached.normalizedCfg;
|
|
47
|
-
if (!Array.isArray(bindings)) return cfg;
|
|
48
|
-
let changed = false;
|
|
49
|
-
const normalizedBindings = bindings.map((binding) => {
|
|
50
|
-
if (binding.type === "acp" || binding.match.channel.trim().toLowerCase() !== "slack") return binding;
|
|
51
|
-
const peer = binding.match.peer;
|
|
52
|
-
if (!peer) return binding;
|
|
53
|
-
const normalizedPeer = normalizeSlackRouteBindingPeer(peer);
|
|
54
|
-
if (normalizedPeer === peer) return binding;
|
|
55
|
-
changed = true;
|
|
56
|
-
return {
|
|
57
|
-
...binding,
|
|
58
|
-
match: {
|
|
59
|
-
...binding.match,
|
|
60
|
-
peer: normalizedPeer
|
|
61
|
-
}
|
|
62
|
-
};
|
|
63
|
-
});
|
|
64
|
-
const normalizedCfg = changed ? {
|
|
65
|
-
...cfg,
|
|
66
|
-
bindings: normalizedBindings
|
|
67
|
-
} : cfg;
|
|
68
|
-
slackRouteBindingConfigCache.set(cfg, {
|
|
69
|
-
bindingsRef: bindings,
|
|
70
|
-
normalizedCfg
|
|
71
|
-
});
|
|
72
|
-
return normalizedCfg;
|
|
73
|
-
}
|
|
74
|
-
function resolveSlackConversationBindingRoute(params) {
|
|
75
|
-
const boundThreadRoute = params.bindingsEnabled && params.runtimeBindingThreadId ? resolveRuntimeConversationBindingRoute({
|
|
76
|
-
route: params.route,
|
|
77
|
-
touchBinding: params.touchBinding,
|
|
78
|
-
conversation: {
|
|
79
|
-
channel: "slack",
|
|
80
|
-
accountId: params.accountId,
|
|
81
|
-
conversationId: params.runtimeBindingThreadId,
|
|
82
|
-
parentConversationId: params.baseConversationId
|
|
83
|
-
}
|
|
84
|
-
}) : null;
|
|
85
|
-
const runtimeRoute = !params.bindingsEnabled ? {
|
|
86
|
-
bindingOwnerAvailable: true,
|
|
87
|
-
route: params.route,
|
|
88
|
-
bindingRecord: null,
|
|
89
|
-
boundSessionKey: void 0
|
|
90
|
-
} : boundThreadRoute?.boundSessionKey || boundThreadRoute?.bindingRecord ? boundThreadRoute : resolveRuntimeConversationBindingRoute({
|
|
91
|
-
route: params.route,
|
|
92
|
-
touchBinding: params.touchBinding,
|
|
93
|
-
conversation: {
|
|
94
|
-
channel: "slack",
|
|
95
|
-
accountId: params.accountId,
|
|
96
|
-
conversationId: params.baseConversationId
|
|
97
|
-
}
|
|
98
|
-
});
|
|
99
|
-
const configuredRoute = params.bindingsEnabled && !runtimeRoute.boundSessionKey && !runtimeRoute.bindingRecord ? resolveConfiguredBindingRoute({
|
|
100
|
-
cfg: params.cfg,
|
|
101
|
-
route: params.route,
|
|
102
|
-
conversation: {
|
|
103
|
-
channel: "slack",
|
|
104
|
-
accountId: params.accountId,
|
|
105
|
-
conversationId: params.baseConversationId
|
|
106
|
-
}
|
|
107
|
-
}) : null;
|
|
108
|
-
return {
|
|
109
|
-
runtimeRoute,
|
|
110
|
-
configuredRoute,
|
|
111
|
-
route: runtimeRoute.boundSessionKey ? runtimeRoute.route : configuredRoute?.route ?? params.route
|
|
112
|
-
};
|
|
113
|
-
}
|
|
114
|
-
//#endregion
|
|
115
|
-
export { resolveSlackConversationBindingRoute as n, resolveSlackReplyToMode as r, normalizeSlackRouteBindingConfig as t };
|