@oneuptime/common 7.0.3786 → 7.0.3822

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 (137) hide show
  1. package/Models/DatabaseModels/AlertStateTimeline.ts +1 -1
  2. package/Models/DatabaseModels/IncidentStateTimeline.ts +1 -1
  3. package/Models/DatabaseModels/MonitorStatusTimeline.ts +1 -1
  4. package/Models/DatabaseModels/ScheduledMaintenanceStateTimeline.ts +1 -1
  5. package/Models/DatabaseModels/WorkspaceNotificationRule.ts +8 -0
  6. package/Server/API/SlackAPI.ts +68 -0
  7. package/Server/Services/AccessTokenService.ts +21 -0
  8. package/Server/Services/AlertFeedService.ts +98 -0
  9. package/Server/Services/AlertInternalNoteService.ts +49 -8
  10. package/Server/Services/AlertOwnerTeamService.ts +50 -2
  11. package/Server/Services/AlertOwnerUserService.ts +52 -2
  12. package/Server/Services/AlertService.ts +236 -37
  13. package/Server/Services/AlertStateService.ts +24 -0
  14. package/Server/Services/AlertStateTimelineService.ts +30 -2
  15. package/Server/Services/IncidentInternalNoteService.ts +6 -6
  16. package/Server/Services/IncidentPublicNoteService.ts +7 -4
  17. package/Server/Services/IncidentStateTimelineService.ts +2 -1
  18. package/Server/Services/MonitorStatusTimelineService.ts +202 -101
  19. package/Server/Services/ScheduledMaintenanceFeedService.ts +103 -0
  20. package/Server/Services/ScheduledMaintenanceInternalNoteService.ts +50 -6
  21. package/Server/Services/ScheduledMaintenanceOwnerTeamService.ts +37 -0
  22. package/Server/Services/ScheduledMaintenanceOwnerUserService.ts +34 -0
  23. package/Server/Services/ScheduledMaintenancePublicNoteService.ts +49 -7
  24. package/Server/Services/ScheduledMaintenanceService.ts +375 -12
  25. package/Server/Services/ScheduledMaintenanceStateService.ts +122 -34
  26. package/Server/Services/ScheduledMaintenanceStateTimelineService.ts +33 -1
  27. package/Server/Services/WorkspaceNotificationRuleService.ts +12 -0
  28. package/Server/Utils/Workspace/MicrosoftTeams/Actions/ActionTypes.ts +38 -0
  29. package/Server/Utils/Workspace/MicrosoftTeams/Messages/Alert.ts +116 -0
  30. package/Server/Utils/Workspace/MicrosoftTeams/Messages/Incident.ts +36 -115
  31. package/Server/Utils/Workspace/MicrosoftTeams/Messages/ScheduledMaintenance.ts +108 -0
  32. package/Server/Utils/Workspace/Slack/Actions/ActionTypes.ts +20 -2
  33. package/Server/Utils/Workspace/Slack/Actions/Alert.ts +697 -0
  34. package/Server/Utils/Workspace/Slack/Actions/Auth.ts +9 -2
  35. package/Server/Utils/Workspace/Slack/Actions/Incident.ts +9 -3
  36. package/Server/Utils/Workspace/Slack/Actions/ScheduledMaintenance.ts +956 -0
  37. package/Server/Utils/Workspace/Slack/Messages/Alert.ts +116 -0
  38. package/Server/Utils/Workspace/Slack/Messages/ScheduledMaintenance.ts +108 -0
  39. package/Server/Utils/Workspace/Slack/Slack.ts +48 -2
  40. package/Server/Utils/Workspace/Slack/app-manifest.json +3 -3
  41. package/Server/Utils/Workspace/WorkspaceBase.ts +14 -0
  42. package/Server/Utils/Workspace/WorkspaceMessages/Alert.ts +69 -0
  43. package/Server/Utils/Workspace/WorkspaceMessages/ScheduledMaintenance.ts +73 -0
  44. package/Types/Date.ts +5 -0
  45. package/Types/Workspace/WorkspaceMessagePayload.ts +9 -0
  46. package/UI/Components/Forms/BasicForm.tsx +4 -0
  47. package/UI/Components/Forms/Types/Field.ts +3 -0
  48. package/build/dist/Models/DatabaseModels/AlertStateTimeline.js +1 -1
  49. package/build/dist/Models/DatabaseModels/AlertStateTimeline.js.map +1 -1
  50. package/build/dist/Models/DatabaseModels/IncidentStateTimeline.js +1 -1
  51. package/build/dist/Models/DatabaseModels/IncidentStateTimeline.js.map +1 -1
  52. package/build/dist/Models/DatabaseModels/MonitorStatusTimeline.js +1 -1
  53. package/build/dist/Models/DatabaseModels/MonitorStatusTimeline.js.map +1 -1
  54. package/build/dist/Models/DatabaseModels/ScheduledMaintenanceStateTimeline.js +1 -1
  55. package/build/dist/Models/DatabaseModels/ScheduledMaintenanceStateTimeline.js.map +1 -1
  56. package/build/dist/Models/DatabaseModels/WorkspaceNotificationRule.js +8 -0
  57. package/build/dist/Models/DatabaseModels/WorkspaceNotificationRule.js.map +1 -1
  58. package/build/dist/Server/API/SlackAPI.js +54 -0
  59. package/build/dist/Server/API/SlackAPI.js.map +1 -1
  60. package/build/dist/Server/Services/AccessTokenService.js +11 -0
  61. package/build/dist/Server/Services/AccessTokenService.js.map +1 -1
  62. package/build/dist/Server/Services/AlertFeedService.js +60 -0
  63. package/build/dist/Server/Services/AlertFeedService.js.map +1 -1
  64. package/build/dist/Server/Services/AlertInternalNoteService.js +39 -8
  65. package/build/dist/Server/Services/AlertInternalNoteService.js.map +1 -1
  66. package/build/dist/Server/Services/AlertOwnerTeamService.js +40 -2
  67. package/build/dist/Server/Services/AlertOwnerTeamService.js.map +1 -1
  68. package/build/dist/Server/Services/AlertOwnerUserService.js +41 -3
  69. package/build/dist/Server/Services/AlertOwnerUserService.js.map +1 -1
  70. package/build/dist/Server/Services/AlertService.js +192 -35
  71. package/build/dist/Server/Services/AlertService.js.map +1 -1
  72. package/build/dist/Server/Services/AlertStateService.js +13 -0
  73. package/build/dist/Server/Services/AlertStateService.js.map +1 -1
  74. package/build/dist/Server/Services/AlertStateTimelineService.js +26 -2
  75. package/build/dist/Server/Services/AlertStateTimelineService.js.map +1 -1
  76. package/build/dist/Server/Services/IncidentInternalNoteService.js +6 -6
  77. package/build/dist/Server/Services/IncidentInternalNoteService.js.map +1 -1
  78. package/build/dist/Server/Services/IncidentPublicNoteService.js +5 -4
  79. package/build/dist/Server/Services/IncidentPublicNoteService.js.map +1 -1
  80. package/build/dist/Server/Services/IncidentStateTimelineService.js +1 -1
  81. package/build/dist/Server/Services/IncidentStateTimelineService.js.map +1 -1
  82. package/build/dist/Server/Services/MonitorStatusTimelineService.js +168 -72
  83. package/build/dist/Server/Services/MonitorStatusTimelineService.js.map +1 -1
  84. package/build/dist/Server/Services/ScheduledMaintenanceFeedService.js +60 -0
  85. package/build/dist/Server/Services/ScheduledMaintenanceFeedService.js.map +1 -1
  86. package/build/dist/Server/Services/ScheduledMaintenanceInternalNoteService.js +36 -6
  87. package/build/dist/Server/Services/ScheduledMaintenanceInternalNoteService.js.map +1 -1
  88. package/build/dist/Server/Services/ScheduledMaintenanceOwnerTeamService.js +24 -0
  89. package/build/dist/Server/Services/ScheduledMaintenanceOwnerTeamService.js.map +1 -1
  90. package/build/dist/Server/Services/ScheduledMaintenanceOwnerUserService.js +22 -0
  91. package/build/dist/Server/Services/ScheduledMaintenanceOwnerUserService.js.map +1 -1
  92. package/build/dist/Server/Services/ScheduledMaintenancePublicNoteService.js +36 -7
  93. package/build/dist/Server/Services/ScheduledMaintenancePublicNoteService.js.map +1 -1
  94. package/build/dist/Server/Services/ScheduledMaintenanceService.js +275 -13
  95. package/build/dist/Server/Services/ScheduledMaintenanceService.js.map +1 -1
  96. package/build/dist/Server/Services/ScheduledMaintenanceStateService.js +52 -4
  97. package/build/dist/Server/Services/ScheduledMaintenanceStateService.js.map +1 -1
  98. package/build/dist/Server/Services/ScheduledMaintenanceStateTimelineService.js +28 -1
  99. package/build/dist/Server/Services/ScheduledMaintenanceStateTimelineService.js.map +1 -1
  100. package/build/dist/Server/Services/WorkspaceNotificationRuleService.js +10 -0
  101. package/build/dist/Server/Services/WorkspaceNotificationRuleService.js.map +1 -1
  102. package/build/dist/Server/Utils/Workspace/MicrosoftTeams/Actions/ActionTypes.js +37 -0
  103. package/build/dist/Server/Utils/Workspace/MicrosoftTeams/Actions/ActionTypes.js.map +1 -0
  104. package/build/dist/Server/Utils/Workspace/MicrosoftTeams/Messages/Alert.js +82 -0
  105. package/build/dist/Server/Utils/Workspace/MicrosoftTeams/Messages/Alert.js.map +1 -0
  106. package/build/dist/Server/Utils/Workspace/MicrosoftTeams/Messages/Incident.js +33 -99
  107. package/build/dist/Server/Utils/Workspace/MicrosoftTeams/Messages/Incident.js.map +1 -1
  108. package/build/dist/Server/Utils/Workspace/MicrosoftTeams/Messages/ScheduledMaintenance.js +74 -0
  109. package/build/dist/Server/Utils/Workspace/MicrosoftTeams/Messages/ScheduledMaintenance.js.map +1 -0
  110. package/build/dist/Server/Utils/Workspace/Slack/Actions/ActionTypes.js +20 -2
  111. package/build/dist/Server/Utils/Workspace/Slack/Actions/ActionTypes.js.map +1 -1
  112. package/build/dist/Server/Utils/Workspace/Slack/Actions/Alert.js +425 -0
  113. package/build/dist/Server/Utils/Workspace/Slack/Actions/Alert.js.map +1 -0
  114. package/build/dist/Server/Utils/Workspace/Slack/Actions/Auth.js +2 -0
  115. package/build/dist/Server/Utils/Workspace/Slack/Actions/Auth.js.map +1 -1
  116. package/build/dist/Server/Utils/Workspace/Slack/Actions/Incident.js +5 -2
  117. package/build/dist/Server/Utils/Workspace/Slack/Actions/Incident.js.map +1 -1
  118. package/build/dist/Server/Utils/Workspace/Slack/Actions/ScheduledMaintenance.js +599 -0
  119. package/build/dist/Server/Utils/Workspace/Slack/Actions/ScheduledMaintenance.js.map +1 -0
  120. package/build/dist/Server/Utils/Workspace/Slack/Messages/Alert.js +82 -0
  121. package/build/dist/Server/Utils/Workspace/Slack/Messages/Alert.js.map +1 -0
  122. package/build/dist/Server/Utils/Workspace/Slack/Messages/ScheduledMaintenance.js +74 -0
  123. package/build/dist/Server/Utils/Workspace/Slack/Messages/ScheduledMaintenance.js.map +1 -0
  124. package/build/dist/Server/Utils/Workspace/Slack/Slack.js +34 -0
  125. package/build/dist/Server/Utils/Workspace/Slack/Slack.js.map +1 -1
  126. package/build/dist/Server/Utils/Workspace/Slack/app-manifest.json +3 -3
  127. package/build/dist/Server/Utils/Workspace/WorkspaceBase.js +8 -0
  128. package/build/dist/Server/Utils/Workspace/WorkspaceBase.js.map +1 -1
  129. package/build/dist/Server/Utils/Workspace/WorkspaceMessages/Alert.js +48 -0
  130. package/build/dist/Server/Utils/Workspace/WorkspaceMessages/Alert.js.map +1 -0
  131. package/build/dist/Server/Utils/Workspace/WorkspaceMessages/ScheduledMaintenance.js +47 -0
  132. package/build/dist/Server/Utils/Workspace/WorkspaceMessages/ScheduledMaintenance.js.map +1 -0
  133. package/build/dist/Types/Date.js +4 -0
  134. package/build/dist/Types/Date.js.map +1 -1
  135. package/build/dist/UI/Components/Forms/BasicForm.js +3 -0
  136. package/build/dist/UI/Components/Forms/BasicForm.js.map +1 -1
  137. package/package.json +2 -2
