@frogbotai/piece-slack 0.29.0 → 0.31.0

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.
Files changed (47) hide show
  1. package/README.md +3 -2
  2. package/dist/actions.d.ts +2 -2
  3. package/dist/actions.d.ts.map +1 -1
  4. package/dist/actions.js +286 -196
  5. package/dist/actions.js.map +1 -1
  6. package/dist/client.d.ts.map +1 -1
  7. package/dist/client.js +47 -35
  8. package/dist/client.js.map +1 -1
  9. package/dist/config.js +17 -5
  10. package/dist/config.js.map +1 -1
  11. package/dist/define.d.ts.map +1 -1
  12. package/dist/define.js +1 -0
  13. package/dist/define.js.map +1 -1
  14. package/dist/files.d.ts.map +1 -1
  15. package/dist/files.js +25 -17
  16. package/dist/files.js.map +1 -1
  17. package/dist/index.d.ts +2 -5
  18. package/dist/index.d.ts.map +1 -1
  19. package/dist/index.js +37 -48
  20. package/dist/index.js.map +1 -1
  21. package/dist/options.js +36 -21
  22. package/dist/options.js.map +1 -1
  23. package/dist/questions/blocks.js +148 -74
  24. package/dist/questions/blocks.js.map +1 -1
  25. package/dist/questions/index.js +2 -1
  26. package/dist/questions/index.js.map +1 -1
  27. package/dist/questions/notify.js +19 -13
  28. package/dist/questions/notify.js.map +1 -1
  29. package/dist/questions/parse.js +110 -59
  30. package/dist/questions/parse.js.map +1 -1
  31. package/dist/questions/render.js +16 -7
  32. package/dist/questions/render.js.map +1 -1
  33. package/dist/questions/settled.js +9 -3
  34. package/dist/questions/settled.js.map +1 -1
  35. package/dist/questions/slackThread.js +12 -6
  36. package/dist/questions/slackThread.js.map +1 -1
  37. package/dist/questions/state.js +18 -5
  38. package/dist/questions/state.js.map +1 -1
  39. package/dist/questions/updated.js +32 -24
  40. package/dist/questions/updated.js.map +1 -1
  41. package/dist/triggers.d.ts.map +1 -1
  42. package/dist/triggers.js +150 -126
  43. package/dist/triggers.js.map +1 -1
  44. package/dist/webhook.d.ts.map +1 -1
  45. package/dist/webhook.js +28 -43
  46. package/dist/webhook.js.map +1 -1
  47. package/package.json +4 -4
package/dist/actions.js CHANGED
@@ -1,29 +1,33 @@
1
+ import { createPieceFile, filesCollectionSlug } from 'frogbot/pieces';
1
2
  import { z } from 'zod';
2
- import { slackApiResult, slackResponse, slackValue, slackValues, } from './client.js';
3
+ import { slackApiResult, slackResponse, slackValue, slackValues } from './client.js';
3
4
  import { defineAction } from './define.js';
4
5
  import { loadSlackFile, slackFile } from './files.js';
5
6
  import { channelOptions, userOptions } from './options.js';
6
- const channel = z.string().min(1).meta({ label: 'Channel' });
7
- const user = z.string().min(1).meta({ label: 'User' });
7
+ const channel = z.string().min(1).meta({
8
+ label: 'Channel'
9
+ });
10
+ const user = z.string().min(1).meta({
11
+ label: 'User'
12
+ });
8
13
  const timestamp = z.string().regex(/^(?:.*\/p\d{16}|\d+\.\d{6})$/, 'Invalid Slack timestamp.');
9
14
  const blocks = z.array(slackValue).default([]);
10
15
  const messageResult = slackResponse.extend({
11
16
  channel: z.string().optional(),
12
- ts: z.string().optional(),
17
+ ts: z.string().optional()
13
18
  });
14
19
  function normalizeTimestamp(value) {
15
20
  const link = value.match(/\/p(\d+)(\d{6})$/);
16
21
  return link ? `${link[1]}.${link[2]}` : value;
17
22
  }
