@pipedream/slack 0.3.2 → 0.4.1

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 (50) hide show
  1. package/actions/add-star/add-star.mjs +43 -0
  2. package/actions/archive-channel/archive-channel.mjs +23 -0
  3. package/actions/common/send-message.mjs +170 -0
  4. package/actions/complete-reminder/complete-reminder.mjs +23 -0
  5. package/actions/create-channel/create-channel.mjs +30 -0
  6. package/actions/create-reminder/create-reminder.mjs +47 -0
  7. package/actions/delete-file/delete-file.mjs +23 -0
  8. package/actions/delete-message/delete-message.mjs +38 -0
  9. package/actions/delete_reminder/delete-reminder.mjs +23 -0
  10. package/actions/find-message/find-message.mjs +38 -0
  11. package/actions/find-user-by-email/find-user-by-email.mjs +23 -0
  12. package/actions/get-channel/get-channel.mjs +23 -0
  13. package/actions/get-file/get-file.mjs +30 -0
  14. package/actions/get-reminder/get-reminder.mjs +23 -0
  15. package/actions/invite-user-to-channel/invite-user-to-channel.mjs +31 -0
  16. package/actions/join-channel/join-channel.mjs +23 -0
  17. package/actions/kick-user/kick-user.mjs +30 -0
  18. package/actions/leave-channel/leave-channel.mjs +23 -0
  19. package/actions/list-channels/list-channels.mjs +15 -0
  20. package/actions/list-files/list-files.mjs +47 -0
  21. package/actions/list-members-in-channel/list-members-in-channel.mjs +23 -0
  22. package/actions/list-reminders/list-reminders.mjs +24 -0
  23. package/actions/list-replies/list-replies.mjs +30 -0
  24. package/actions/list-users/list-users.mjs +22 -0
  25. package/actions/remove-star/remove-star.mjs +40 -0
  26. package/actions/reply-to-a-message-thread/reply-to-a-message-thread.mjs +41 -0
  27. package/actions/send-block-kit-message/send-block-kit-message.mjs +33 -0
  28. package/actions/send-custom-message/send-custom-message.mjs +79 -0
  29. package/actions/send-direct-message/send-direct-message.mjs +52 -0
  30. package/actions/send-group-message/send-group-message.mjs +52 -0
  31. package/actions/send-large-message/send-large-message.mjs +91 -0
  32. package/actions/send-message-private-channel/send-message-private-channel.mjs +52 -0
  33. package/actions/send-message-public-channel/send-message-public-channel.mjs +52 -0
  34. package/actions/set-channel-topic/set-channel-topic.mjs +30 -0
  35. package/actions/set-purpose-of-channel/set-purpose-of-channel.mjs +30 -0
  36. package/actions/unarchive-channel/unarchive-channel.mjs +23 -0
  37. package/actions/update-message/update-message.mjs +52 -0
  38. package/actions/update-profile/update-profile.mjs +30 -0
  39. package/actions/upload-file/upload-file.mjs +38 -0
  40. package/package.json +19 -16
  41. package/slack.app.mjs +544 -0
  42. package/sources/common/base.mjs +97 -0
  43. package/sources/common/constants.mjs +30 -0
  44. package/sources/new-direct-message/new-direct-message.mjs +51 -0
  45. package/sources/new-mention/new-mention.mjs +95 -0
  46. package/sources/new-message-in-channels/new-message-in-channels.mjs +84 -0
  47. package/sources/new-reaction-added/new-reaction-added.mjs +65 -0
  48. package/sources/new-star-added/new-star-added.mjs +46 -0
  49. package/slack.app.js +0 -48
  50. package/sources/new-message-in-channels/new-message-in-channels.js +0 -151
