@oneuptime/common 7.0.3707 → 7.0.3708

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 (35) hide show
  1. package/Server/Services/WorkspaceNotificationRuleService.ts +205 -11
  2. package/Server/Services/WorkspaceProjectAuthTokenService.ts +1 -0
  3. package/Server/Types/Workflow/Components/BaseModel/OnTriggerBaseModel.ts +18 -7
  4. package/Server/Utils/Workspace/Slack/Slack.ts +352 -45
  5. package/Server/Utils/Workspace/Slack/app-manifest.json +9 -4
  6. package/Server/Utils/Workspace/WorkspaceBase.ts +31 -2
  7. package/Types/Workflow/Component.ts +1 -0
  8. package/Types/Workflow/Components/BaseModel.ts +30 -0
  9. package/Types/Workflow/Components/Manual.ts +10 -0
  10. package/Types/Workflow/Components/Schedule.ts +1 -0
  11. package/Types/Workflow/Components/Webhook.ts +26 -0
  12. package/UI/Components/Workflow/RunForm.tsx +23 -25
  13. package/build/dist/Server/Services/WorkspaceNotificationRuleService.js +136 -8
  14. package/build/dist/Server/Services/WorkspaceNotificationRuleService.js.map +1 -1
  15. package/build/dist/Server/Services/WorkspaceProjectAuthTokenService.js +1 -0
  16. package/build/dist/Server/Services/WorkspaceProjectAuthTokenService.js.map +1 -1
  17. package/build/dist/Server/Types/Workflow/Components/BaseModel/OnTriggerBaseModel.js +14 -5
  18. package/build/dist/Server/Types/Workflow/Components/BaseModel/OnTriggerBaseModel.js.map +1 -1
  19. package/build/dist/Server/Utils/Workspace/Slack/Slack.js +251 -36
  20. package/build/dist/Server/Utils/Workspace/Slack/Slack.js.map +1 -1
  21. package/build/dist/Server/Utils/Workspace/Slack/app-manifest.json +9 -4
  22. package/build/dist/Server/Utils/Workspace/WorkspaceBase.js +12 -2
  23. package/build/dist/Server/Utils/Workspace/WorkspaceBase.js.map +1 -1
  24. package/build/dist/Types/Workflow/Components/BaseModel.js +30 -0
  25. package/build/dist/Types/Workflow/Components/BaseModel.js.map +1 -1
  26. package/build/dist/Types/Workflow/Components/Manual.js +10 -0
  27. package/build/dist/Types/Workflow/Components/Manual.js.map +1 -1
  28. package/build/dist/Types/Workflow/Components/Schedule.js +1 -0
  29. package/build/dist/Types/Workflow/Components/Schedule.js.map +1 -1
  30. package/build/dist/Types/Workflow/Components/Webhook.js +26 -0
  31. package/build/dist/Types/Workflow/Components/Webhook.js.map +1 -1
  32. package/build/dist/UI/Components/Workflow/RunForm.js +16 -14
  33. package/build/dist/UI/Components/Workflow/RunForm.js.map +1 -1
  34. package/package.json +2 -2
  35. /package/Server/Utils/Workspace/Slack/{app-manifest-temp.json → app-manifest.example.json} +0 -0
@@ -15,125 +15,270 @@ import WorkspaceBase, { WorkspaceChannel } from "../WorkspaceBase";
15
15
  import WorkspaceType from "../../../../Types/Workspace/WorkspaceType";
16
16
 
