@oneuptime/common 7.0.4007 → 7.0.4026

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 (54) hide show
  1. package/Server/Services/AlertStateTimelineService.ts +66 -0
  2. package/Server/Services/IncidentStateTimelineService.ts +66 -0
  3. package/Server/Services/MonitorService.ts +72 -1
  4. package/Server/Services/OnCallDutyPolicyEscalationRuleScheduleService.ts +243 -0
  5. package/Server/Services/OnCallDutyPolicyEscalationRuleService.ts +46 -0
  6. package/Server/Services/OnCallDutyPolicyEscalationRuleTeamService.ts +237 -0
  7. package/Server/Services/OnCallDutyPolicyEscalationRuleUserService.ts +210 -0
  8. package/Server/Services/OnCallDutyPolicyScheduleService.ts +392 -14
  9. package/Server/Services/ScheduledMaintenanceStateTimelineService.ts +76 -0
  10. package/Server/Services/UserNotificationSettingService.ts +114 -237
  11. package/Server/Services/UserService.ts +21 -0
  12. package/Server/Services/WorkspaceNotificationRuleService.ts +128 -35
  13. package/Server/Utils/Workspace/Slack/Actions/Alert.ts +2 -2
  14. package/Server/Utils/Workspace/Slack/Actions/Incident.ts +3 -3
  15. package/Server/Utils/Workspace/Slack/Slack.ts +59 -0
  16. package/Server/Utils/Workspace/WorkspaceBase.ts +10 -0
  17. package/Types/Email/EmailTemplateType.ts +6 -0
  18. package/Types/NotificationSetting/NotificationSettingEventType.ts +7 -0
  19. package/Types/Workspace/NotificationRules/CreateChannelNotificationRule.ts +4 -0
  20. package/build/dist/Server/Services/AlertStateTimelineService.js +50 -0
  21. package/build/dist/Server/Services/AlertStateTimelineService.js.map +1 -1
  22. package/build/dist/Server/Services/IncidentStateTimelineService.js +50 -0
  23. package/build/dist/Server/Services/IncidentStateTimelineService.js.map +1 -1
  24. package/build/dist/Server/Services/MonitorService.js +56 -1
  25. package/build/dist/Server/Services/MonitorService.js.map +1 -1
  26. package/build/dist/Server/Services/OnCallDutyPolicyEscalationRuleScheduleService.js +170 -0
  27. package/build/dist/Server/Services/OnCallDutyPolicyEscalationRuleScheduleService.js.map +1 -1
  28. package/build/dist/Server/Services/OnCallDutyPolicyEscalationRuleService.js +40 -0
  29. package/build/dist/Server/Services/OnCallDutyPolicyEscalationRuleService.js.map +1 -1
  30. package/build/dist/Server/Services/OnCallDutyPolicyEscalationRuleTeamService.js +170 -0
  31. package/build/dist/Server/Services/OnCallDutyPolicyEscalationRuleTeamService.js.map +1 -1
  32. package/build/dist/Server/Services/OnCallDutyPolicyEscalationRuleUserService.js +152 -0
  33. package/build/dist/Server/Services/OnCallDutyPolicyEscalationRuleUserService.js.map +1 -1
  34. package/build/dist/Server/Services/OnCallDutyPolicyScheduleService.js +266 -10
  35. package/build/dist/Server/Services/OnCallDutyPolicyScheduleService.js.map +1 -1
  36. package/build/dist/Server/Services/ScheduledMaintenanceStateTimelineService.js +52 -0
  37. package/build/dist/Server/Services/ScheduledMaintenanceStateTimelineService.js.map +1 -1
  38. package/build/dist/Server/Services/UserNotificationSettingService.js +35 -202
  39. package/build/dist/Server/Services/UserNotificationSettingService.js.map +1 -1
  40. package/build/dist/Server/Services/UserService.js +17 -0
  41. package/build/dist/Server/Services/UserService.js.map +1 -1
  42. package/build/dist/Server/Services/WorkspaceNotificationRuleService.js +101 -29
  43. package/build/dist/Server/Services/WorkspaceNotificationRuleService.js.map +1 -1
  44. package/build/dist/Server/Utils/Workspace/Slack/Actions/Alert.js +2 -2
  45. package/build/dist/Server/Utils/Workspace/Slack/Actions/Incident.js +3 -3
  46. package/build/dist/Server/Utils/Workspace/Slack/Slack.js +46 -0
  47. package/build/dist/Server/Utils/Workspace/Slack/Slack.js.map +1 -1
  48. package/build/dist/Server/Utils/Workspace/WorkspaceBase.js +9 -0
  49. package/build/dist/Server/Utils/Workspace/WorkspaceBase.js.map +1 -1
  50. package/build/dist/Types/Email/EmailTemplateType.js +5 -0
  51. package/build/dist/Types/Email/EmailTemplateType.js.map +1 -1
  52. package/build/dist/Types/NotificationSetting/NotificationSettingEventType.js +6 -0
  53. package/build/dist/Types/NotificationSetting/NotificationSettingEventType.js.map +1 -1
  54. package/package.json +2 -2