18
- async function upload({ client, file, channelId, title, initialComment, threadTimestamp, token = 'bot', signal, }) {
19
- const created = await client.request('files.getUploadURLExternal', { filename: file.name, length: file.data.size }, token);
23
+ async function upload({ client, file, channelId, title, initialComment, threadTimestamp, token = 'bot', signal }) {
24
+ const created = await client.request('files.getUploadURLExternal', {
25
+ filename: file.name,
26
+ length: file.data.size
27
+ }, token);
20
28
  const uploadUrl = typeof created.upload_url === 'string' ? new URL(created.upload_url) : undefined;
21
29
  const fileId = typeof created.file_id === 'string' ? created.file_id : undefined;
22
- if (!uploadUrl ||
23
- !fileId ||
24
- uploadUrl.protocol !== 'https:' ||
25
- uploadUrl.username ||
26
- uploadUrl.password) {
30
+ if (!uploadUrl || !fileId || uploadUrl.protocol !== 'https:' || uploadUrl.username || uploadUrl.password) {
27
31
  throw new Error('Slack returned an invalid file upload target.');
28
32
  }
29
33
  if (uploadUrl.hostname !== 'files.slack.com' && !uploadUrl.hostname.endsWith('.slack.com')) {
@@ -33,15 +37,19 @@ async function upload({ client, file, channelId, title, initialComment, threadTi
33
37
  method: 'POST',
34
38
  body: file.data,
35
39
  redirect: 'error',
36
- signal,
40
+ signal
37
41
  });
38
- if (!response.ok)
39
- throw new Error(`Slack file upload failed (${response.status}).`);
42
+ if (!response.ok) throw new Error(`Slack file upload failed (${response.status}).`);
40
43
  return client.request('files.completeUploadExternal', {
41
- files: [{ id: fileId, title }],
44
+ files: [
45
+ {
46
+ id: fileId,
47
+ title
48
+ }
49
+ ],
42
50
  channel_id: channelId,
43
51
  initial_comment: initialComment,
44
- thread_ts: threadTimestamp,
52
+ thread_ts: threadTimestamp
45
53
  }, token);
46
54
  }
47
55
  const messageFields = {
@@ -50,17 +58,22 @@ const messageFields = {
50
58
  profilePicture: z.url().optional(),
51
59
  iconEmoji: z.string().optional(),
52
60
  blocks,
53
- unfurlLinks: z.boolean().default(true),
61
+ unfurlLinks: z.boolean().default(true)
54
62
  };
55
- const sendDirectMessageInput = z.object({ userId: user, ...messageFields });
63
+ const sendDirectMessageInput = z.object({
64
+ userId: user,
65
+ ...messageFields
66
+ });
56
67
  export const sendDirectMessage = defineAction({
57
68
  slug: 'sendDirectMessage',
58
69
  description: 'Send a direct message to a Slack user.',
59
70
  input: sendDirectMessageInput,
60
71
  output: messageResult,
61
72
  idempotent: false,
62
- options: { userId: userOptions },
63
- async run({ client, input }) {
73
+ options: {
74
+ userId: userOptions
75
+ },
76
+ async run ({ client, input }) {
64
77
  return client.request('chat.postMessage', {
65
78
  channel: input.userId,
66
79
  text: input.text,
@@ -68,12 +81,11 @@ export const sendDirectMessage = defineAction({
68
81
  icon_url: input.profilePicture,
69
82
  icon_emoji: input.iconEmoji,
70
83
  blocks: input.blocks,
71
- unfurl_links: input.unfurlLinks,
84
+ unfurl_links: input.unfurlLinks
72
85
  });
73
- },
86
+ }
74
87
  });
75
- const sendChannelInput = z
76
- .object({
88
+ const sendChannelInput = z.object({
77
89
  channel,
78
90
  text: z.string().optional(),
79
91
  sendAsBot: z.boolean().default(true),
@@ -84,10 +96,9 @@ const sendChannelInput = z
84
96
  file: slackFile.optional(),
85
97
  replyBroadcast: z.boolean().default(false),
86
98
  unfurlLinks: z.boolean().default(true),
87
- blocks,
88
- })
89
- .refine(({ text, blocks: value }) => Boolean(text) || value.length > 0, {
90
- message: 'A message or Block Kit blocks are required.',
99
+ blocks
100
+ }).refine(({ text, blocks: value })=>Boolean(text) || value.length > 0, {
101
+ message: 'A message or Block Kit blocks are required.'
91
102
  });
92
103
  export const sendChannelMessage = defineAction({
93
104
  slug: 'sendChannelMessage',
@@ -95,8 +106,10 @@ export const sendChannelMessage = defineAction({
95
106
  input: sendChannelInput,
96
107
  output: slackResponse,
97
108
  idempotent: false,
98
- options: { channel: channelOptions },
99
- async run({ client, input, req }) {
109
+ options: {
110
+ channel: channelOptions
111
+ },
112
+ async run ({ client, input, req }) {
100
113
  const token = input.sendAsBot ? 'bot' : 'user';
101
114
  if (input.file) {
102
115
  const file = await loadSlackFile(req, input.file);
@@ -105,11 +118,9 @@ export const sendChannelMessage = defineAction({
105
118
  file,
106
119
  channelId: input.channel,
107
120
  initialComment: input.text,
108
- threadTimestamp: input.threadTimestamp
109
- ? normalizeTimestamp(input.threadTimestamp)
110
- : undefined,
121
+ threadTimestamp: input.threadTimestamp ? normalizeTimestamp(input.threadTimestamp) : undefined,
111
122
  token,
112
- signal: req.signal,
123
+ signal: req.signal
113
124
  });
114
125
  }
115
126
  return client.request('chat.postMessage', {
@@ -121,15 +132,15 @@ export const sendChannelMessage = defineAction({
121
132
  icon_emoji: input.iconEmoji,
122
133
  reply_broadcast: input.replyBroadcast,
123
134
  unfurl_links: input.unfurlLinks,
124
- blocks: input.blocks,
135
+ blocks: input.blocks
125
136
  }, token);
126
- },
137
+ }
127
138
  });
128
139
  const addReactionInput = z.object({
129
140
  channel,
130
141
  timestamp,
131
142
  reaction: z.string().min(1),
132
- reactAsUser: z.boolean().default(false),
143
+ reactAsUser: z.boolean().default(false)
133
144
  });
134
145
  export const addReaction = defineAction({
135
146
  slug: 'addReaction',
@@ -137,20 +148,22 @@ export const addReaction = defineAction({
137
148
  input: addReactionInput,
138
149
  output: slackResponse,
139
150
  idempotent: true,
140
- options: { channel: channelOptions },
141
- async run({ client, input }) {
151
+ options: {
152
+ channel: channelOptions
153
+ },
154
+ async run ({ client, input }) {
142
155
  return client.request('reactions.add', {
143
156
  channel: input.channel,
144
157
  timestamp: normalizeTimestamp(input.timestamp),
145
- name: input.reaction,
158
+ name: input.reaction
146
159
  }, input.reactAsUser ? 'user' : 'bot');
147
- },
160
+ }
148
161
  });
149
162
  const uploadFileInput = z.object({
150
163
  file: slackFile,
151
164
  title: z.string().optional(),
152
165
  filename: z.string().optional(),
153
- channel: channel.optional(),
166
+ channel: channel.optional()
154
167
  });
155
168
  export const uploadFile = defineAction({
156
169
  slug: 'uploadFile',
@@ -158,65 +171,66 @@ export const uploadFile = defineAction({
158
171
  input: uploadFileInput,
159
172
  output: slackResponse,
160
173
  idempotent: false,
161
- options: { channel: channelOptions },
162
- async run({ client, input, req }) {
174
+ options: {
175
+ channel: channelOptions
176
+ },
177
+ async run ({ client, input, req }) {
163
178
  const loaded = await loadSlackFile(req, {
164
179
  ...input.file,
165
- name: input.filename ?? input.file.name,
180
+ name: input.filename ?? input.file.name
166
181
  });
167
182
  return upload({
168
183
  client,
169
184
  file: loaded,
170
185
  channelId: input.channel,
171
186
  title: input.title,
172
- signal: req.signal,
187
+ signal: req.signal
173
188
  });
174
- },
189
+ }
190
+ });
191
+ const getFileInput = z.object({
192
+ fileId: z.string().min(1)
175
193
  });
176
- const getFileInput = z.object({ fileId: z.string().min(1) });
177
194
  export const getFile = defineAction({
178
195
  slug: 'getFile',
179
196
  description: 'Get Slack file metadata and safely download its contents.',
180
197
  input: getFileInput,
181
198
  output: slackValue,
182
199
  idempotent: true,
183
- async run({ client, input, req }) {
184
- const response = await client.request('files.info', { file: input.fileId });
200
+ async run ({ client, input, req }) {
201
+ const response = await client.request('files.info', {
202
+ file: input.fileId
203
+ });
185
204
  const file = response.file;
186
- if (!file ||
187
- typeof file !== 'object' ||
188
- !('url_private_download' in file) ||
189
- typeof file.url_private_download !== 'string') {
205
+ if (!file || typeof file !== 'object' || !('url_private_download' in file) || typeof file.url_private_download !== 'string') {
190
206
  throw new Error('Slack file has no download URL.');
191
207
  }
192
208
  const url = new URL(file.url_private_download);
193
- if (url.protocol !== 'https:' ||
194
- url.hostname !== 'files.slack.com' ||
195
- url.username ||
196
- url.password) {
209
+ if (url.protocol !== 'https:' || url.hostname !== 'files.slack.com' || url.username || url.password) {
197
210
  throw new Error('Slack file download URL is untrusted.');
198
211
  }
199
212
  const downloaded = await fetch(url, {
200
- headers: { authorization: `Bearer ${client.token()}` },
213
+ headers: {
214
+ authorization: `Bearer ${client.token()}`
215
+ },
201
216
  redirect: 'error',
202
- signal: req.signal,
217
+ signal: req.signal
203
218
  });
204
- if (!downloaded.ok)
205
- throw new Error(`Slack file download failed (${downloaded.status}).`);
219
+ if (!downloaded.ok) throw new Error(`Slack file download failed (${downloaded.status}).`);
206
220
  const data = Buffer.from(await downloaded.arrayBuffer());
207
221
  const name = 'name' in file && typeof file.name === 'string' ? file.name : `slack-${input.fileId}`;
208
222
  const mimeType = downloaded.headers.get('content-type')?.split(';')[0] || 'application/octet-stream';
209
- const collection = req.frogbot.config.files?.slug;
210
- if (!collection) {
211
- throw new Error('[frogbot] Slack file downloads require the files collection.');
212
- }
223
+ filesCollectionSlug(req, 'Slack');
213
224
  req.signal?.throwIfAborted();
214
- const saved = await req.frogbot.create({
215
- collection,
216
- data: {},
217
- file: { data, name, mimetype: mimeType, size: data.length },
225
+ const saved = await createPieceFile(req, 'Slack', {
226
+ file: {
227
+ data,
228
+ name,
229
+ mimetype: mimeType,
230
+ size: data.length
231
+ },
218
232
  req,
219
- overrideAccess: false,
233
+ overrideAccess: false
220
234
  });
221
235
  return {
222
236
  ...file,
@@ -225,96 +239,104 @@ export const getFile = defineAction({
225
239
  name,
226
240
  mimeType,
227
241
  size: data.length,
228
- url: typeof saved.url === 'string' ? saved.url : undefined,
229
- },
242
+ url: typeof saved.url === 'string' ? saved.url : undefined
243
+ }
230
244
  };
231
- },
245
+ }
246
+ });
247
+ const searchMessagesInput = z.object({
248
+ query: z.string().min(1)
232
249
  });
233
- const searchMessagesInput = z.object({ query: z.string().min(1) });
234
250
  export const searchMessages = defineAction({
235
251
  slug: 'searchMessages',
236
252
  description: 'Search all Slack messages matching a query.',
237
253
  input: searchMessagesInput,
238
254
  output: slackValues,
239
255
  idempotent: true,
240
- async run({ client, input }) {
256
+ async run ({ client, input }) {
241
257
  const matches = [];
242
258
  let cursor = '*';
243
259
  do {
244
- const response = await client.request('search.messages', { query: input.query, count: 100, cursor }, 'user');
260
+ const response = await client.request('search.messages', {
261
+ query: input.query,
262
+ count: 100,
263
+ cursor
264
+ }, 'user');
245
265
  const messages = response.messages;
246
- if (!messages || typeof messages !== 'object')
247
- break;
266
+ if (!messages || typeof messages !== 'object') break;
248
267
  if ('matches' in messages && Array.isArray(messages.matches)) {
249
- for (const match of messages.matches) {
268
+ for (const match of messages.matches){
250
269
  if (match && typeof match === 'object' && !Array.isArray(match)) {
251
270
  matches.push(Object.fromEntries(Object.entries(match)));
252
271
  }
253
272
  }
254
273
  }
255
274
  const pagination = 'pagination' in messages ? messages.pagination : undefined;
256
- cursor =
257
- pagination && typeof pagination === 'object' && 'next_cursor' in pagination
258
- ? String(pagination.next_cursor || '') || undefined
259
- : undefined;
260
- } while (cursor);
275
+ cursor = pagination && typeof pagination === 'object' && 'next_cursor' in pagination ? String(pagination.next_cursor || '') || undefined : undefined;
276
+ }while (cursor)
261
277
  return matches;
262
- },
278
+ }
279
+ });
280
+ const emailInput = z.object({
281
+ email: z.email()
263
282
  });
264
- const emailInput = z.object({ email: z.email() });
265
283
  export const findUserByEmail = defineAction({
266
284
  slug: 'findUserByEmail',
267
285
  description: 'Find a Slack user by exact email address.',
268
286
  input: emailInput,
269
287
  output: slackResponse,
270
288
  idempotent: true,
271
- async run({ client, input }) {
289
+ async run ({ client, input }) {
272
290
  return client.request('users.lookupByEmail', input);
273
- },
291
+ }
292
+ });
293
+ const handleInput = z.object({
294
+ handle: z.string().min(1)
274
295
  });
275
- const handleInput = z.object({ handle: z.string().min(1) });
276
296
  export const findUserByHandle = defineAction({
277
297
  slug: 'findUserByHandle',
278
298
  description: 'Find a Slack user by display-name handle.',
279
299
  input: handleInput,
280
300
  output: slackValue,
281
301
  idempotent: true,
282
- async run({ client, input }) {
302
+ async run ({ client, input }) {
283
303
  const handle = input.handle.replace(/^@/, '');
284
304
  const members = await client.paginate({
285
305
  path: 'users.list',
286
306
  item: 'members',
287
- body: { limit: 1000 },
307
+ body: {
308
+ limit: 1000
309
+ }
288
310
  });
289
- const found = members.find((member) => {
290
- if (!member || typeof member !== 'object' || !('profile' in member))
291
- return false;
311
+ const found = members.find((member)=>{
312
+ if (!member || typeof member !== 'object' || !('profile' in member)) return false;
292
313
  const profile = member.profile;
293
- return (profile &&
294
- typeof profile === 'object' &&
295
- 'display_name' in profile &&
296
- profile.display_name === handle);
314
+ return profile && typeof profile === 'object' && 'display_name' in profile && profile.display_name === handle;
297
315
  });
298
316
  if (!found || typeof found !== 'object') {
299
317
  throw new Error(`Could not find user with handle @${handle}`);
300
318
  }
301
319
  return found;
302
- },
320
+ }
321
+ });
322
+ const findUserByIdInput = z.object({
323
+ id: z.string().min(1)
303
324
  });
304
- const findUserByIdInput = z.object({ id: z.string().min(1) });
305
325
  export const findUserById = defineAction({
306
326
  slug: 'findUserById',
307
327
  description: 'Find a Slack user profile by ID.',
308
328
  input: findUserByIdInput,
309
329
  output: slackResponse,
310
330
  idempotent: true,
311
- async run({ client, input }) {
312
- return client.request('users.profile.get', { user: input.id });
313
- },
331
+ async run ({ client, input }) {
332
+ return client.request('users.profile.get', {
333
+ user: input.id
334
+ });
335
+ }
314
336
  });
315
337
  const listUsersInput = z.object({
316
338
  includeBots: z.boolean().default(false),
317
- includeDisabled: z.boolean().default(false),
339
+ includeDisabled: z.boolean().default(false)
318
340
  });
319
341
  export const listUsers = defineAction({
320
342
  slug: 'listUsers',
@@ -322,60 +344,79 @@ export const listUsers = defineAction({
322
344
  input: listUsersInput,
323
345
  output: slackValues,
324
346
  idempotent: true,
325
- async run({ client, input }) {
347
+ async run ({ client, input }) {
326
348
  const members = await client.paginate({
327
349
  path: 'users.list',
328
350
  item: 'members',
329
- body: { limit: 1000 },
351
+ body: {
352
+ limit: 1000
353
+ }
330
354
  });
331
- return members.filter((member) => {
332
- if (!member || typeof member !== 'object')
333
- return false;
334
- if (!input.includeBots && 'is_bot' in member && member.is_bot === true)
335
- return false;
336
- if (!input.includeDisabled && 'deleted' in member && member.deleted === true)
337
- return false;
355
+ return members.filter((member)=>{
356
+ if (!member || typeof member !== 'object') return false;
357
+ if (!input.includeBots && 'is_bot' in member && member.is_bot === true) return false;
358
+ if (!input.includeDisabled && 'deleted' in member && member.deleted === true) return false;
338
359
  return true;
339
360
  });
340
- },
361
+ }
362
+ });
363
+ const updateMessageInput = z.object({
364
+ channel,
365
+ timestamp,
366
+ text: z.string().min(1),
367
+ blocks
341
368
  });
342
- const updateMessageInput = z.object({ channel, timestamp, text: z.string().min(1), blocks });
343
369
  export const updateMessage = defineAction({
344
370
  slug: 'updateMessage',
345
371
  description: 'Update an existing Slack message.',
346
372
  input: updateMessageInput,
347
373
  output: slackResponse,
348
374
  idempotent: true,
349
- options: { channel: channelOptions },
350
- async run({ client, input }) {
375
+ options: {
376
+ channel: channelOptions
377
+ },
378
+ async run ({ client, input }) {
351
379
  return client.request('chat.update', {
352
380
  channel: input.channel,
353
381
  ts: normalizeTimestamp(input.timestamp),
354
382
  text: input.text,
355
- blocks: input.blocks,
383
+ blocks: input.blocks
356
384
  });
357
- },
385
+ }
386
+ });
387
+ const deleteMessageInput = z.object({
388
+ channel,
389
+ timestamp
358
390
  });
359
- const deleteMessageInput = z.object({ channel, timestamp });
360
391
  export const deleteMessage = defineAction({
361
392
  slug: 'deleteMessage',
362
393
  description: 'Delete a Slack message after confirming it exists.',
363
394
  input: deleteMessageInput,
364
395
  output: slackResponse,
365
396
  idempotent: false,
366
- options: { channel: channelOptions },
367
- async run({ client, input }) {
397
+ options: {
398
+ channel: channelOptions
399
+ },
400
+ async run ({ client, input }) {
368
401
  const ts = normalizeTimestamp(input.timestamp);
369
- const history = await client.request('conversations.history', { channel: input.channel, oldest: ts, limit: 1, inclusive: true }, 'user');
402
+ const history = await client.request('conversations.history', {
403
+ channel: input.channel,
404
+ oldest: ts,
405
+ limit: 1,
406
+ inclusive: true
407
+ }, 'user');
370
408
  if (!Array.isArray(history.messages) || history.messages.length === 0) {
371
409
  throw new Error('No message found for the provided timestamp.');
372
410
  }
373
- return client.request('chat.delete', { channel: input.channel, ts }, 'user');
374
- },
411
+ return client.request('chat.delete', {
412
+ channel: input.channel,
413
+ ts
414
+ }, 'user');
415
+ }
375
416
  });
376
417
  const createChannelInput = z.object({
377
418
  channelName: z.string().min(1),
378
- isPrivate: z.boolean().default(false),
419
+ isPrivate: z.boolean().default(false)
379
420
  });
380
421
  export const createChannel = defineAction({
381
422
  slug: 'createChannel',
@@ -383,18 +424,18 @@ export const createChannel = defineAction({
383
424
  input: createChannelInput,
384
425
  output: slackResponse,
385
426
  idempotent: false,
386
- async run({ client, input }) {
427
+ async run ({ client, input }) {
387
428
  return client.request('conversations.create', {
388
429
  name: input.channelName,
389
- is_private: input.isPrivate,
430
+ is_private: input.isPrivate
390
431
  });
391
- },
432
+ }
392
433
  });
393
434
  const updateProfileInput = z.object({
394
435
  firstName: z.string().optional(),
395
436
  lastName: z.string().optional(),
396
437
  email: z.email().optional(),
397
- userId: z.string().optional(),
438
+ userId: z.string().optional()
398
439
  });
399
440
  export const updateProfile = defineAction({
400
441
  slug: 'updateProfile',
@@ -402,19 +443,23 @@ export const updateProfile = defineAction({
402
443
  input: updateProfileInput,
403
444
  output: slackResponse,
404
445
  idempotent: true,
405
- async run({ client, input }) {
446
+ async run ({ client, input }) {
406
447
  return client.request('users.profile.set', {
407
- profile: { first_name: input.firstName, last_name: input.lastName, email: input.email },
408
- user: input.userId,
448
+ profile: {
449
+ first_name: input.firstName,
450
+ last_name: input.lastName,
451
+ email: input.email
452
+ },
453
+ user: input.userId
409
454
  }, 'user');
410
- },
455
+ }
411
456
  });
412
457
  const getChannelHistoryInput = z.object({
413
458
  channel,
414
459
  oldest: z.number().optional(),
415
460
  latest: z.number().optional(),
416
461
  inclusive: z.boolean().default(false),
417
- includeAllMetadata: z.boolean().default(false),
462
+ includeAllMetadata: z.boolean().default(false)
418
463
  });
419
464
  export const getChannelHistory = defineAction({
420
465
  slug: 'getChannelHistory',
@@ -422,8 +467,10 @@ export const getChannelHistory = defineAction({
422
467
  input: getChannelHistoryInput,
423
468
  output: slackValues,
424
469
  idempotent: true,
425
- options: { channel: channelOptions },
426
- async run({ client, input }) {
470
+ options: {
471
+ channel: channelOptions
472
+ },
473
+ async run ({ client, input }) {
427
474
  return client.paginate({
428
475
  path: 'conversations.history',
429
476
  item: 'messages',
@@ -433,15 +480,15 @@ export const getChannelHistory = defineAction({
433
480
  latest: input.latest,
434
481
  inclusive: input.inclusive,
435
482
  include_all_metadata: input.includeAllMetadata,
436
- limit: 200,
437
- },
483
+ limit: 200
484
+ }
438
485
  });
439
- },
486
+ }
440
487
  });
441
488
  const setUserStatusInput = z.object({
442
489
  text: z.string().max(100),
443
490
  emoji: z.string().optional(),
444
- expiration: z.number().int().optional(),
491
+ expiration: z.number().int().optional()
445
492
  });
446
493
  export const setUserStatus = defineAction({
447
494
  slug: 'setUserStatus',
@@ -449,88 +496,118 @@ export const setUserStatus = defineAction({
449
496
  input: setUserStatusInput,
450
497
  output: slackResponse,
451
498
  idempotent: true,
452
- async run({ client, input }) {
499
+ async run ({ client, input }) {
453
500
  return client.request('users.profile.set', {
454
501
  profile: {
455
502
  status_text: input.text,
456
503
  status_emoji: input.emoji,
457
- status_expiration: input.expiration,
458
- },
504
+ status_expiration: input.expiration
505
+ }
459
506
  }, 'user');
460
- },
507
+ }
508
+ });
509
+ const markdownToSlackInput = z.object({
510
+ markdown: z.string()
511
+ });
512
+ const markdownToSlackOutput = z.object({
513
+ text: z.string()
461
514
  });
462
- const markdownToSlackInput = z.object({ markdown: z.string() });
463
- const markdownToSlackOutput = z.object({ text: z.string() });
464
515
  export const markdownToSlack = defineAction({
465
516
  slug: 'markdownToSlack',
466
517
  description: 'Convert Markdown text to Slack mrkdwn.',
467
518
  input: markdownToSlackInput,
468
519
  output: markdownToSlackOutput,
469
520
  idempotent: true,
470
- async run({ input }) {
471
- const text = input.markdown
472
- .replace(/\[([^\]]+)]\((https?:\/\/[^)]+)\)/g, '<$2|$1>')
473
- .replace(/\*\*([^*]+)\*\*/g, '*$1*')
474
- .replace(/^[-+] /gm, '• ');
475
- return { text };
476
- },
521
+ run ({ input }) {
522
+ const text = input.markdown.replace(/\[([^\]]+)]\((https?:\/\/[^)]+)\)/g, '<$2|$1>').replace(/\*\*([^*]+)\*\*/g, '*$1*').replace(/^[-+] /gm, '• ');
523
+ return Promise.resolve({
524
+ text
525
+ });
526
+ }
527
+ });
528
+ const listThreadMessagesInput = z.object({
529
+ channel,
530
+ threadTimestamp: timestamp
477
531
  });
478
- const listThreadMessagesInput = z.object({ channel, threadTimestamp: timestamp });
479
532
  export const listThreadMessages = defineAction({
480
533
  slug: 'listThreadMessages',
481
534
  description: 'Retrieve all messages in a Slack thread.',
482
535
  input: listThreadMessagesInput,
483
536
  output: slackValues,
484
537
  idempotent: true,
485
- options: { channel: channelOptions },
486
- async run({ client, input }) {
538
+ options: {
539
+ channel: channelOptions
540
+ },
541
+ async run ({ client, input }) {
487
542
  return client.paginate({
488
543
  path: 'conversations.replies',
489
544
  item: 'messages',
490
- body: { channel: input.channel, ts: normalizeTimestamp(input.threadTimestamp) },
545
+ body: {
546
+ channel: input.channel,
547
+ ts: normalizeTimestamp(input.threadTimestamp)
548
+ }
491
549
  });
492
- },
550
+ }
551
+ });
552
+ const setChannelTopicInput = z.object({
553
+ channel,
554
+ topic: z.string()
493
555
  });
494
- const setChannelTopicInput = z.object({ channel, topic: z.string() });
495
556
  export const setChannelTopic = defineAction({
496
557
  slug: 'setChannelTopic',
497
558
  description: 'Set a Slack channel topic.',
498
559
  input: setChannelTopicInput,
499
560
  output: slackResponse,
500
561
  idempotent: true,
501
- options: { channel: channelOptions },
502
- async run({ client, input }) {
503
- return client.request('conversations.setTopic', input);
562
+ options: {
563
+ channel: channelOptions
504
564
  },
565
+ async run ({ client, input }) {
566
+ return client.request('conversations.setTopic', input);
567
+ }
568
+ });
569
+ const getMessageInput = z.object({
570
+ channel,
571
+ timestamp
505
572
  });
506
- const getMessageInput = z.object({ channel, timestamp });
507
573
  export const getMessage = defineAction({
508
574
  slug: 'getMessage',
509
575
  description: 'Get a Slack message by channel and timestamp.',
510
576
  input: getMessageInput,
511
577
  output: slackResponse,
512
578
  idempotent: true,
513
- options: { channel: channelOptions },
514
- async run({ client, input }) {
579
+ options: {
580
+ channel: channelOptions
581
+ },
582
+ async run ({ client, input }) {
515
583
  return client.request('conversations.history', {
516
584
  channel: input.channel,
517
585
  oldest: normalizeTimestamp(input.timestamp),
518
586
  limit: 1,
519
- inclusive: true,
587
+ inclusive: true
520
588
  });
521
- },
589
+ }
590
+ });
591
+ const inviteUserToChannelInput = z.object({
592
+ channel,
593
+ userId: user
522
594
  });
523
- const inviteUserToChannelInput = z.object({ channel, userId: user });
524
595
  export const inviteUserToChannel = defineAction({
525
596
  slug: 'inviteUserToChannel',
526
597
  description: 'Invite an existing user to a Slack channel.',
527
598
  input: inviteUserToChannelInput,
528
599
  output: slackResponse,
529
600
  idempotent: false,
530
- options: { channel: channelOptions, userId: userOptions },
531
- async run({ client, input }) {
532
- return client.request('conversations.invite', { channel: input.channel, users: input.userId });
601
+ options: {
602
+ channel: channelOptions,
603
+ userId: userOptions
533
604
  },
605
+ async run ({ client, input }) {
606
+ return client.request('conversations.invite', {
607
+ channel: input.channel,
608
+ users: input.userId
609
+ });
610
+ }
534
611
  });
535
612
  export const getUserGroupByHandle = defineAction({
536
613
  slug: 'getUserGroupByHandle',
@@ -538,18 +615,15 @@ export const getUserGroupByHandle = defineAction({
538
615
  input: handleInput,
539
616
  output: slackValue,
540
617
  idempotent: true,
541
- async run({ client, input }) {
618
+ async run ({ client, input }) {
542
619
  return findUserGroup(client, input.handle);
543
- },
620
+ }
544
621
  });
545
622
  async function findUserGroup(client, value) {
546
623
  const handle = value.replace(/^@/, '').toLowerCase();
547
624
  const response = await client.request('usergroups.list');
548
625
  const groups = Array.isArray(response.usergroups) ? response.usergroups : [];
549
- const found = groups.find((group) => group &&
550
- typeof group === 'object' &&
551
- 'handle' in group &&
552
- String(group.handle).toLowerCase() === handle);
626
+ const found = groups.find((group)=>group && typeof group === 'object' && 'handle' in group && String(group.handle).toLowerCase() === handle);
553
627
  if (!found || typeof found !== 'object') {
554
628
  throw new Error(`User group with handle '@${handle}' not found.`);
555
629
  }
@@ -557,7 +631,7 @@ async function findUserGroup(client, value) {
557
631
  }
558
632
  const updateUserGroupMembersInput = handleInput.extend({
559
633
  userIds: z.array(z.string()).optional(),
560
- appendUsers: z.boolean().default(true),
634
+ appendUsers: z.boolean().default(true)
561
635
  });
562
636
  export const updateUserGroupMembers = defineAction({
563
637
  slug: 'updateUserGroupMembers',
@@ -565,23 +639,39 @@ export const updateUserGroupMembers = defineAction({
565
639
  input: updateUserGroupMembersInput,
566
640
  output: slackResponse,
567
641
  idempotent: false,
568
- async run({ client, input }) {
642
+ async run ({ client, input }) {
569
643
  const group = await findUserGroup(client, input.handle);
570
644
  const id = 'id' in group ? String(group.id) : '';
571
- const existing = input.appendUsers && 'users' in group && Array.isArray(group.users)
572
- ? group.users.map(String)
573
- : [];
574
- const users = [...new Set([...existing, ...(input.userIds ?? []).filter(Boolean)])].join(', ');
575
- return client.request('usergroups.users.update', { usergroup: id, users }, 'user');
576
- },
645
+ const existing = input.appendUsers && 'users' in group && Array.isArray(group.users) ? group.users.map(String) : [];
646
+ const users = [
647
+ ...new Set([
648
+ ...existing,
649
+ ...(input.userIds ?? []).filter(Boolean)
650
+ ])
651
+ ].join(', ');
652
+ return client.request('usergroups.users.update', {
653
+ usergroup: id,
654
+ users
655
+ }, 'user');
656
+ }
577
657
  });
578
658
  const customApiInput = z.object({
579
- method: z.enum(['GET', 'POST', 'PUT', 'PATCH', 'DELETE']),
659
+ method: z.enum([
660
+ 'GET',
661
+ 'POST',
662
+ 'PUT',
663
+ 'PATCH',
664
+ 'DELETE'
665
+ ]),
580
666
  path: z.string().regex(/^[a-zA-Z][a-zA-Z0-9._-]*$/),
581
667
  headers: z.record(z.string(), z.string()).default({}),
582
- queryParams: z.record(z.string(), z.union([z.string(), z.number(), z.boolean()])).default({}),
668
+ queryParams: z.record(z.string(), z.union([
669
+ z.string(),
670
+ z.number(),
671
+ z.boolean()
672
+ ])).default({}),
583
673
  body: z.record(z.string(), z.unknown()).optional(),
584
- useUserToken: z.boolean().default(false),
674
+ useUserToken: z.boolean().default(false)
585
675
  });
586
676
  export const customApiCall = defineAction({
587
677
  slug: 'customApiCall',
@@ -589,10 +679,9 @@ export const customApiCall = defineAction({
589
679
  input: customApiInput,
590
680
  output: slackApiResult,
591
681
  idempotent: false,
592
- async run({ client, input }) {
682
+ async run ({ client, input }) {
593
683
  const query = new URLSearchParams();
594
- for (const [key, value] of Object.entries(input.queryParams))
595
- query.set(key, String(value));
684
+ for (const [key, value] of Object.entries(input.queryParams))query.set(key, String(value));
596
685
  const suffix = query.size ? `?${query}` : '';
597
686
  const headers = new Headers(input.headers);
598
687
  headers.delete('authorization');
@@ -606,9 +695,9 @@ export const customApiCall = defineAction({
606
695
  method: input.method,
607
696
  headers,
608
697
  body: input.body === undefined ? undefined : JSON.stringify(input.body),
609
- token: input.useUserToken ? 'user' : 'bot',
698
+ token: input.useUserToken ? 'user' : 'bot'
610
699
  });
611
- },
700
+ }
612
701
  });
613
702
  export const slackActions = [
614
703
  addReaction,
@@ -634,6 +723,7 @@ export const slackActions = [
634
723
  inviteUserToChannel,
635
724
  getUserGroupByHandle,
636
725
  updateUserGroupMembers,
637
- customApiCall,
726
+ customApiCall
638
727
  ];
728
+
639
729
  //# sourceMappingURL=actions.js.map