@@ -514,7 +514,7 @@ export default class AlertStateTimeline extends BaseModel {
514
514
  @TableColumn({
515
515
  type: TableColumnType.Date,
516
516
  title: "Starts At",
517
- description: "When did this status change start?",
517
+ description: "When did this status change?",
518
518
  })
519
519
  @Column({
520
520
  type: ColumnType.Date,
@@ -567,7 +567,7 @@ export default class IncidentStateTimeline extends BaseModel {
567
567
  @TableColumn({
568
568
  type: TableColumnType.Date,
569
569
  title: "Starts At",
570
- description: "When did this status change start?",
570
+ description: "When did this status change?",
571
571
  })
572
572
  @Column({
573
573
  type: ColumnType.Date,
@@ -515,7 +515,7 @@ export default class MonitorStatusTimeline extends BaseModel {
515
515
  @TableColumn({
516
516
  type: TableColumnType.Date,
517
517
  title: "Starts At",
518
- description: "When did this status change start?",
518
+ description: "When did this status change?",
519
519
  })
520
520
  @Column({
521
521
  type: ColumnType.Date,
@@ -516,7 +516,7 @@ export default class ScheduledMaintenanceStateTimeline extends BaseModel {
516
516
  @TableColumn({
517
517
  type: TableColumnType.Date,
518
518
  title: "Starts At",
519
- description: "When did this status change start?",
519
+ description: "When did this status change?",
520
520
  })
521
521
  @Column({
522
522
  type: ColumnType.Date,
@@ -19,6 +19,8 @@ import WorkspaceType from "../../Types/Workspace/WorkspaceType";
19
19
  import BaseNotificationRule from "../../Types/Workspace/NotificationRules/BaseNotificationRule";
20
20
  import NotificationRuleEventType from "../../Types/Workspace/NotificationRules/EventType";
21
21
  import Permission from "../../Types/Permission";
22
+ import TableBillingAccessControl from "../../Types/Database/AccessControl/TableBillingAccessControl";
23
+ import { PlanType } from "../../Types/Billing/SubscriptionPlan";
22
24
 
23
25
  @TenantColumn("projectId")
24
26
  @AllowAccessIfSubscriptionIsUnpaid()
@@ -48,6 +50,12 @@ import Permission from "../../Types/Permission";
48
50
  Permission.EditWorkspaceNotificationRule,
49
51
  ],
50
52
  })
53
+ @TableBillingAccessControl({
54
+ create: PlanType.Growth,
55
+ read: PlanType.Growth,
56
+ update: PlanType.Growth,
57
+ delete: PlanType.Growth,
58
+ })
51
59
  @CrudApiEndpoint(new Route("/workspace-notification-rule"))
52
60
  @Entity({
53
61
  name: "WorkspaceNotificationRule",
@@ -30,6 +30,9 @@ import SlackAuthAction, {
30
30
  SlackRequest,
31
31
  } from "../Utils/Workspace/Slack/Actions/Auth";
32
32
  import SlackIncidentActions from "../Utils/Workspace/Slack/Actions/Incident";
33
+ import SlackAlertActions from "../Utils/Workspace/Slack/Actions/Alert";
34
+ import SlackScheduledMaintenanceActions from "../Utils/Workspace/Slack/Actions/ScheduledMaintenance";
35
+ import LIMIT_MAX from "../../Types/Database/LimitMax";
33
36
 
34
37
  export default class SlackAPI {
35
38
  public getRouter(): ExpressRouter {
@@ -283,6 +286,43 @@ export default class SlackAPI {
283
286
  logger.debug("Slack Interactive Auth Result: ");
284
287
  logger.debug(authResult);
285
288
 
289
+ // if slack uninstall app then,
290
+ if (authResult.payloadType === "app_uninstall") {
291
+ logger.debug("Slack App Uninstall Request: ");
292
+
293
+ // remove the project auth and user auth.
294
+
295
+ // delete all user auth tokens for this project.
296
+ await WorkspaceUserAuthTokenService.deleteBy({
297
+ query: {
298
+ projectId: authResult.projectId,
299
+ workspaceType: WorkspaceType.Slack,
300
+ },
301
+ limit: LIMIT_MAX,
302
+ skip: 0,
303
+ props: {
304
+ isRoot: true,
305
+ },
306
+ });
307
+
308
+ await WorkspaceProjectAuthTokenService.deleteBy({
309
+ query: {
310
+ projectId: authResult.projectId,
311
+ workspaceType: WorkspaceType.Slack,
312
+ },
313
+ limit: 1,
314
+ skip: 0,
315
+ props: {
316
+ isRoot: true,
317
+ },
318
+ });
319
+
320
+ logger.debug("Slack App Uninstall Request: Deleted all auth tokens.");
321
+ // return empty response.
322
+
323
+ return Response.sendTextResponse(req, res, "");
324
+ }
325
+
286
326
  if (authResult.isAuthorized === false) {
287
327
  // return empty response if not authorized. Do nothing in this case.
288
328
  return Response.sendTextResponse(req, res, "");
@@ -309,6 +349,34 @@ export default class SlackAPI {
309
349
  res: res,
310
350
  });
311
351
  }
352
+
353
+ if (
354
+ SlackAlertActions.isAlertAction({
355
+ actionType: action.actionType,
356
+ })
357
+ ) {
358
+ return SlackAlertActions.handleAlertAction({
359
+ slackRequest: authResult,
360
+ action: action,
361
+ req: req,
362
+ res: res,
363
+ });
364
+ }
365
+
366
+ if (
367
+ SlackScheduledMaintenanceActions.isScheduledMaintenanceAction({
368
+ actionType: action.actionType,
369
+ })
370
+ ) {
371
+ return SlackScheduledMaintenanceActions.handleScheduledMaintenanceAction(
372
+ {
373
+ slackRequest: authResult,
374
+ action: action,
375
+ req: req,
376
+ res: res,
377
+ },
378
+ );
379
+ }
312
380
  }
313
381
 
314
382
  return Response.sendErrorResponse(
@@ -15,6 +15,7 @@ import TeamMember from "Common/Models/DatabaseModels/TeamMember";
15
15
  import TeamPermission from "Common/Models/DatabaseModels/TeamPermission";
16
16
  import UserPermissionUtil from "../Utils/UserPermission/UserPermission";
17
17
  import PermissionNamespace from "../Types/Permission/PermissionNamespace";
18
+ import DatabaseCommonInteractionProps from "../../Types/BaseDatabase/DatabaseCommonInteractionProps";
18
19
 
19
20
  export class AccessTokenService extends BaseService {
20
21
  public constructor() {
@@ -198,6 +199,26 @@ export class AccessTokenService extends BaseService {
198
199
  return permission;
199
200
  }
200
201
 
202
+ public async getDatabaseCommonInteractionPropsByUserAndProject(data: {
203
+ userId: ObjectID;
204
+ projectId: ObjectID;
205
+ }): Promise<DatabaseCommonInteractionProps> {
206
+ const { userId, projectId } = data;
207
+
208
+ return {
209
+ userId: userId,
210
+ userGlobalAccessPermission:
211
+ (await this.getUserGlobalAccessPermission(userId)) || undefined,
212
+ userTenantAccessPermission: {
213
+ [projectId.toString()]: (await this.getUserTenantAccessPermission(
214
+ userId,
215
+ projectId,
216
+ ))!,
217
+ },
218
+ tenantId: projectId,
219
+ };
220
+ }
221
+
201
222
  public async getUserTenantAccessPermission(
202
223
  userId: ObjectID,
203
224
  projectId: ObjectID,
@@ -3,12 +3,21 @@ import Color from "../../Types/Color";
3
3
  import OneUptimeDate from "../../Types/Date";
4
4
  import BadDataException from "../../Types/Exception/BadDataException";
5
5
  import ObjectID from "../../Types/ObjectID";
6
+ import WorkspaceMessagePayload from "../../Types/Workspace/WorkspaceMessagePayload";
6
7
  import { IsBillingEnabled } from "../EnvironmentConfig";
7
8
  import logger from "../Utils/Logger";
9
+ import { WorkspaceChannel } from "../Utils/Workspace/WorkspaceBase";
10
+ import AlertService from "./AlertService";
8
11
  import DatabaseService from "./DatabaseService";
9
12
  import Model, {
10
13
  AlertFeedEventType,
11
14
  } from "Common/Models/DatabaseModels/AlertFeed";
15
+ import WorkspaceNotificationRuleService, {
16
+ MessageBlocksByWorkspaceType,
17
+ } from "./WorkspaceNotificationRuleService";
18
+ import NotificationRuleEventType from "../../Types/Workspace/NotificationRules/EventType";
19
+ import WorkspaceUtil from "../Utils/Workspace/Workspace";
20
+ import WorkspaceType from "../../Types/Workspace/WorkspaceType";
12
21
 
13
22
  export class Service extends DatabaseService<Model> {
14
23
  public constructor() {
@@ -28,6 +37,13 @@ export class Service extends DatabaseService<Model> {
28
37
  displayColor?: Color | undefined;
29
38
  userId?: ObjectID | undefined;
30
39
  postedAt?: Date | undefined;
40
+ workspaceNotification?:
41
+ | {
42
+ notifyUserId?: ObjectID | undefined; // this is oneuptime user id.
43
+ sendWorkspaceNotification: boolean;
44
+ appendMessageBlocks?: Array<MessageBlocksByWorkspaceType> | undefined;
45
+ }
46
+ | undefined;
31
47
  }): Promise<void> {
32
48
  try {
33
49
  if (!data.alertId) {
@@ -77,6 +93,88 @@ export class Service extends DatabaseService<Model> {
77
93
  isRoot: true,
78
94
  },
79
95
  });
96
+
97
+ try {
98
+ // send notification to slack and teams
99
+ if (data.workspaceNotification?.sendWorkspaceNotification) {
100
+ let messageBlocksByWorkspaceTypes: Array<MessageBlocksByWorkspaceType> =
101
+ [];
102
+
103
+ // use markdown to create blocks
104
+ messageBlocksByWorkspaceTypes =
105
+ await WorkspaceUtil.getMessageBlocksByMarkdown({
106
+ userId: data.workspaceNotification.notifyUserId,
107
+ markdown: data.feedInfoInMarkdown,
108
+ projectId: data.projectId,
109
+ });
110
+
111
+ if (data.workspaceNotification.appendMessageBlocks) {
112
+ for (const messageBlocksByWorkspaceType of data
113
+ .workspaceNotification.appendMessageBlocks) {
114
+ const workspaceType: WorkspaceType =
115
+ messageBlocksByWorkspaceType.workspaceType;
116
+
117
+ messageBlocksByWorkspaceTypes
118
+ .find(
119
+ (
120
+ messageBlocksByWorkspaceType: MessageBlocksByWorkspaceType,
121
+ ) => {
122
+ return (
123
+ messageBlocksByWorkspaceType.workspaceType ===
124
+ workspaceType
125
+ );
126
+ },
127
+ )
128
+ ?.messageBlocks.push(
129
+ ...messageBlocksByWorkspaceType.messageBlocks,
130
+ );
131
+ }
132
+ }
133
+
134
+ const workspaceNotificationPaylaods: Array<WorkspaceMessagePayload> =
135
+ [];
136
+
137
+ for (const messageBlocksByWorkspaceType of messageBlocksByWorkspaceTypes) {
138
+ const existingChannels: Array<string> =
139
+ await WorkspaceNotificationRuleService.getExistingChannelNamesBasedOnEventType(
140
+ {
141
+ projectId: data.projectId,
142
+ notificationRuleEventType: NotificationRuleEventType.Alert,
143
+ workspaceType: messageBlocksByWorkspaceType.workspaceType,
144
+ },
145
+ );
146
+
147
+ const alertChannels: Array<WorkspaceChannel> =
148
+ await AlertService.getWorkspaceChannelForAlert({
149
+ alertId: data.alertId,
150
+ workspaceType: messageBlocksByWorkspaceType.workspaceType,
151
+ });
152
+
153
+ const workspaceMessagePayload: WorkspaceMessagePayload = {
154
+ _type: "WorkspaceMessagePayload",
155
+ workspaceType: messageBlocksByWorkspaceType.workspaceType,
156
+ messageBlocks: messageBlocksByWorkspaceType.messageBlocks,
157
+ channelNames: existingChannels,
158
+ channelIds:
159
+ alertChannels.map((channel: WorkspaceChannel) => {
160
+ return channel.id;
161
+ }) || [],
162
+ };
163
+
164
+ workspaceNotificationPaylaods.push(workspaceMessagePayload);
165
+ }
166
+
167
+ await WorkspaceUtil.postMessageToAllWorkspaceChannelsAsBot({
168
+ projectId: data.projectId,
169
+ messagePayloadsByWorkspace: workspaceNotificationPaylaods,
170
+ });
171
+ }
172
+ } catch (e) {
173
+ logger.error("Error in sending notification to slack and teams");
174
+ logger.error(e);
175
+
176
+ // we dont throw this error as it is not a critical error
177
+ }
80
178
  } catch (error) {
81
179
  logger.error("AlertFeedService.createAlertFeedItem");
82
180
  logger.error(error);
@@ -6,12 +6,34 @@ import AlertFeedService from "./AlertFeedService";
6
6
  import { AlertFeedEventType } from "../../Models/DatabaseModels/AlertFeed";
7
7
  import { Blue500 } from "../../Types/BrandColors";
8
8
  import { LIMIT_PER_PROJECT } from "../../Types/Database/LimitMax";
9
+ import Alert from "../../Models/DatabaseModels/Alert";
10
+ import AlertService from "./AlertService";
9
11
 
10
12
  export class Service extends DatabaseService<Model> {
11
13
  public constructor() {
12
14
  super(Model);
13
15
  }
14
16
 
17
+ public async addNote(data: {
18
+ userId: ObjectID;
19
+ alertId: ObjectID;
20
+ projectId: ObjectID;
21
+ note: string;
22
+ }): Promise<Model> {
23
+ const internalNote: Model = new Model();
24
+ internalNote.createdByUserId = data.userId;
25
+ internalNote.alertId = data.alertId;
26
+ internalNote.projectId = data.projectId;
27
+ internalNote.note = data.note;
28
+
29
+ return this.create({
30
+ data: internalNote,
31
+ props: {
32
+ isRoot: true,
33
+ },
34
+ });
35
+ }
36
+
15
37
  public override async onCreateSuccess(
16
38
  _onCreate: OnCreate<Model>,
17
39
  createdItem: Model,
@@ -19,6 +41,12 @@ export class Service extends DatabaseService<Model> {
19
41
  const userId: ObjectID | null | undefined =
20
42
  createdItem.createdByUserId || createdItem.createdByUser?.id;
21
43
 
44
+ const alertId: ObjectID = createdItem.alertId!;
45
+
46
+ const alertNumber: number | null = await AlertService.getAlertNumber({
47
+ alertId: alertId,
48
+ });
49
+
22
50
  await AlertFeedService.createAlertFeedItem({
23
51
  alertId: createdItem.alertId!,
24
52
  projectId: createdItem.projectId!,
@@ -26,10 +54,14 @@ export class Service extends DatabaseService<Model> {
26
54
  displayColor: Blue500,
27
55
  userId: userId || undefined,
28
56
 
29
- feedInfoInMarkdown: `**Posted Internal / Private Note**
30
-
31
- ${createdItem.note}
32
- `,
57
+ feedInfoInMarkdown: `📄 posted **private note** for this [Alert ${alertNumber}](${(await AlertService.getAlertLinkInDashboard(createdItem.projectId!, alertId)).toString()}):
58
+
59
+ ${createdItem.note}
60
+ `,
61
+ workspaceNotification: {
62
+ sendWorkspaceNotification: true,
63
+ notifyUserId: userId || undefined,
64
+ },
33
65
  });
34
66
 
35
67
  return createdItem;
@@ -52,6 +84,10 @@ export class Service extends DatabaseService<Model> {
52
84
  projectId: true,
53
85
  note: true,
54
86
  createdByUserId: true,
87
+ alert: {
88
+ projectId: true,
89
+ alertNumber: true,
90
+ },
55
91
  createdByUser: {
56
92
  _id: true,
57
93
  },
@@ -62,6 +98,7 @@ export class Service extends DatabaseService<Model> {
62
98
  onUpdate.updateBy.props.userId;
63
99
 
64
100
  for (const updatedItem of updatedItems) {
101
+ const alert: Alert = updatedItem.alert!;
65
102
  await AlertFeedService.createAlertFeedItem({
66
103
  alertId: updatedItem.alertId!,
67
104
  projectId: updatedItem.projectId!,
@@ -69,10 +106,14 @@ export class Service extends DatabaseService<Model> {
69
106
  displayColor: Blue500,
70
107
  userId: userId || undefined,
71
108
 
72
- feedInfoInMarkdown: `**Updated Internal / Private Note**
73
-
74
- ${updatedItem.note}
75
- `,
109
+ feedInfoInMarkdown: `📄 updated **Private Note** for this [Alert ${alert.alertNumber}](${(await AlertService.getAlertLinkInDashboard(alert.projectId!, alert.id!)).toString()})
110
+
111
+ ${updatedItem.note}
112
+ `,
113
+ workspaceNotification: {
114
+ sendWorkspaceNotification: true,
115
+ notifyUserId: userId || undefined,
116
+ },
76
117
  });
77
118
  }
78
119
  }
@@ -8,6 +8,11 @@ import TeamService from "./TeamService";
8
8
  import AlertFeedService from "./AlertFeedService";
9
9
  import { AlertFeedEventType } from "../../Models/DatabaseModels/AlertFeed";
10
10
  import { Gray500, Red500 } from "../../Types/BrandColors";
11
+ import AlertService from "./AlertService";
12
+ import WorkspaceNotificationRule from "../../Models/DatabaseModels/WorkspaceNotificationRule";
13
+ import WorkspaceNotificationRuleService from "./WorkspaceNotificationRuleService";
14
+ import NotificationRuleEventType from "../../Types/Workspace/NotificationRules/EventType";
15
+ import logger from "../Utils/Logger";
11
16
 
12
17
  export class Service extends DatabaseService<Model> {
13
18
  public constructor() {
@@ -65,13 +70,20 @@ export class Service extends DatabaseService<Model> {
65
70
  });
66
71
 
67
72
  if (team && team.name) {
73
+ const alertNumber: number | null = await AlertService.getAlertNumber({
74
+ alertId: alertId,
75
+ });
68
76
  await AlertFeedService.createAlertFeedItem({
69
77
  alertId: alertId,
70
78
  projectId: projectId,
71
79
  alertFeedEventType: AlertFeedEventType.OwnerTeamRemoved,
72
80
  displayColor: Red500,
73
- feedInfoInMarkdown: `Removed team **${team.name}** from the alert as the owner.`,
81
+ feedInfoInMarkdown: `👨🏻‍👩🏻‍👦🏻 Removed team **${team.name}** from the [Alert ${alertNumber}](${(await AlertService.getAlertLinkInDashboard(projectId!, alertId!)).toString()}) as the owner.`,
74
82
  userId: deleteByUserId || undefined,
83
+ workspaceNotification: {
84
+ sendWorkspaceNotification: true,
85
+ notifyUserId: deleteByUserId || undefined,
86
+ },
75
87
  });
76
88
  }
77
89
  }
@@ -104,17 +116,53 @@ export class Service extends DatabaseService<Model> {
104
116
  });
105
117
 
106
118
  if (team && team.name) {
119
+ const alertNumber: number | null = await AlertService.getAlertNumber({
120
+ alertId: alertId,
121
+ });
122
+
107
123
  await AlertFeedService.createAlertFeedItem({
108
124
  alertId: alertId,
109
125
  projectId: projectId,
110
126
  alertFeedEventType: AlertFeedEventType.OwnerTeamAdded,
111
127
  displayColor: Gray500,
112
- feedInfoInMarkdown: `Added team **${team.name}** to the alert as the owner.`,
128
+ feedInfoInMarkdown: `👨🏻‍👩🏻‍👦🏻 Added team **${team.name}** to the [Alert ${alertNumber}](${(await AlertService.getAlertLinkInDashboard(projectId!, alertId!)).toString()}) as the owner.`,
113
129
  userId: createdByUserId || undefined,
130
+ workspaceNotification: {
131
+ sendWorkspaceNotification: true,
132
+ notifyUserId: createdByUserId || undefined,
133
+ },
114
134
  });
115
135
  }
116
136
  }
117
137
 
138
+ // get notification rule where inviteOwners is true.
139
+ const notificationRules: Array<WorkspaceNotificationRule> =
140
+ await WorkspaceNotificationRuleService.getNotificationRulesWhereInviteOwnersIsTrue(
141
+ {
142
+ projectId: projectId!,
143
+ notificationFor: {
144
+ alertId: alertId,
145
+ },
146
+ notificationRuleEventType: NotificationRuleEventType.Alert,
147
+ },
148
+ );
149
+
150
+ logger.debug(`Notification Rules for Alert Owner Teams`);
151
+ logger.debug(notificationRules);
152
+
153
+ WorkspaceNotificationRuleService.inviteTeamsBasedOnRulesAndWorkspaceChannels(
154
+ {
155
+ notificationRules: notificationRules,
156
+ projectId: projectId!,
157
+ workspaceChannels: await AlertService.getWorkspaceChannelForAlert({
158
+ alertId: alertId!,
159
+ }),
160
+ teamIds: [teamId!],
161
+ },
162
+ ).catch((error: Error) => {
163
+ logger.error(error);
164
+ });
165
+
118
166
  return createdItem;
119
167
  }
120
168
  }
@@ -8,6 +8,11 @@ import UserService from "./UserService";
8
8
  import AlertFeedService from "./AlertFeedService";
9
9
  import { AlertFeedEventType } from "../../Models/DatabaseModels/AlertFeed";
10
10
  import { Gray500, Red500 } from "../../Types/BrandColors";
11
+ import AlertService from "./AlertService";
12
+ import WorkspaceNotificationRule from "../../Models/DatabaseModels/WorkspaceNotificationRule";
13
+ import WorkspaceNotificationRuleService from "./WorkspaceNotificationRuleService";
14
+ import NotificationRuleEventType from "../../Types/Workspace/NotificationRules/EventType";
15
+ import logger from "../Utils/Logger";
11
16
 
12
17
  export class Service extends DatabaseService<Model> {
13
18
  public constructor() {
@@ -66,13 +71,21 @@ export class Service extends DatabaseService<Model> {
66
71
  });
67
72
 
68
73
  if (user && user.name) {
74
+ const alertNumber: number | null = await AlertService.getAlertNumber({
75
+ alertId: alertId,
76
+ });
77
+
69
78
  await AlertFeedService.createAlertFeedItem({
70
79
  alertId: alertId,
71
80
  projectId: projectId,
72
81
  alertFeedEventType: AlertFeedEventType.OwnerUserRemoved,
73
82
  displayColor: Red500,
74
- feedInfoInMarkdown: `Removed **${user.name.toString()}** (${user.email?.toString()}) from the alert as the owner.`,
83
+ feedInfoInMarkdown: `👨🏻‍💻 Removed **${user.name.toString()}** (${user.email?.toString()}) from the [Alert ${alertNumber}](${(await AlertService.getAlertLinkInDashboard(projectId!, alertId!)).toString()}) as the owner.`,
75
84
  userId: deleteByUserId || undefined,
85
+ workspaceNotification: {
86
+ sendWorkspaceNotification: true,
87
+ notifyUserId: userId || undefined,
88
+ },
76
89
  });
77
90
  }
78
91
  }
@@ -106,17 +119,54 @@ export class Service extends DatabaseService<Model> {
106
119
  });
107
120
 
108
121
  if (user && user.name) {
122
+ const alertNumber: number | null = await AlertService.getAlertNumber({
123
+ alertId: alertId,
124
+ });
109
125
  await AlertFeedService.createAlertFeedItem({
110
126
  alertId: alertId,
111
127
  projectId: projectId,
112
128
  alertFeedEventType: AlertFeedEventType.OwnerUserAdded,
113
129
  displayColor: Gray500,
114
- feedInfoInMarkdown: `**${user.name.toString()}** (${user.email?.toString()}) was added to the alert as the owner.`,
130
+ feedInfoInMarkdown: `👨🏻‍💻 Added **${await UserService.getUserMarkdownString(
131
+ {
132
+ userId: userId,
133
+ projectId: projectId,
134
+ },
135
+ )}** to the [Alert ${alertNumber}](${(await AlertService.getAlertLinkInDashboard(projectId!, alertId!)).toString()}) as the owner.`,
115
136
  userId: createdByUserId || undefined,
137
+ workspaceNotification: {
138
+ sendWorkspaceNotification: true,
139
+ notifyUserId: userId || undefined,
140
+ },
116
141
  });
117
142
  }
118
143
  }
119
144
 
145
+ // get notification rule where inviteOwners is true.
146
+ const notificationRules: Array<WorkspaceNotificationRule> =
147
+ await WorkspaceNotificationRuleService.getNotificationRulesWhereInviteOwnersIsTrue(
148
+ {
149
+ projectId: projectId!,
150
+ notificationFor: {
151
+ alertId: alertId,
152
+ },
153
+ notificationRuleEventType: NotificationRuleEventType.Alert,
154
+ },
155
+ );
156
+
157
+ WorkspaceNotificationRuleService.inviteUsersBasedOnRulesAndWorkspaceChannels(
158
+ {
159
+ notificationRules: notificationRules,
160
+ projectId: projectId!,
161
+ workspaceChannels: await AlertService.getWorkspaceChannelForAlert({
162
+ alertId: alertId!,
163
+ }),
164
+ userIds: [userId!],
165
+ },
166
+ ).catch((error: Error) => {
167
+ logger.error(error);
168
+ });
169
+
120
170
  return createdItem;
121
171
  }
122
172
  }