17
17
  export default class SlackUtil extends WorkspaceBase {
18
- public static override async inviteUserToChannel(data: {
18
+ public static override async joinChannel(data: {
19
19
  authToken: string;
20
- channelName: string;
20
+ channelId: string;
21
+ }): Promise<void> {
22
+ logger.debug("Joining channel with data:");
23
+ logger.debug(data);
24
+
25
+ // Join channel
26
+ const response: HTTPErrorResponse | HTTPResponse<JSONObject> =
27
+ await API.post(
28
+ URL.fromString("https://slack.com/api/conversations.join"),
29
+ {
30
+ channel: data.channelId,
31
+ },
32
+ {
33
+ Authorization: `Bearer ${data.authToken}`,
34
+ ["Content-Type"]: "application/x-www-form-urlencoded",
35
+ },
36
+ );
37
+
38
+ logger.debug("Response from Slack API for joining channel:");
39
+ logger.debug(response);
40
+
41
+ if (response instanceof HTTPErrorResponse) {
42
+ logger.error("Error response from Slack API:");
43
+ logger.error(response);
44
+ throw response;
45
+ }
46
+
47
+ if ((response.jsonData as JSONObject)?.["ok"] !== true) {
48
+ logger.error("Invalid response from Slack API:");
49
+ logger.error(response.jsonData);
50
+ throw new BadRequestException("Invalid response");
51
+ }
52
+
53
+ logger.debug("Channel joined successfully with data:");
54
+ logger.debug(data);
55
+ }
56
+
57
+ public static override async inviteUserToChannelByChannelId(data: {
58
+ authToken: string;
59
+ channelId: string;
21
60
  workspaceUserId: string;
22
61
  }): Promise<void> {
23
- const channelId: string = (
24
- await this.getWorkspaceChannelFromChannelId({
25
- authToken: data.authToken,
26
- channelId: data.channelName,
27
- })
28
- ).id;
62
+ logger.debug("Inviting user to channel with data:");
63
+ logger.debug(data);
29
64
 
30
65
  const response: HTTPErrorResponse | HTTPResponse<JSONObject> =
31
66
  await API.post(
32
67
  URL.fromString("https://slack.com/api/conversations.invite"),
33
68
  {
34
- channel: channelId,
69
+ channel: data.channelId,
35
70
  users: data.workspaceUserId,
36
71
  },
37
72
  {
38
73
  Authorization: `Bearer ${data.authToken}`,
74
+ ["Content-Type"]: "application/x-www-form-urlencoded",
39
75
  },
40
76
  );
41
77
 
78
+ logger.debug("Response from Slack API for inviting user:");
79
+ logger.debug(response);
80
+
42
81
  if (response instanceof HTTPErrorResponse) {
82
+ logger.error("Error response from Slack API:");
83
+ logger.error(response);
43
84
  throw response;
44
85
  }
45
86
 
46
87
  if ((response.jsonData as JSONObject)?.["ok"] !== true) {
88
+ logger.error("Invalid response from Slack API:");
89
+ logger.error(response.jsonData);
47
90
  throw new BadRequestException("Invalid response");
48
91
  }
92
+
93
+ logger.debug("User invited to channel successfully.");
94
+ }
95
+
96
+ public static override async inviteUserToChannelByChannelName(data: {
97
+ authToken: string;
98
+ channelName: string;
99
+ workspaceUserId: string;
100
+ }): Promise<void> {
101
+ if (data.channelName && data.channelName.startsWith("#")) {
102
+ // trim # from channel name
103
+ data.channelName = data.channelName.substring(1);
104
+ }
105
+
106
+ logger.debug("Inviting user to channel with data:");
107
+ logger.debug(data);
108
+
109
+ const channelId: string = (
110
+ await this.getWorkspaceChannelFromChannelName({
111
+ authToken: data.authToken,
112
+ channelName: data.channelName,
113
+ })
114
+ ).id;
115
+
116
+ return this.inviteUserToChannelByChannelId({
117
+ authToken: data.authToken,
118
+ channelId: channelId,
119
+ workspaceUserId: data.workspaceUserId,
120
+ });
49
121
  }
50
122
 
51
123
  public static override async createChannelsIfDoesNotExist(data: {
52
124
  authToken: string;
53
125
  channelNames: Array<string>;
54
126
  }): Promise<Array<WorkspaceChannel>> {
55
- // check existing channels and only create if they dont exist.
127
+ logger.debug("Creating channels if they do not exist with data:");
128
+ logger.debug(data);
129
+
56
130
  const workspaceChannels: Array<WorkspaceChannel> = [];
57
131
  const existingWorkspaceChannels: Dictionary<WorkspaceChannel> =
58
132
  await this.getAllWorkspaceChannels({
59
133
  authToken: data.authToken,
60
134
  });
61
135
 
62
- for (const channelName of data.channelNames) {
136
+ logger.debug("Existing workspace channels:");
137
+ logger.debug(existingWorkspaceChannels);
138
+
139
+ for (let channelName of data.channelNames) {
140
+ // if channel name starts with #, remove it
141
+ if (channelName && channelName.startsWith("#")) {
142
+ channelName = channelName.substring(1);
143
+ }
144
+
63
145
  if (existingWorkspaceChannels[channelName]) {
64
146
  logger.debug(`Channel ${channelName} already exists.`);
65
-
66
147
  workspaceChannels.push(existingWorkspaceChannels[channelName]!);
67
-
68
148
  continue;
69
149
  }
70
150
 
151
+ logger.debug(`Channel ${channelName} does not exist. Creating channel.`);
71
152
  const channel: WorkspaceChannel = await this.createChannel({
72
153
  authToken: data.authToken,
73
154
  channelName: channelName,
74
155
  });
75
156
 
76
157
  if (channel) {
158
+ logger.debug(`Channel ${channelName} created successfully.`);
77
159
  workspaceChannels.push(channel);
78
160
  }
79
161
  }
80
162
 
163
+ logger.debug("Channels created or found:");
164
+ logger.debug(workspaceChannels);
81
165
  return workspaceChannels;
82
166
  }
83
167
 
168
+ public static override async getWorkspaceChannelFromChannelName(data: {
169
+ authToken: string;
170
+ channelName: string;
171
+ }): Promise<WorkspaceChannel> {
172
+ logger.debug("Getting workspace channel ID from channel name with data:");
173
+ logger.debug(data);
174
+
175
+ const channels: Dictionary<WorkspaceChannel> =
176
+ await this.getAllWorkspaceChannels({
177
+ authToken: data.authToken,
178
+ });
179
+
180
+ logger.debug("All workspace channels:");
181
+ logger.debug(channels);
182
+
183
+ if (!channels[data.channelName]) {
184
+ logger.error("Channel not found.");
185
+ throw new Error("Channel not found.");
186
+ }
187
+
188
+ logger.debug("Workspace channel ID obtained:");
189
+ logger.debug(channels[data.channelName]!.id);
190
+
191
+ return channels[data.channelName]!;
192
+ }
193
+
84
194
  public static override async getWorkspaceChannelFromChannelId(data: {
85
195
  authToken: string;
86
196
  channelId: string;
87
197
  }): Promise<WorkspaceChannel> {
198
+ logger.debug("Getting workspace channel from channel ID with data:");
199
+ logger.debug(data);
200
+
88
201
  const response: HTTPErrorResponse | HTTPResponse<JSONObject> =
89
- await API.get<JSONObject>(
202
+ await API.post<JSONObject>(
90
203
  URL.fromString("https://slack.com/api/conversations.info"),
91
204
  {
92
- headers: {
93
- Authorization: `Bearer ${data.authToken}`,
94
- },
95
- params: {
96
- channel: data.channelId,
97
- },
205
+ channel: data.channelId,
206
+ },
207
+ {
208
+ Authorization: `Bearer ${data.authToken}`,
209
+ ["Content-Type"]: "application/x-www-form-urlencoded",
98
210
  },
99
211
  );
100
212
 
213
+ logger.debug("Response from Slack API for getting channel info:");
214
+ logger.debug(response);
215
+
101
216
  if (response instanceof HTTPErrorResponse) {
217
+ logger.error("Error response from Slack API:");
218
+ logger.error(response);
102
219
  throw response;
103
220
  }
104
221
 
222
+ // check for ok response
223
+ if ((response.jsonData as JSONObject)?.["ok"] !== true) {
224
+ logger.error("Invalid response from Slack API:");
225
+ logger.error(response.jsonData);
226
+ throw new BadRequestException("Invalid response");
227
+ }
228
+
105
229
  if (
106
230
  !((response.jsonData as JSONObject)?.["channel"] as JSONObject)?.["name"]
107
231
  ) {
232
+ logger.error("Invalid response from Slack API:");
233
+ logger.error(response.jsonData);
108
234
  throw new Error("Invalid response");
109
235
  }
110
236
 
111
- return {
237
+ const channel: WorkspaceChannel = {
112
238
  name: ((response.jsonData as JSONObject)["channel"] as JSONObject)[
113
239
  "name"
114
240
  ] as string,
115
241
  id: data.channelId,
116
242
  workspaceType: WorkspaceType.Slack,
117
243
  };
244
+
245
+ logger.debug("Workspace channel obtained:");
246
+ logger.debug(channel);
247
+ return channel;
118
248
  }
119
249
 
120
250
  public static override async getAllWorkspaceChannels(data: {
121
251
  authToken: string;
122
252
  }): Promise<Dictionary<WorkspaceChannel>> {
253
+ logger.debug("Getting all workspace channels with data:");
254
+ logger.debug(data);
255
+
123
256
  const response: HTTPErrorResponse | HTTPResponse<JSONObject> =
124
- await API.get<JSONObject>(
257
+ await API.post<JSONObject>(
125
258
  URL.fromString("https://slack.com/api/conversations.list"),
259
+ {},
126
260
  {
127
- headers: {
128
- Authorization: `Bearer ${data.authToken}`,
129
- },
261
+ Authorization: `Bearer ${data.authToken}`,
262
+ ["Content-Type"]: "application/x-www-form-urlencoded",
130
263
  },
131
264
  );
132
265
 
266
+ logger.debug("Response from Slack API for getting all channels:");
267
+ logger.debug(response);
268
+
133
269
  if (response instanceof HTTPErrorResponse) {
270
+ logger.error("Error response from Slack API:");
271
+ logger.error(response);
134
272
  throw response;
135
273
  }
136
274
 
275
+ // check for ok response
276
+ if ((response.jsonData as JSONObject)?.["ok"] !== true) {
277
+ logger.error("Invalid response from Slack API:");
278
+ logger.error(response.jsonData);
279
+ throw new BadRequestException("Invalid response");
280
+ }
281
+
137
282
  const channels: Dictionary<WorkspaceChannel> = {};
138
283
 
139
284
  for (const channel of (response.jsonData as JSONObject)[
@@ -150,29 +295,42 @@ export default class SlackUtil extends WorkspaceBase {
150
295
  };
151
296
  }
152
297
 
298
+ logger.debug("All workspace channels obtained:");
299
+ logger.debug(channels);
153
300
  return channels;
154
301
  }
155
302
 
156
303
  public static override async sendMessage(data: {
157
304
  workspaceMessagePayload: WorkspaceMessagePayload;
158
305
  authToken: string; // which auth token should we use to send.
306
+ userId: string;
159
307
  }): Promise<void> {
160
- logger.debug("Notify Slack");
308
+ logger.debug("Sending message to Slack with data:");
161
309
  logger.debug(data);
162
310
 
163
311
  const blocks: Array<JSONObject> = this.getBlocksFromWorkspaceMessagePayload(
164
312
  data.workspaceMessagePayload,
165
313
  );
166
314
 
315
+ logger.debug("Blocks generated from workspace message payload:");
316
+ logger.debug(blocks);
317
+
167
318
  const existingWorkspaceChannels: Dictionary<WorkspaceChannel> =
168
319
  await this.getAllWorkspaceChannels({
169
320
  authToken: data.authToken,
170
321
  });
171
322
 
323
+ logger.debug("Existing workspace channels:");
324
+ logger.debug(existingWorkspaceChannels);
325
+
172
326
  const channelIdsToPostTo: Array<string> = [];
173
327
 
174
- for (const channelName of data.workspaceMessagePayload.channelNames) {
175
- // get channel ids from existingWorkspaceChannels. IF channel doesn't exist, create it if createChannelsIfItDoesNotExist is true.
328
+ for (let channelName of data.workspaceMessagePayload.channelNames) {
329
+ if (channelName && channelName.startsWith("#")) {
330
+ // trim # from channel name
331
+ channelName = channelName.substring(1);
332
+ }
333
+
176
334
  let channel: WorkspaceChannel | null = null;
177
335
 
178
336
  if (existingWorkspaceChannels[channelName]) {
@@ -186,15 +344,35 @@ export default class SlackUtil extends WorkspaceBase {
186
344
  }
187
345
  }
188
346
 
347
+ logger.debug("Channel IDs to post to:");
348
+ logger.debug(channelIdsToPostTo);
349
+
189
350
  for (const channelId of channelIdsToPostTo) {
190
351
  try {
191
- // try catch here to prevent failure of one channel to prevent posting to other channels.
352
+ // check if the user is in the channel.
353
+ const isUserInChannel: boolean = await this.isUserInChannel({
354
+ authToken: data.authToken,
355
+ channelId: channelId,
356
+ userId: data.userId,
357
+ });
358
+
359
+ if (!isUserInChannel) {
360
+ // add user to the channel
361
+ await this.joinChannel({
362
+ authToken: data.authToken,
363
+ channelId: channelId,
364
+ });
365
+ }
366
+
192
367
  await this.sendPayloadBlocksToChannel({
193
368
  authToken: data.authToken,
194
369
  channelId: channelId,
195
370
  blocks: blocks,
196
371
  });
372
+
373
+ logger.debug(`Message sent to channel ID ${channelId} successfully.`);
197
374
  } catch (e) {
375
+ logger.error(`Error sending message to channel ID ${channelId}:`);
198
376
  logger.error(e);
199
377
  }
200
378
  }
@@ -205,6 +383,9 @@ export default class SlackUtil extends WorkspaceBase {
205
383
  channelId: string;
206
384
  blocks: Array<JSONObject>;
207
385
  }): Promise<void> {
386
+ logger.debug("Sending payload blocks to channel with data:");
387
+ logger.debug(JSON.stringify(data, null, 2));
388
+
208
389
  const response: HTTPErrorResponse | HTTPResponse<JSONObject> =
209
390
  await API.post(
210
391
  URL.fromString("https://slack.com/api/chat.postMessage"),
@@ -214,22 +395,35 @@ export default class SlackUtil extends WorkspaceBase {
214
395
  },
215
396
  {
216
397
  Authorization: `Bearer ${data.authToken}`,
398
+ ["Content-Type"]: "application/json",
217
399
  },
218
400
  );
219
401
 
402
+ logger.debug("Response from Slack API for sending message:");
403
+ logger.debug(response);
404
+
220
405
  if (response instanceof HTTPErrorResponse) {
406
+ logger.error("Error response from Slack API:");
407
+ logger.error(response);
221
408
  throw response;
222
409
  }
223
410
 
224
411
  if ((response.jsonData as JSONObject)?.["ok"] !== true) {
412
+ logger.error("Invalid response from Slack API:");
413
+ logger.error(response.jsonData);
225
414
  throw new BadRequestException("Invalid response");
226
415
  }
416
+
417
+ logger.debug("Payload blocks sent to channel successfully.");
227
418
  }
228
419
 
229
420
  public static override async createChannel(data: {
230
421
  authToken: string;
231
422
  channelName: string;
232
423
  }): Promise<WorkspaceChannel> {
424
+ logger.debug("Creating channel with data:");
425
+ logger.debug(data);
426
+
233
427
  const response: HTTPResponse<JSONObject> | HTTPErrorResponse =
234
428
  await API.post(
235
429
  URL.fromString("https://slack.com/api/conversations.create"),
@@ -238,21 +432,36 @@ export default class SlackUtil extends WorkspaceBase {
238
432
  },
239
433
  {
240
434
  Authorization: `Bearer ${data.authToken}`,
435
+ ["Content-Type"]: "application/x-www-form-urlencoded",
241
436
  },
242
437
  );
243
438
 
439
+ logger.debug("Response from Slack API for creating channel:");
440
+ logger.debug(response);
441
+
244
442
  if (response instanceof HTTPErrorResponse) {
443
+ logger.error("Error response from Slack API:");
444
+ logger.error(response);
245
445
  throw response;
246
446
  }
247
447
 
448
+ // check for ok response
449
+ if ((response.jsonData as JSONObject)?.["ok"] !== true) {
450
+ logger.error("Invalid response from Slack API:");
451
+ logger.error(response.jsonData);
452
+ throw new BadRequestException("Invalid response");
453
+ }
454
+
248
455
  if (
249
456
  !((response.jsonData as JSONObject)?.["channel"] as JSONObject)?.["id"] ||
250
457
  !((response.jsonData as JSONObject)?.["channel"] as JSONObject)?.["name"]
251
458
  ) {
459
+ logger.error("Invalid response from Slack API:");
460
+ logger.error(response.jsonData);
252
461
  throw new Error("Invalid response");
253
462
  }
254
463
 
255
- return {
464
+ const channel: WorkspaceChannel = {
256
465
  id: ((response.jsonData as JSONObject)["channel"] as JSONObject)[
257
466
  "id"
258
467
  ] as string,
@@ -261,36 +470,127 @@ export default class SlackUtil extends WorkspaceBase {
261
470
  ] as string,
262
471
  workspaceType: WorkspaceType.Slack,
263
472
  };
473
+
474
+ logger.debug("Channel created successfully:");
475
+ logger.debug(channel);
476
+ return channel;
264
477
  }
265
478
 
266
479
  public static override getHeaderBlock(data: {
267
480
  payloadHeaderBlock: WorkspacePayloadHeader;
268
481
  }): JSONObject {
269
- return {
482
+ logger.debug("Getting header block with data:");
483
+ logger.debug(data);
484
+
485
+ const headerBlock: JSONObject = {
270
486
  type: "header",
271
487
  text: {
272
488
  type: "plain_text",
273
489
  text: data.payloadHeaderBlock.text,
274
490
  },
275
491
  };
492
+
493
+ logger.debug("Header block generated:");
494
+ logger.debug(headerBlock);
495
+ return headerBlock;
276
496
  }
277
497
 
278
498
  public static override getMarkdownBlock(data: {
279
499
  payloadMarkdownBlock: WorkspacePayloadMarkdown;
280
500
  }): JSONObject {
281
- return {
501
+ logger.debug("Getting markdown block with data:");
502
+ logger.debug(data);
503
+
504
+ const markdownBlock: JSONObject = {
282
505
  type: "section",
283
506
  text: {
284
507
  type: "mrkdwn",
285
508
  text: data.payloadMarkdownBlock.text,
286
509
  },
287
510
  };
511
+
512
+ logger.debug("Markdown block generated:");
513
+ logger.debug(markdownBlock);
514
+ return markdownBlock;
515
+ }
516
+
517
+ public static override async isUserInChannel(data: {
518
+ authToken: string;
519
+ channelId: string;
520
+ userId: string;
521
+ }): Promise<boolean> {
522
+ const members: Array<string> = [];
523
+
524
+ logger.debug("Checking if user is in channel with data:");
525
+ logger.debug(data);
526
+
527
+ let cursor: string | undefined = undefined;
528
+
529
+ do {
530
+ // check if the user is in the channel, return true if they are, false if they are not
531
+
532
+ const requestBody: JSONObject = {
533
+ channel: data.channelId,
534
+ limit: 1000,
535
+ };
536
+
537
+ if (cursor) {
538
+ requestBody["cursor"] = cursor;
539
+ }
540
+
541
+ const response: HTTPErrorResponse | HTTPResponse<JSONObject> =
542
+ await API.post<JSONObject>(
543
+ URL.fromString("https://slack.com/api/conversations.members"),
544
+ requestBody,
545
+ {
546
+ Authorization: `Bearer ${data.authToken}`,
547
+ ["Content-Type"]: "application/x-www-form-urlencoded",
548
+ },
549
+ );
550
+
551
+ logger.debug("Response from Slack API for getting channel members:");
552
+ logger.debug(response);
553
+
554
+ if (response instanceof HTTPErrorResponse) {
555
+ logger.error("Error response from Slack API:");
556
+ logger.error(response);
557
+ throw response;
558
+ }
559
+
560
+ // check for ok response
561
+
562
+ if ((response.jsonData as JSONObject)?.["ok"] !== true) {
563
+ logger.error("Invalid response from Slack API:");
564
+ logger.error(response.jsonData);
565
+ throw new BadRequestException("Invalid response");
566
+ }
567
+
568
+ // check if the user is in the channel
569
+ const membersOnThisPage: Array<string> = (
570
+ response.jsonData as JSONObject
571
+ )["members"] as Array<string>;
572
+
573
+ members.push(...membersOnThisPage);
574
+
575
+ cursor = (
576
+ (response.jsonData as JSONObject)["response_metadata"] as JSONObject
577
+ )?.["next_cursor"] as string;
578
+ } while (cursor);
579
+
580
+ if (members.includes(data.userId)) {
581
+ return true;
582
+ }
583
+
584
+ return false;
288
585
  }
289
586
 
290
587
  public static override getButtonBlock(data: {
291
588
  payloadButtonBlock: WorkspaceMessagePayloadButton;
292
589
  }): JSONObject {
293
- return {
590
+ logger.debug("Getting button block with data:");
591
+ logger.debug(data);
592
+
593
+ const buttonBlock: JSONObject = {
294
594
  type: "button",
295
595
  text: {
296
596
  type: "plain_text",
@@ -299,27 +599,34 @@ export default class SlackUtil extends WorkspaceBase {
299
599
  value: data.payloadButtonBlock.title,
300
600
  action_id: data.payloadButtonBlock.title,
301
601
  };
602
+
603
+ logger.debug("Button block generated:");
604
+ logger.debug(buttonBlock);
605
+ return buttonBlock;
302
606
  }
303
607
 
304
608
  public static override async sendMessageToChannelViaIncomingWebhook(data: {
305
609
  url: URL;
306
610
  text: string;
307
611
  }): Promise<HTTPResponse<JSONObject> | HTTPErrorResponse> {
308
- let apiResult: HTTPResponse<JSONObject> | HTTPErrorResponse | null = null;
612
+ logger.debug("Sending message to channel via incoming webhook with data:");
613
+ logger.debug(data);
309
614
 
310
- // https://api.slack.com/messaging/webhooks#advanced_message_formatting
311
- apiResult = await API.post(data.url, {
312
- blocks: [
313
- {
314
- type: "section",
315
- text: {
316
- type: "mrkdwn",
317
- text: `${data.text}`,
615
+ const apiResult: HTTPResponse<JSONObject> | HTTPErrorResponse | null =
616
+ await API.post(data.url, {
617
+ blocks: [
618
+ {
619
+ type: "section",
620
+ text: {
621
+ type: "mrkdwn",
622
+ text: `${data.text}`,
623
+ },
318
624
  },
319
- },
320
- ],
321
- });
625
+ ],
626
+ });
322
627
 
628
+ logger.debug("Response from Slack API for sending message via webhook:");
629
+ logger.debug(apiResult);
323
630
  return apiResult;
324
631
  }
325
632
  }
@@ -45,12 +45,17 @@
45
45
  ],
46
46
  "scopes": {
47
47
  "user": [
48
- "identity.email",
49
- "identity.basic",
50
- "email"
48
+ "users:read"
51
49
  ],
52
50
  "bot": [
53
- "commands"
51
+ "commands",
52
+ "channels:history",
53
+ "channels:join",
54
+ "channels:manage",
55
+ "channels:read",
56
+ "channels:write.invites",
57
+ "channels:write.topic",
58
+ "chat:write"
54
59
  ]
55
60
  }
56
61
  },