@@ -197,266 +197,143 @@ export class Service extends DatabaseService<UserNotificationSetting> {
197
197
  userId: ObjectID,
198
198
  projectId: ObjectID,
199
199
  ): Promise<void> {
200
- const probeOwnerAddedNotificationEvent: PositiveNumber = await this.countBy(
201
- {
202
- query: {
203
- userId,
204
- projectId,
205
- eventType:
206
- NotificationSettingEventType.SEND_PROBE_OWNER_ADDED_NOTIFICATION,
207
- },
208
- props: {
209
- isRoot: true,
210
- },
211
- },
200
+ await this.addProbeOwnerNotificationSettings(userId, projectId);
201
+ await this.addIncidentNotificationSettings(userId, projectId);
202
+ await this.addMonitorNotificationSettings(userId, projectId);
203
+ await this.addOnCallNotificationSettings(userId, projectId);
204
+ await this.addAlertNotificationSettings(userId, projectId);
205
+ }
206
+
207
+ private async addProbeOwnerNotificationSettings(
208
+ userId: ObjectID,
209
+ projectId: ObjectID,
210
+ ): Promise<void> {
211
+ await this.addNotificationSettingIfNotExists(
212
+ userId,
213
+ projectId,
214
+ NotificationSettingEventType.SEND_PROBE_OWNER_ADDED_NOTIFICATION,
212
215
  );
213
216
 
214
- if (probeOwnerAddedNotificationEvent.toNumber() === 0) {
215
- const item: UserNotificationSetting = new UserNotificationSetting();
216
- item.userId = userId;
217
- item.projectId = projectId;
218
- item.eventType =
219
- NotificationSettingEventType.SEND_PROBE_OWNER_ADDED_NOTIFICATION;
220
- item.alertByEmail = true;
217
+ await this.addNotificationSettingIfNotExists(
218
+ userId,
219
+ projectId,
220
+ NotificationSettingEventType.SEND_PROBE_STATUS_CHANGED_OWNER_NOTIFICATION,
221
+ );
222
+ }
221
223
 
222
- await this.create({
223
- data: item,
224
- props: {
225
- isRoot: true,
226
- },
227
- });
228
- }
224
+ private async addIncidentNotificationSettings(
225
+ userId: ObjectID,
226
+ projectId: ObjectID,
227
+ ): Promise<void> {
228
+ await this.addNotificationSettingIfNotExists(
229
+ userId,
230
+ projectId,
231
+ NotificationSettingEventType.SEND_INCIDENT_CREATED_OWNER_NOTIFICATION,
232
+ );
229
233
 
230
- const probeStatusChangedNotificationEvent: PositiveNumber =
231
- await this.countBy({
232
- query: {
233
- userId,
234
- projectId,
235
- eventType:
236
- NotificationSettingEventType.SEND_PROBE_STATUS_CHANGED_OWNER_NOTIFICATION,
237
- },
238
- props: {
239
- isRoot: true,
240
- },
241
- });
234
+ await this.addNotificationSettingIfNotExists(
235
+ userId,
236
+ projectId,
237
+ NotificationSettingEventType.SEND_INCIDENT_STATE_CHANGED_OWNER_NOTIFICATION,
238
+ );
239
+ }
242
240
 
243
- if (probeStatusChangedNotificationEvent.toNumber() === 0) {
244
- const item: UserNotificationSetting = new UserNotificationSetting();
245
- item.userId = userId;
246
- item.projectId = projectId;
247
- item.eventType =
248
- NotificationSettingEventType.SEND_PROBE_STATUS_CHANGED_OWNER_NOTIFICATION;
249
- item.alertByEmail = true;
241
+ private async addMonitorNotificationSettings(
242
+ userId: ObjectID,
243
+ projectId: ObjectID,
244
+ ): Promise<void> {
245
+ await this.addNotificationSettingIfNotExists(
246
+ userId,
247
+ projectId,
248
+ NotificationSettingEventType.SEND_MONITOR_STATUS_CHANGED_OWNER_NOTIFICATION,
249
+ );
250
250
 
251
- await this.create({
252
- data: item,
253
- props: {
254
- isRoot: true,
255
- },
256
- });
257
- }
251
+ await this.addNotificationSettingIfNotExists(
252
+ userId,
253
+ projectId,
254
+ NotificationSettingEventType.SEND_MONITOR_NOTIFICATION_WHEN_NO_PROBES_ARE_MONITORING_THE_MONITOR,
255
+ );
258
256
 
259
- const incidentCreatedNotificationEvent: PositiveNumber = await this.countBy(
260
- {
261
- query: {
262
- userId,
263
- projectId,
264
- eventType:
265
- NotificationSettingEventType.SEND_INCIDENT_CREATED_OWNER_NOTIFICATION,
266
- },
267
- props: {
268
- isRoot: true,
269
- },
270
- },
257
+ await this.addNotificationSettingIfNotExists(
258
+ userId,
259
+ projectId,
260
+ NotificationSettingEventType.SEND_MONITOR_NOTIFICATION_WHEN_PORBE_STATUS_CHANGES,
271
261
  );
262
+ }
272
263
 
273
- if (incidentCreatedNotificationEvent.toNumber() === 0) {
274
- const item: UserNotificationSetting = new UserNotificationSetting();
275
- item.userId = userId;
276
- item.projectId = projectId;
277
- item.eventType =
278
- NotificationSettingEventType.SEND_INCIDENT_CREATED_OWNER_NOTIFICATION;
279
- item.alertByEmail = true;
264
+ public async addOnCallNotificationSettings(
265
+ userId: ObjectID,
266
+ projectId: ObjectID,
267
+ ): Promise<void> {
268
+ await this.addNotificationSettingIfNotExists(
269
+ userId,
270
+ projectId,
271
+ NotificationSettingEventType.SEND_WHEN_USER_IS_ON_CALL_ROSTER,
272
+ );
280
273
 
281
- await this.create({
282
- data: item,
283
- props: {
284
- isRoot: true,
285
- },
286
- });
287
- }
274
+ await this.addNotificationSettingIfNotExists(
275
+ userId,
276
+ projectId,
277
+ NotificationSettingEventType.SEND_WHEN_USER_IS_NEXT_ON_CALL_ROSTER,
278
+ );
279
+
280
+ await this.addNotificationSettingIfNotExists(
281
+ userId,
282
+ projectId,
283
+ NotificationSettingEventType.SEND_WHEN_USER_IS_ADDED_TO_ON_CALL_POLICY,
284
+ );
285
+
286
+ await this.addNotificationSettingIfNotExists(
287
+ userId,
288
+ projectId,
289
+ NotificationSettingEventType.SEND_WHEN_USER_IS_REMOVED_FROM_ON_CALL_POLICY,
290
+ );
291
+
292
+ await this.addNotificationSettingIfNotExists(
293
+ userId,
294
+ projectId,
295
+ NotificationSettingEventType.SEND_WHEN_USER_IS_NO_LONGER_ACTIVE_ON_ON_CALL_ROSTER,
296
+ );
297
+ }
298
+
299
+ private async addAlertNotificationSettings(
300
+ userId: ObjectID,
301
+ projectId: ObjectID,
302
+ ): Promise<void> {
303
+ await this.addNotificationSettingIfNotExists(
304
+ userId,
305
+ projectId,
306
+ NotificationSettingEventType.SEND_ALERT_CREATED_OWNER_NOTIFICATION,
307
+ );
288
308
 
289
- const alertCreatedNotificationEvent: PositiveNumber = await this.countBy({
309
+ await this.addNotificationSettingIfNotExists(
310
+ userId,
311
+ projectId,
312
+ NotificationSettingEventType.SEND_ALERT_STATE_CHANGED_OWNER_NOTIFICATION,
313
+ );
314
+ }
315
+
316
+ private async addNotificationSettingIfNotExists(
317
+ userId: ObjectID,
318
+ projectId: ObjectID,
319
+ eventType: NotificationSettingEventType,
320
+ ): Promise<void> {
321
+ const existingNotification: PositiveNumber = await this.countBy({
290
322
  query: {
291
323
  userId,
292
324
  projectId,
293
- eventType:
294
- NotificationSettingEventType.SEND_ALERT_CREATED_OWNER_NOTIFICATION,
325
+ eventType,
295
326
  },
296
327
  props: {
297
328
  isRoot: true,
298
329
  },
299
330
  });
300
331
 
301
- if (alertCreatedNotificationEvent.toNumber() === 0) {
302
- const item: UserNotificationSetting = new UserNotificationSetting();
303
- item.userId = userId;
304
- item.projectId = projectId;
305
- item.eventType =
306
- NotificationSettingEventType.SEND_ALERT_CREATED_OWNER_NOTIFICATION;
307
- item.alertByEmail = true;
308
-
309
- await this.create({
310
- data: item,
311
- props: {
312
- isRoot: true,
313
- },
314
- });
315
- }
316
-
317
- // check monitor state changed notification
318
- const monitorStateChangedNotificationEvent: PositiveNumber =
319
- await this.countBy({
320
- query: {
321
- userId,
322
- projectId,
323
- eventType:
324
- NotificationSettingEventType.SEND_MONITOR_STATUS_CHANGED_OWNER_NOTIFICATION,
325
- },
326
- props: {
327
- isRoot: true,
328
- },
329
- });
330
-
331
- if (monitorStateChangedNotificationEvent.toNumber() === 0) {
332
- const item: UserNotificationSetting = new UserNotificationSetting();
333
- item.userId = userId;
334
- item.projectId = projectId;
335
- item.eventType =
336
- NotificationSettingEventType.SEND_MONITOR_STATUS_CHANGED_OWNER_NOTIFICATION;
337
- item.alertByEmail = true;
338
-
339
- await this.create({
340
- data: item,
341
- props: {
342
- isRoot: true,
343
- },
344
- });
345
- }
346
-
347
- // SEND_MONITOR_NOTIFICATION_WHEN_NO_PROBES_ARE_MONITORING_THE_MONITOR
348
-
349
- const monitorNoProbesNotificationEvent: PositiveNumber = await this.countBy(
350
- {
351
- query: {
352
- userId,
353
- projectId,
354
- eventType:
355
- NotificationSettingEventType.SEND_MONITOR_NOTIFICATION_WHEN_NO_PROBES_ARE_MONITORING_THE_MONITOR,
356
- },
357
- props: {
358
- isRoot: true,
359
- },
360
- },
361
- );
362
-
363
- if (monitorNoProbesNotificationEvent.toNumber() === 0) {
364
- const item: UserNotificationSetting = new UserNotificationSetting();
365
- item.userId = userId;
366
- item.projectId = projectId;
367
- item.eventType =
368
- NotificationSettingEventType.SEND_MONITOR_NOTIFICATION_WHEN_NO_PROBES_ARE_MONITORING_THE_MONITOR;
369
- item.alertByEmail = true;
370
-
371
- await this.create({
372
- data: item,
373
- props: {
374
- isRoot: true,
375
- },
376
- });
377
- }
378
-
379
- // SEND_MONITOR_NOTIFICATION_WHEN_PORBE_STATUS_CHANGES
380
-
381
- const monitorProbeStatusChangedNotificationEvent: PositiveNumber =
382
- await this.countBy({
383
- query: {
384
- userId,
385
- projectId,
386
- eventType:
387
- NotificationSettingEventType.SEND_MONITOR_NOTIFICATION_WHEN_PORBE_STATUS_CHANGES,
388
- },
389
- props: {
390
- isRoot: true,
391
- },
392
- });
393
-
394
- if (monitorProbeStatusChangedNotificationEvent.toNumber() === 0) {
395
- const item: UserNotificationSetting = new UserNotificationSetting();
396
- item.userId = userId;
397
- item.projectId = projectId;
398
- item.eventType =
399
- NotificationSettingEventType.SEND_MONITOR_NOTIFICATION_WHEN_PORBE_STATUS_CHANGES;
400
- item.alertByEmail = true;
401
-
402
- await this.create({
403
- data: item,
404
- props: {
405
- isRoot: true,
406
- },
407
- });
408
- }
409
-
410
- // check incident state changed notification
411
- const incidentStateChangedNotificationEvent: PositiveNumber =
412
- await this.countBy({
413
- query: {
414
- userId,
415
- projectId,
416
- eventType:
417
- NotificationSettingEventType.SEND_INCIDENT_STATE_CHANGED_OWNER_NOTIFICATION,
418
- },
419
- props: {
420
- isRoot: true,
421
- },
422
- });
423
-
424
- if (incidentStateChangedNotificationEvent.toNumber() === 0) {
425
- const item: UserNotificationSetting = new UserNotificationSetting();
426
- item.userId = userId;
427
- item.projectId = projectId;
428
- item.eventType =
429
- NotificationSettingEventType.SEND_INCIDENT_STATE_CHANGED_OWNER_NOTIFICATION;
430
- item.alertByEmail = true;
431
-
432
- await this.create({
433
- data: item,
434
- props: {
435
- isRoot: true,
436
- },
437
- });
438
- }
439
-
440
- // check alert state changed notification
441
- const alertStateChangedNotificationEvent: PositiveNumber =
442
- await this.countBy({
443
- query: {
444
- userId,
445
- projectId,
446
- eventType:
447
- NotificationSettingEventType.SEND_ALERT_STATE_CHANGED_OWNER_NOTIFICATION,
448
- },
449
- props: {
450
- isRoot: true,
451
- },
452
- });
453
-
454
- if (alertStateChangedNotificationEvent.toNumber() === 0) {
332
+ if (existingNotification.toNumber() === 0) {
455
333
  const item: UserNotificationSetting = new UserNotificationSetting();
456
334
  item.userId = userId;
457
335
  item.projectId = projectId;
458
- item.eventType =
459
- NotificationSettingEventType.SEND_ALERT_STATE_CHANGED_OWNER_NOTIFICATION;
336
+ item.eventType = eventType;
460
337
  item.alertByEmail = true;
461
338
 
462
339
  await this.create({
@@ -34,6 +34,7 @@ import UserTwoFactorAuthService from "./UserTwoFactorAuthService";
34
34
  import BadDataException from "../../Types/Exception/BadDataException";
35
35
  import Name from "../../Types/Name";
36
36
  import CaptureSpan from "../Utils/Telemetry/CaptureSpan";
37
+ import Timezone from "../../Types/Timezone";
37
38
 
38
39
  export class Service extends DatabaseService<Model> {
39
40
  public constructor() {
@@ -364,6 +365,26 @@ export class Service extends DatabaseService<Model> {
364
365
  props: props,
365
366
  });
366
367
  }
368
+
369
+ public async getTimezoneForUser(userId: ObjectID): Promise<Timezone | null> {
370
+ const user: Model | null = await this.findOneBy({
371
+ query: {
372
+ _id: userId,
373
+ },
374
+ select: {
375
+ timezone: true,
376
+ },
377
+ props: {
378
+ isRoot: true,
379
+ },
380
+ });
381
+
382
+ if (!user) {
383
+ return null;
384
+ }
385
+
386
+ return user.timezone || null;
387
+ }
367
388
  }
368
389
 
369
390
  export default new Service();
@@ -264,6 +264,87 @@ export class Service extends DatabaseService<WorkspaceNotificationRule> {
264
264
  }
265
265
  }
266
266
 
267
+ @CaptureSpan()
268
+ public async archiveWorkspaceChannels(data: {
269
+ projectId: ObjectID;
270
+ notificationFor: NotificationFor;
271
+ sendMessageBeforeArchiving: WorkspacePayloadMarkdown;
272
+ }): Promise<void> {
273
+ const workspaceTypes: Array<WorkspaceType> = Service.getAllWorkspaceTypes();
274
+
275
+ for (const workspaceType of workspaceTypes) {
276
+ const notificationRules: Array<WorkspaceNotificationRule> =
277
+ await this.getMatchingNotificationRules({
278
+ projectId: data.projectId,
279
+ notificationFor: data.notificationFor,
280
+ workspaceType: workspaceType,
281
+ notificationRuleEventType: this.getNotificationRuleEventType(
282
+ data.notificationFor,
283
+ ),
284
+ });
285
+
286
+ // check if any of these rules have archive channel to true.
287
+ let shouldArchiveChannel: boolean = false;
288
+
289
+ for (const notificationRule of notificationRules) {
290
+ const rule: CreateChannelNotificationRule =
291
+ notificationRule.notificationRule as CreateChannelNotificationRule;
292
+ if (rule && rule.archiveChannelAutomatically) {
293
+ shouldArchiveChannel = true;
294
+ break;
295
+ }
296
+ }
297
+
298
+ if (!shouldArchiveChannel) {
299
+ continue; // check next workspace type.
300
+ }
301
+
302
+ const channels: Array<WorkspaceChannel> =
303
+ await this.getWorkspaceChannelsByNotificationFor({
304
+ projectId: data.projectId,
305
+ notificationFor: data.notificationFor,
306
+ workspaceType: workspaceType,
307
+ });
308
+
309
+ const channelIds: Array<string> = channels.map(
310
+ (channel: WorkspaceChannel) => {
311
+ return channel.id;
312
+ },
313
+ );
314
+
315
+ // get project auth token.
316
+ const projectAuth: WorkspaceProjectAuthToken | null =
317
+ await WorkspaceProjectAuthTokenService.findOneBy({
318
+ query: {
319
+ projectId: data.projectId,
320
+ workspaceType: workspaceType,
321
+ },
322
+ select: {
323
+ authToken: true,
324
+ miscData: true,
325
+ },
326
+ props: {
327
+ isRoot: true,
328
+ },
329
+ });
330
+
331
+ if (!projectAuth || !projectAuth.authToken) {
332
+ logger.debug("No project auth found for workspace type");
333
+ continue;
334
+ }
335
+
336
+ await WorkspaceUtil.getWorkspaceTypeUtil(workspaceType).archiveChannels({
337
+ authToken: projectAuth.authToken!,
338
+ channelIds: channelIds,
339
+ userId: this.getBotUserIdFromprojectAuthToken({
340
+ projectAuthToken: projectAuth,
341
+ workspaceType: workspaceType,
342
+ }),
343
+ sendMessageBeforeArchiving: data.sendMessageBeforeArchiving,
344
+ });
345
+ }
346
+ }
347
+
267
348
  @CaptureSpan()
268
349
  public async sendWorkspaceMarkdownNotification(data: {
269
350
  projectId: ObjectID;
@@ -316,43 +397,12 @@ export class Service extends DatabaseService<WorkspaceNotificationRule> {
316
397
  notificationFor: data.notificationFor,
317
398
  });
318
399
 
319
- let monitorChannels: Array<WorkspaceChannel> = [];
320
-
321
- if (data.notificationFor.monitorId) {
322
- monitorChannels = await MonitorService.getWorkspaceChannelForMonitor({
323
- monitorId: data.notificationFor.monitorId,
324
- workspaceType: messageBlocksByWorkspaceType.workspaceType,
325
- });
326
- }
327
-
328
- // incidents
329
- if (data.notificationFor.incidentId) {
330
- monitorChannels = await IncidentService.getWorkspaceChannelForIncident({
331
- incidentId: data.notificationFor.incidentId,
332
- workspaceType: messageBlocksByWorkspaceType.workspaceType,
333
- });
334
- }
335
-
336
- // alerts
337
- if (data.notificationFor.alertId) {
338
- monitorChannels = await AlertService.getWorkspaceChannelForAlert({
339
- alertId: data.notificationFor.alertId,
400
+ const monitorChannels: Array<WorkspaceChannel> =
401
+ await this.getWorkspaceChannelsByNotificationFor({
402
+ projectId: data.projectId,
403
+ notificationFor: data.notificationFor,
340
404
  workspaceType: messageBlocksByWorkspaceType.workspaceType,
341
405
  });
342
- }
343
-
344
- // scheduled maintenance
345
-
346
- if (data.notificationFor.scheduledMaintenanceId) {
347
- monitorChannels =
348
- await ScheduledMaintenanceService.getWorkspaceChannelForScheduledMaintenance(
349
- {
350
- scheduledMaintenanceId:
351
- data.notificationFor.scheduledMaintenanceId,
352
- workspaceType: messageBlocksByWorkspaceType.workspaceType,
353
- },
354
- );
355
- }
356
406
 
357
407
  const workspaceMessagePayload: WorkspaceMessagePayload = {
358
408
  _type: "WorkspaceMessagePayload",
@@ -374,6 +424,49 @@ export class Service extends DatabaseService<WorkspaceNotificationRule> {
374
424
  });
375
425
  }
376
426
 
427
+ private async getWorkspaceChannelsByNotificationFor(data: {
428
+ projectId: ObjectID;
429
+ notificationFor: NotificationFor;
430
+ workspaceType: WorkspaceType;
431
+ }): Promise<Array<WorkspaceChannel>> {
432
+ let monitorChannels: Array<WorkspaceChannel> = [];
433
+
434
+ if (data.notificationFor.monitorId) {
435
+ monitorChannels = await MonitorService.getWorkspaceChannelForMonitor({
436
+ monitorId: data.notificationFor.monitorId,
437
+ workspaceType: data.workspaceType,
438
+ });
439
+ }
440
+
441
+ // incidents
442
+ if (data.notificationFor.incidentId) {
443
+ monitorChannels = await IncidentService.getWorkspaceChannelForIncident({
444
+ incidentId: data.notificationFor.incidentId,
445
+ workspaceType: data.workspaceType,
446
+ });
447
+ }
448
+
449
+ // alerts
450
+ if (data.notificationFor.alertId) {
451
+ monitorChannels = await AlertService.getWorkspaceChannelForAlert({
452
+ alertId: data.notificationFor.alertId,
453
+ workspaceType: data.workspaceType,
454
+ });
455
+ }
456
+
457
+ // scheduled maintenance
458
+ if (data.notificationFor.scheduledMaintenanceId) {
459
+ monitorChannels =
460
+ await ScheduledMaintenanceService.getWorkspaceChannelForScheduledMaintenance(
461
+ {
462
+ scheduledMaintenanceId: data.notificationFor.scheduledMaintenanceId,
463
+ workspaceType: data.workspaceType,
464
+ },
465
+ );
466
+ }
467
+ return monitorChannels;
468
+ }
469
+
377
470
  private getNotificationRuleEventType(
378
471
  notificationFor: NotificationFor,
379
472
  ): NotificationRuleEventType {
@@ -503,7 +503,7 @@ export default class SlackAlertActions {
503
503
  // send a message to the channel visible to user, that the alert has already been Resolved.
504
504
  const markdwonPayload: WorkspacePayloadMarkdown = {
505
505
  _type: "WorkspacePayloadMarkdown",
506
- text: `@${slackUsername}, unfortunately you cannot execute the on call policy for **[Alert ${alertNumber?.toString()}](${await AlertService.getAlertLinkInDashboard(slackRequest.projectId!, alertId)})**. It has already been resolved.`,
506
+ text: `@${slackUsername}, unfortunately you cannot execute the on-call policy for **[Alert ${alertNumber?.toString()}](${await AlertService.getAlertLinkInDashboard(slackRequest.projectId!, alertId)})**. It has already been resolved.`,
507
507
  };
508
508
 
509
509
  await SlackUtil.sendDirectMessageToUser({
@@ -529,7 +529,7 @@ export default class SlackAlertActions {
529
529
  const onCallPolicyString: string =
530
530
  data.slackRequest.viewValues["onCallPolicy"].toString();
531
531
 
532
- // get the on call policy id.
532
+ // get the on-call policy id.
533
533
  const onCallPolicyId: ObjectID = new ObjectID(onCallPolicyString);
534
534
 
535
535
  await OnCallDutyPolicyService.executePolicy(onCallPolicyId, {
@@ -400,7 +400,7 @@ export default class SlackIncidentActions {
400
400
  blocks.push(monitorStatusDropdown);
401
401
  }
402
402
 
403
- // add on call policy dropdown.
403
+ // add on-call policy dropdown.
404
404
 
405
405
  const onCallPolicies: Array<OnCallDutyPolicy> =
406
406
  await OnCallDutyPolicyService.findBy({
@@ -957,7 +957,7 @@ export default class SlackIncidentActions {
957
957
  // send a message to the channel visible to user, that the incident has already been Resolved.
958
958
  const markdwonPayload: WorkspacePayloadMarkdown = {
959
959
  _type: "WorkspacePayloadMarkdown",
960
- text: `@${slackUsername}, unfortunately you cannot execute the on call policy for **[Incident ${incidentNumber?.toString()}](${await IncidentService.getIncidentLinkInDashboard(slackRequest.projectId!, incidentId)})**. It has already been resolved.`,
960
+ text: `@${slackUsername}, unfortunately you cannot execute the on-call policy for **[Incident ${incidentNumber?.toString()}](${await IncidentService.getIncidentLinkInDashboard(slackRequest.projectId!, incidentId)})**. It has already been resolved.`,
961
961
  };
962
962
 
963
963
  await SlackUtil.sendDirectMessageToUser({
@@ -983,7 +983,7 @@ export default class SlackIncidentActions {
983
983
  const onCallPolicyString: string =
984
984
  data.slackRequest.viewValues["onCallPolicy"].toString();
985
985
 
986
- // get the on call policy id.
986
+ // get the on-call policy id.
987
987
  const onCallPolicyId: ObjectID = new ObjectID(onCallPolicyString);
988
988
 
989
989
  await OnCallDutyPolicyService.executePolicy(onCallPolicyId, {