package/slack.app.mjs ADDED
@@ -0,0 +1,544 @@
1
+ import { WebClient } from "@slack/web-api";
2
+
3
+ export default {
4
+ type: "app",
5
+ app: "slack",
6
+ propDefinitions: {
7
+ publicChannel: {
8
+ type: "string",
9
+ label: "Channel",
10
+ description: "Select a public channel",
11
+ async options({ prevContext }) {
12
+ const { cursor } = prevContext;
13
+ const types = [
14
+ "public_channel",
15
+ ];
16
+ const resp = await this.availableConversations(types.join(), cursor);
17
+ return {
18
+ options: resp.conversations.map((c) => ({
19
+ label: `${c.name}`,
20
+ value: c.id,
21
+ })),
22
+ context: {
23
+ cursor: resp.cursor,
24
+ },
25
+ };
26
+ },
27
+ },
28
+ privateChannel: {
29
+ type: "string",
30
+ label: "Channel",
31
+ description: "Select a private channel",
32
+ async options({ prevContext }) {
33
+ const { cursor } = prevContext;
34
+ const types = [
35
+ "private_channel",
36
+ ];
37
+ const resp = await this.availableConversations(types.join(), cursor);
38
+ return {
39
+ options: resp.conversations.map((c) => ({
40
+ label: `${c.name}`,
41
+ value: c.id,
42
+ })),
43
+ context: {
44
+ cursor: resp.cursor,
45
+ },
46
+ };
47
+ },
48
+ },
49
+ user: {
50
+ type: "string",
51
+ label: "User",
52
+ description: "Select a user",
53
+ async options({ prevContext }) {
54
+ const types = [
55
+ "im",
56
+ ];
57
+ const [
58
+ userNames,
59
+ conversationsResp,
60
+ ] = await Promise.all([
61
+ prevContext.userNames ?? this.userNames(),
62
+ this.availableConversations(types.join(), prevContext.cursor),
63
+ ]);
64
+ return {
65
+ options: conversationsResp.conversations.map((c) => ({
66
+ label: `@${userNames[c.user]}`,
67
+ value: c.id,
68
+ })),
69
+ context: {
70
+ userNames,
71
+ cursor: conversationsResp.cursor,
72
+ },
73
+ };
74
+ },
75
+ },
76
+ group: {
77
+ type: "string",
78
+ label: "Group",
79
+ description: "Select a group",
80
+ async options({ prevContext }) {
81
+ let { cursor } = prevContext;
82
+ const types = [
83
+ "mpim",
84
+ ];
85
+ const resp = await this.availableConversations(types.join(), cursor);
86
+ return {
87
+ options: resp.conversations.map((c) => {
88
+ return {
89
+ label: c.purpose.value,
90
+ value: c.id,
91
+ };
92
+ }),
93
+ context: {
94
+ cursor: resp.cursor,
95
+ },
96
+ };
97
+ },
98
+ },
99
+ reminder: {
100
+ type: "string",
101
+ label: "Reminder",
102
+ description: "Select a reminder",
103
+ async options({ prevContext }) {
104
+ let { cursor } = prevContext;
105
+ let resp = await this.getRemindersForTeam();
106
+ return {
107
+ options: resp.reminders.map((c) => {
108
+ return {
109
+ label: c.text,
110
+ value: c.id,
111
+ };
112
+ }),
113
+ context: {
114
+ cursor: cursor,
115
+ },
116
+ };
117
+ },
118
+ },
119
+ conversation: {
120
+ type: "string",
121
+ label: "Channel",
122
+ description: "Select a public or private channel, or a user or group",
123
+ async options({ prevContext }) {
124
+ let {
125
+ types,
126
+ cursor,
127
+ userNames: userNamesOrPromise,
128
+ } = prevContext;
129
+ if (types == null) {
130
+ const scopes = await this.scopes();
131
+ types = [
132
+ "public_channel",
133
+ ];
134
+ if (scopes.includes("groups:read")) {
135
+ types.push("private_channel");
136
+ }
137
+ if (scopes.includes("mpim:read")) {
138
+ types.push("mpim");
139
+ }
140
+ if (scopes.includes("im:read")) {
141
+ types.push("im");
142
+ userNamesOrPromise = this.userNames();
143
+ }
144
+ }
145
+ const [
146
+ userNames,
147
+ conversationsResp,
148
+ ] = await Promise.all([
149
+ userNamesOrPromise,
150
+ this.availableConversations(types.join(), cursor),
151
+ ]);
152
+ return {
153
+ options: conversationsResp.conversations.map((c) => {
154
+ if (c.is_im) {
155
+ return {
156
+ label: `Direct messaging with: @${userNames[c.user]}`,
157
+ value: c.id,
158
+ };
159
+ } else if (c.is_mpim) {
160
+ return {
161
+ label: c.purpose.value,
162
+ value: c.id,
163
+ };
164
+ } else {
165
+ return {
166
+ label: `${c.is_private
167
+ ? "Private"
168
+ : "Public"} channel: ${c.name}`,
169
+ value: c.id,
170
+ };
171
+ }
172
+ }),
173
+ context: {
174
+ types,
175
+ cursor: conversationsResp.cursor,
176
+ userNames,
177
+ },
178
+ };
179
+ },
180
+ },
181
+ team: {
182
+ type: "string",
183
+ label: "Team",
184
+ description: "Select a team.",
185
+ async options({ prevContext }) {
186
+ let { cursor } = prevContext;
187
+
188
+ const resp = await this.getTeams(cursor);
189
+
190
+ return {
191
+ options: resp.teams.map((team) => ({
192
+ label: team.name,
193
+ value: team.id,
194
+ })),
195
+
196
+ context: {
197
+ cursor: resp.cursor,
198
+ },
199
+ };
200
+ },
201
+ },
202
+ notificationText: {
203
+ type: "string",
204
+ label: "Notification Text",
205
+ description: "Optionally provide a string for Slack to display as the new message notification (if you do not provide this, notification will be blank).",
206
+ optional: true,
207
+ },
208
+ text: {
209
+ type: "string",
210
+ label: "Text",
211
+ description: "Text of the message to send (see Slack's [formatting docs](https://api.slack.com/reference/surfaces/formatting)). This field is usually necessary, unless you're providing only attachments instead.",
212
+ },
213
+ name: {
214
+ type: "string",
215
+ label: "Name",
216
+ description: "Name of a single key to set.",
217
+ },
218
+ value: {
219
+ type: "string",
220
+ label: "Value",
221
+ description: "Value to set a single key to.",
222
+ },
223
+ topic: {
224
+ type: "string",
225
+ label: "Topic",
226
+ description: "Text of the new channel topic.",
227
+ },
228
+ purpose: {
229
+ type: "string",
230
+ label: "Purpose",
231
+ description: "Text of the new channel purpose.",
232
+ },
233
+ query: {
234
+ type: "string",
235
+ label: "Query",
236
+ description: "Search query.",
237
+ },
238
+ team_id: {
239
+ type: "string",
240
+ label: "Team ID",
241
+ description: "The ID of the team.",
242
+ },
243
+ file: {
244
+ type: "string",
245
+ label: "File ID",
246
+ description: "Specify a file by providing its ID.",
247
+ },
248
+ attachments: {
249
+ type: "string",
250
+ label: "Attachments",
251
+ description: "A JSON-based array of structured attachments, presented as a URL-encoded string (e.g., `[{\"pretext\": \"pre-hello\", \"text\": \"text-world\"}]`).",
252
+ optional: true,
253
+ },
254
+ unfurl_links: {
255
+ type: "boolean",
256
+ label: "Unfurl Links",
257
+ description: "`TRUE` by default. Pass `FALSE` to disable unfurling of links.",
258
+ optional: true,
259
+ },
260
+ unfurl_media: {
261
+ type: "boolean",
262
+ label: "Unful Media",
263
+ description: "`TRUE` by default. Pass `FALSE` to disable unfurling of media content.",
264
+ optional: true,
265
+ },
266
+ parse: {
267
+ type: "string",
268
+ label: "Parse",
269
+ description: "Change how messages are treated. Defaults to none. See below.",
270
+ optional: true,
271
+ },
272
+ as_user: {
273
+ type: "boolean",
274
+ label: "Send as User",
275
+ description: "Optionally pass `TRUE` to post the message as the authed user, instead of as a bot. Defaults to `FALSE`.",
276
+ default: false,
277
+ optional: true,
278
+ },
279
+ mrkdwn: {
280
+ label: "Send text as Slack mrkdwn",
281
+ type: "boolean",
282
+ description: "`TRUE` by default. Pass `FALSE` to disable Slack markup parsing. [See docs here](https://api.slack.com/reference/surfaces/formatting)",
283
+ default: true,
284
+ optional: true,
285
+ },
286
+ post_at: {
287
+ label: "Schedule message",
288
+ description: "Messages can only be scheduled up to 120 days in advance, and cannot be scheduled for the past. The datetime format should be a unix timestamp (e.g., `1650507616`, [see here](https://www.epochconverter.com/) for help with this format).",
289
+ type: "integer",
290
+ optional: true,
291
+ },
292
+ username: {
293
+ type: "string",
294
+ label: "Bot Username",
295
+ description: "Optionally customize your bot's user name (default is `Pipedream`). Must be used in conjunction with `as_user` set to false, otherwise ignored.",
296
+ optional: true,
297
+ },
298
+ blocks: {
299
+ type: "string",
300
+ label: "Blocks",
301
+ description: "Enter an array of [structured blocks](https://app.slack.com/block-kit-builder) as a URL-encoded string. E.g., `[{ \"type\": \"section\", \"text\": { \"type\": \"mrkdwn\", \"text\": \"This is a mrkdwn section block :ghost: *this is bold*, and ~this is crossed out~, and <https://pipedream.com|this is a link>\" }}]`\n\n**Tip:** Construct your blocks in a code step, return them as an array, and then pass the return value to this step.",
302
+ optional: true,
303
+ },
304
+ icon_emoji: {
305
+ type: "string",
306
+ label: "Icon (emoji)",
307
+ description: "Optionally provide an emoji to use as the icon for this message. E.g., `:fire:` Overrides `icon_url`. Must be used in conjunction with `as_user` set to `false`, otherwise ignored.",
308
+ optional: true,
309
+ },
310
+ content: {
311
+ label: "Content",
312
+ type: "string",
313
+ description: "File contents via a POST variable.",
314
+ },
315
+ link_names: {
316
+ type: "string",
317
+ label: "Link Names",
318
+ description: "Find and link channel names and usernames.",
319
+ optional: true,
320
+ },
321
+ reply_broadcast: {
322
+ type: "string",
323
+ label: "Reply Broadcasts",
324
+ description: "Used in conjunction with thread_ts and indicates whether reply should be made visible to everyone in the channel or conversation. Defaults to false.",
325
+ optional: true,
326
+ },
327
+ reply_channel: {
328
+ label: "Reply Channel or Conversation ID",
329
+ type: "string",
330
+ description: "Provide the channel or conversation ID for the thread to reply to (e.g., if triggering on new Slack messages, enter `{{event.channel}}`). If the channel does not match the thread timestamp, a new message will be posted to this channel.",
331
+ optional: true,
332
+ },
333
+ thread_ts: {
334
+ label: "Thread Timestamp",
335
+ type: "string",
336
+ description: "Provide another message's `ts` value to make this message a reply (e.g., if triggering on new Slack messages, enter `{{event.ts}}`). Avoid using a reply's `ts` value; use its parent instead.",
337
+ optional: true,
338
+ },
339
+ timestamp: {
340
+ label: "Timestamp",
341
+ type: "string",
342
+ description: "Timestamp of the relevant data.",
343
+ optional: true,
344
+ },
345
+ icon_url: {
346
+ type: "string",
347
+ label: "Icon (image URL)",
348
+ description: "Optionally provide an image URL to use as the icon for this message. Must be used in conjunction with `as_user` set to `false`, otherwise ignored.",
349
+ optional: true,
350
+ },
351
+ initial_comment: {
352
+ type: "string",
353
+ label: "Initial Comment",
354
+ description: "The message text introducing the file",
355
+ optional: true,
356
+ },
357
+ count: {
358
+ type: "integer",
359
+ label: "Count",
360
+ description: "Number of items to return per page.",
361
+ optional: true,
362
+ },
363
+ email: {
364
+ type: "string",
365
+ label: "Email",
366
+ description: "An email address belonging to a user in the workspace",
367
+ },
368
+ metadata_event_type: {
369
+ type: "string",
370
+ label: "Metadata Event Type",
371
+ description: "The name of the metadata event",
372
+ optional: true,
373
+ },
374
+ metadata_event_payload: {
375
+ type: "string",
376
+ label: "Metadata Event Payload",
377
+ description: "The payload of the metadata event. Must be a JSON string e.g. `{\"key\": \"value\"}`",
378
+ optional: true,
379
+ },
380
+ ignoreMyself: {
381
+ type: "boolean",
382
+ label: "Ignore myself",
383
+ description: "Ignore messages from me",
384
+ default: false,
385
+ },
386
+ keyword: {
387
+ type: "string",
388
+ label: "Keyword",
389
+ description: "Keyword to monitor",
390
+ },
391
+ isUsername: {
392
+ type: "boolean",
393
+ label: "Is Username",
394
+ description: "Filters out mentions of the keyword that are not a username",
395
+ default: false,
396
+ optional: true,
397
+ },
398
+ ignoreBot: {
399
+ type: "boolean",
400
+ label: "Ignore Bots",
401
+ description: "Ignore messages from bots",
402
+ default: false,
403
+ optional: true
404
+ },
405
+ resolveNames: {
406
+ type: "boolean",
407
+ label: "Resolve Names",
408
+ description: "Instead of returning `channel`, `team`, and `user` as IDs, return their human-readable names.",
409
+ default: false,
410
+ optional: true
411
+ },
412
+ },
413
+ methods: {
414
+ mySlackId() {
415
+ return this.$auth.oauth_uid;
416
+ },
417
+ /**
418
+ * Returns a Slack Web Client object authenticated with the user's access
419
+ * token
420
+ */
421
+ sdk() {
422
+ return new WebClient(this.$auth.oauth_access_token);
423
+ },
424
+ /**
425
+ * This method returns the list of OAuth scopes the current authenticated
426
+ * user has
427
+ *
428
+ * @returns the list of scopes
429
+ */
430
+ async scopes() {
431
+ const resp = await this.sdk().auth.test();
432
+ if (resp.ok) {
433
+ return resp.response_metadata.scopes;
434
+ } else {
435
+ console.log("Error getting scopes", resp.error);
436
+ throw (resp.error);
437
+ }
438
+ },
439
+ /**
440
+ * Returns a list of channel-like conversations in a workspace. The
441
+ * "channels" returned depend on what the calling token has access to and
442
+ * the directives placed in the types parameter.
443
+ *
444
+ * @param {string} [types] - a comma-separated list of channel types to get.
445
+ * Any combination of: `public_channel`, `private_channel`, `mpim`, `im`
446
+ * @param {string} [cursor] - a cursor returned by the previous API call,
447
+ * used to paginate through collections of data
448
+ * @returns an object containing a list of conversations and the cursor for the next
449
+ * page of conversations
450
+ */
451
+ async availableConversations(types, cursor) {
452
+ const params = {
453
+ types,
454
+ cursor,
455
+ limit: 200,
456
+ exclude_archived: true,
457
+ user: this.$auth.oauth_uid,
458
+ };
459
+ const resp = await this.sdk().users.conversations(params);
460
+ if (resp.ok) {
461
+ return {
462
+ cursor: resp.response_metadata.next_cursor,
463
+ conversations: resp.channels,
464
+ };
465
+ } else {
466
+ console.log("Error getting conversations", resp.error);
467
+ throw (resp.error);
468
+ }
469
+ },
470
+ /**
471
+ * This method lists reminders created by or for a given user
472
+ *
473
+ * @returns an object containing a list of reminders
474
+ */
475
+ async getRemindersForTeam() {
476
+ const resp = await this.sdk().reminders.list();
477
+ if (resp.ok) {
478
+ return {
479
+ reminders: resp.reminders,
480
+ };
481
+ } else {
482
+ throw (resp.error);
483
+ }
484
+ },
485
+ /**
486
+ * Returns a list of all users in the workspace. This includes
487
+ * deleted/deactivated users.
488
+ *
489
+ * @param {string} [cursor] - a cursor returned by the previous API call,
490
+ * used to paginate through collections of data
491
+ * @returns an object containing a list of users and the cursor for the next
492
+ * page of users
493
+ */
494
+ async users(cursor) {
495
+ const resp = await this.sdk().users.list({
496
+ cursor,
497
+ });
498
+ if (resp.ok) {
499
+ return {
500
+ users: resp.members,
501
+ cursor: resp.response_metadata.next_cursor,
502
+ };
503
+ } else {
504
+ console.log("Error getting users", resp.error);
505
+ throw (resp.error);
506
+ }
507
+ },
508
+ /**
509
+ * Returns a mapping from user ID to user name for all users in the workspace
510
+ *
511
+ * @returns the mapping from user ID to user name
512
+ */
513
+ async userNames() {
514
+ let cursor;
515
+ const userNames = {};
516
+ do {
517
+ const {
518
+ users,
519
+ cursor: nextCursor,
520
+ } = await this.users(cursor);
521
+ for (const user of users) {
522
+ userNames[user.id] = user.name;
523
+ }
524
+ cursor = nextCursor;
525
+ } while (cursor);
526
+ return userNames;
527
+ },
528
+ async getTeams(cursor) {
529
+ const resp = await this.sdk().auth.teams.list({
530
+ cursor,
531
+ });
532
+
533
+ if (resp.ok) {
534
+ return {
535
+ cursor: resp.response_metadata.next_cursor,
536
+ teams: resp.teams,
537
+ };
538
+ } else {
539
+ console.log("Error getting teams", resp.error);
540
+ throw (resp.error);
541
+ }
542
+ },
543
+ },
544
+ };
@@ -0,0 +1,97 @@
1
+ import slack from "../../slack.app.mjs";
2
+
3
+ export default {
4
+ props: {
5
+ slack,
6
+ nameCache: "$.service.db",
7
+ },
8
+ methods: {
9
+ async maybeCached(key, refreshVal, timeoutMs = 3600000) {
10
+ let record = this.nameCache.get(key);
11
+ const time = Date.now();
12
+ if (!record || time - record.ts > timeoutMs) {
13
+ record = {
14
+ ts: time,
15
+ val: await refreshVal(),
16
+ };
17
+ this.nameCache.set(key, record);
18
+ }
19
+ return record.val;
20
+ },
21
+ async getUserName(id) {
22
+ return this.maybeCached(`users:${id}`, async () => {
23
+ const info = await this.slack.sdk().users.info({
24
+ user: id,
25
+ });
26
+ if (!info.ok) throw new Error(info.error);
27
+ return info.user.name;
28
+ });
29
+ },
30
+ async getBotName(id) {
31
+ return this.maybeCached(`bots:${id}`, async () => {
32
+ const info = await this.slack.sdk().bots.info({
33
+ bot: id,
34
+ });
35
+ if (!info.ok) throw new Error(info.error);
36
+ return info.bot.name;
37
+ });
38
+ },
39
+ async getConversationName(id) {
40
+ return this.maybeCached(`conversations:${id}`, async () => {
41
+ const info = await this.slack.sdk().conversations.info({
42
+ channel: id,
43
+ });
44
+ if (!info.ok) throw new Error(info.error);
45
+ if (info.channel.is_im) {
46
+ return `DM with ${await this.getUserName(info.channel.user)}`;
47
+ }
48
+ return info.channel.name;
49
+ });
50
+ },
51
+ async getTeamName(id) {
52
+ return this.maybeCached(`team:${id}`, async () => {
53
+ try {
54
+ const info = await this.slack.sdk().team.info({
55
+ team: id,
56
+ });
57
+ return info.team.name;
58
+ } catch (err) {
59
+ console.log("Error getting team name, probably need to re-connect the account at pipedream.com/apps", err);
60
+ return id;
61
+ }
62
+ });
63
+ },
64
+ async getLastMessage({
65
+ channel, event_ts,
66
+ }) {
67
+ return this.maybeCached(`lastMessage:${channel}:${event_ts}`, async () => {
68
+ const info = await this.slack.sdk().conversations.history({
69
+ channel,
70
+ latest: event_ts,
71
+ limit: 1,
72
+ inclusive: true,
73
+ });
74
+ return info;
75
+ });
76
+ },
77
+ processEvent(event) {
78
+ return event;
79
+ },
80
+ },
81
+ async run(event) {
82
+ event = await this.processEvent(event);
83
+
84
+ if (event) {
85
+ if (!event.client_msg_id) {
86
+ event.pipedream_msg_id = `pd_${Date.now()}_${Math.random().toString(36)
87
+ .substr(2, 10)}`;
88
+ }
89
+
90
+ this.$emit(event, {
91
+ id: event.client_msg_id || event.pipedream_msg_id,
92
+ summary: this.getSummary(event),
93
+ ts: event.event_ts || Date.now(),
94
+ });
95
+ }
96
+ },
97
+ };
@@ -0,0 +1,30 @@
1
+ const events = {
2
+ im: "User",
3
+ message: "Message",
4
+ file: "File",
5
+ channel: "Channel",
6
+ };
7
+
8
+ const eventsOptions = [
9
+ {
10
+ label: "User",
11
+ value: "im",
12
+ },
13
+ {
14
+ label: "Message",
15
+ value: "message",
16
+ },
17
+ {
18
+ label: "File",
19
+ value: "file",
20
+ },
21
+ {
22
+ label: "Channel",
23
+ value: "channel",
24
+ },
25
+ ];
26
+
27
+ export {
28
+ events,
29
+ eventsOptions,
30
+ };