@oneuptime/common 7.0.3669 → 7.0.3679

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 (63) hide show
  1. package/Models/DatabaseModels/Alert.ts +4 -4
  2. package/Models/DatabaseModels/Incident.ts +4 -4
  3. package/Models/DatabaseModels/ScheduledMaintenance.ts +4 -4
  4. package/Server/API/SlackAPI.ts +1 -1
  5. package/Server/EnvironmentConfig.ts +4 -0
  6. package/Server/Infrastructure/Postgres/SchemaMigrations/1739569321582-MigrationName.ts +65 -0
  7. package/Server/Infrastructure/Postgres/SchemaMigrations/Index.ts +2 -0
  8. package/Server/Services/IncidentService.ts +58 -0
  9. package/Server/Services/ProjectService.ts +1 -1
  10. package/Server/Services/UserService.ts +1 -1
  11. package/Server/Services/WorkspaceNotificationRuleService.ts +266 -12
  12. package/Server/Types/Workflow/Components/Slack/SendMessageToChannel.ts +1 -1
  13. package/Server/Utils/Workspace/MicrosoftTeams/MicrosoftTeams.ts +3 -0
  14. package/Server/Utils/{Slack → Workspace/Slack}/Slack.ts +93 -172
  15. package/Server/Utils/Workspace/Workspace.ts +23 -0
  16. package/Server/Utils/Workspace/WorkspaceBase.ts +169 -0
  17. package/Types/Workspace/NotificationRules/CreateChannelNotificationRule.ts +14 -0
  18. package/Types/Workspace/NotificationRules/NotificationRuleCondition.ts +23 -11
  19. package/Types/Workspace/NotificationRules/NotificationRuleTypes/AlertNotificationRule.ts +3 -10
  20. package/Types/Workspace/NotificationRules/NotificationRuleTypes/IncidentNotificationRule.ts +3 -10
  21. package/Types/Workspace/NotificationRules/NotificationRuleTypes/ScheduledMaintenanceNotificationRule.ts +2 -10
  22. package/Types/Workspace/WorkspaceChannelInvitationPayload.ts +1 -1
  23. package/build/dist/Models/DatabaseModels/Alert.js +5 -6
  24. package/build/dist/Models/DatabaseModels/Alert.js.map +1 -1
  25. package/build/dist/Models/DatabaseModels/Incident.js +5 -6
  26. package/build/dist/Models/DatabaseModels/Incident.js.map +1 -1
  27. package/build/dist/Models/DatabaseModels/ScheduledMaintenance.js +5 -6
  28. package/build/dist/Models/DatabaseModels/ScheduledMaintenance.js.map +1 -1
  29. package/build/dist/Server/API/SlackAPI.js +1 -1
  30. package/build/dist/Server/API/SlackAPI.js.map +1 -1
  31. package/build/dist/Server/EnvironmentConfig.js +3 -0
  32. package/build/dist/Server/EnvironmentConfig.js.map +1 -1
  33. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1739569321582-MigrationName.js +28 -0
  34. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1739569321582-MigrationName.js.map +1 -0
  35. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/Index.js +2 -0
  36. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/Index.js.map +1 -1
  37. package/build/dist/Server/Services/IncidentService.js +47 -0
  38. package/build/dist/Server/Services/IncidentService.js.map +1 -1
  39. package/build/dist/Server/Services/ProjectService.js +1 -1
  40. package/build/dist/Server/Services/ProjectService.js.map +1 -1
  41. package/build/dist/Server/Services/UserService.js +1 -1
  42. package/build/dist/Server/Services/UserService.js.map +1 -1
  43. package/build/dist/Server/Services/WorkspaceNotificationRuleService.js +170 -1
  44. package/build/dist/Server/Services/WorkspaceNotificationRuleService.js.map +1 -1
  45. package/build/dist/Server/Types/Workflow/Components/Slack/SendMessageToChannel.js +1 -1
  46. package/build/dist/Server/Types/Workflow/Components/Slack/SendMessageToChannel.js.map +1 -1
  47. package/build/dist/Server/Utils/Workspace/MicrosoftTeams/MicrosoftTeams.js +4 -0
  48. package/build/dist/Server/Utils/Workspace/MicrosoftTeams/MicrosoftTeams.js.map +1 -0
  49. package/build/dist/Server/Utils/{Slack → Workspace/Slack}/Slack.js +53 -101
  50. package/build/dist/Server/Utils/Workspace/Slack/Slack.js.map +1 -0
  51. package/build/dist/Server/Utils/Workspace/Workspace.js +16 -0
  52. package/build/dist/Server/Utils/Workspace/Workspace.js.map +1 -0
  53. package/build/dist/Server/Utils/Workspace/WorkspaceBase.js +90 -0
  54. package/build/dist/Server/Utils/Workspace/WorkspaceBase.js.map +1 -0
  55. package/build/dist/Types/Workspace/NotificationRules/CreateChannelNotificationRule.js +2 -0
  56. package/build/dist/Types/Workspace/NotificationRules/CreateChannelNotificationRule.js.map +1 -0
  57. package/build/dist/Types/Workspace/NotificationRules/NotificationRuleCondition.js +17 -11
  58. package/build/dist/Types/Workspace/NotificationRules/NotificationRuleCondition.js.map +1 -1
  59. package/package.json +2 -2
  60. package/build/dist/Server/Utils/Slack/Slack.js.map +0 -1
  61. /package/Server/Utils/{Slack → Workspace/Slack}/app-manifest-temp.json +0 -0
  62. /package/Server/Utils/{Slack → Workspace/Slack}/app-manifest.json +0 -0
  63. /package/build/dist/Server/Utils/{Slack → Workspace/Slack}/app-manifest.json +0 -0
@@ -36,6 +36,7 @@ import {
36
36
  ManyToOne,
37
37
  } from "typeorm";
38
38
  import { TelemetryQuery } from "../../Types/Telemetry/TelemetryQuery";
39
+ import { WorkspaceChannel } from "../../Server/Utils/Workspace/WorkspaceBase";
39
40
 
40
41
  @EnableDocumentation()
41
42
  @AccessControlColumn("labels")
@@ -1044,14 +1045,13 @@ export default class Alert extends BaseModel {
1044
1045
  @TableColumn({
1045
1046
  isDefaultValueColumn: false,
1046
1047
  required: false,
1047
- type: TableColumnType.ShortText,
1048
+ type: TableColumnType.JSON,
1048
1049
  title: "Post Updates To Workspace Channel Name",
1049
1050
  description: "Post Updates To Workspace Channel Name",
1050
1051
  })
1051
1052
  @Column({
1052
- type: ColumnType.ShortText,
1053
- length: ColumnLength.ShortText,
1053
+ type: ColumnType.JSON,
1054
1054
  nullable: true,
1055
1055
  })
1056
- public postUpdatesToWorkspaceChannelName?: number = undefined;
1056
+ public postUpdatesToWorkspaceChannels?: Array<WorkspaceChannel> = undefined;
1057
1057
  }
@@ -37,6 +37,7 @@ import {
37
37
  ManyToOne,
38
38
  } from "typeorm";
39
39
  import { TelemetryQuery } from "../../Types/Telemetry/TelemetryQuery";
40
+ import { WorkspaceChannel } from "../../Server/Utils/Workspace/WorkspaceBase";
40
41
 
41
42
  @EnableDocumentation()
42
43
  @AccessControlColumn("labels")
@@ -1129,14 +1130,13 @@ export default class Incident extends BaseModel {
1129
1130
  @TableColumn({
1130
1131
  isDefaultValueColumn: false,
1131
1132
  required: false,
1132
- type: TableColumnType.ShortText,
1133
+ type: TableColumnType.JSON,
1133
1134
  title: "Post Updates To Workspace Channel Name",
1134
1135
  description: "Post Updates To Workspace Channel Name",
1135
1136
  })
1136
1137
  @Column({
1137
- type: ColumnType.ShortText,
1138
- length: ColumnLength.ShortText,
1138
+ type: ColumnType.JSON,
1139
1139
  nullable: true,
1140
1140
  })
1141
- public postUpdatesToWorkspaceChannelName?: number = undefined;
1141
+ public postUpdatesToWorkspaceChannels?: Array<WorkspaceChannel> = undefined;
1142
1142
  }
@@ -35,6 +35,7 @@ import {
35
35
  ManyToOne,
36
36
  } from "typeorm";
37
37
  import Recurring from "../../Types/Events/Recurring";
38
+ import { WorkspaceChannel } from "../../Server/Utils/Workspace/WorkspaceBase";
38
39
 
39
40
  @EnableDocumentation()
40
41
  @AccessControlColumn("labels")
@@ -988,14 +989,13 @@ export default class ScheduledMaintenance extends BaseModel {
988
989
  @TableColumn({
989
990
  isDefaultValueColumn: false,
990
991
  required: false,
991
- type: TableColumnType.ShortText,
992
+ type: TableColumnType.JSON,
992
993
  title: "Post Updates To Workspace Channel Name",
993
994
  description: "Post Updates To Workspace Channel Name",
994
995
  })
995
996
  @Column({
996
- type: ColumnType.ShortText,
997
- length: ColumnLength.ShortText,
997
+ type: ColumnType.JSON,
998
998
  nullable: true,
999
999
  })
1000
- public postUpdatesToWorkspaceChannelName?: number = undefined;
1000
+ public postUpdatesToWorkspaceChannels?: Array<WorkspaceChannel> = undefined;
1001
1001
  }
@@ -15,7 +15,7 @@ import {
15
15
  SlackAppClientId,
16
16
  SlackAppClientSecret,
17
17
  } from "../EnvironmentConfig";
18
- import SlackAppManifest from "../Utils/Slack/app-manifest.json";
18
+ import SlackAppManifest from "../Utils/Workspace/Slack/app-manifest.json";
19
19
  import URL from "../../Types/API/URL";
20
20
  import HTTPErrorResponse from "../../Types/API/HTTPErrorResponse";
21
21
  import HTTPResponse from "../../Types/API/HTTPResponse";
@@ -260,6 +260,10 @@ export const WorkflowScriptTimeoutInMS: number = process.env[
260
260
  ? parseInt(process.env["WORKFLOW_SCRIPT_TIMEOUT_IN_MS"].toString())
261
261
  : 5000;
262
262
 
263
+ export const WorkflowTimeoutInMs: number = process.env["WORKFLOW_TIMEOUT_IN_MS"]
264
+ ? parseInt(process.env["WORKFLOW_TIMEOUT_IN_MS"].toString())
265
+ : 5000;
266
+
263
267
  export const AllowedActiveMonitorCountInFreePlan: number = process.env[
264
268
  "ALLOWED_ACTIVE_MONITOR_COUNT_IN_FREE_PLAN"
265
269
  ]
@@ -0,0 +1,65 @@
1
+ import { MigrationInterface, QueryRunner } from "typeorm";
2
+
3
+ export class MigrationName1739569321582 implements MigrationInterface {
4
+ public name = "MigrationName1739569321582";
5
+
6
+ public async up(queryRunner: QueryRunner): Promise<void> {
7
+ await queryRunner.query(
8
+ `ALTER TABLE "Incident" RENAME COLUMN "postUpdatesToWorkspaceChannelName" TO "postUpdatesToWorkspaceChannels"`,
9
+ );
10
+ await queryRunner.query(
11
+ `ALTER TABLE "Alert" RENAME COLUMN "postUpdatesToWorkspaceChannelName" TO "postUpdatesToWorkspaceChannels"`,
12
+ );
13
+ await queryRunner.query(
14
+ `ALTER TABLE "ScheduledMaintenance" RENAME COLUMN "postUpdatesToWorkspaceChannelName" TO "postUpdatesToWorkspaceChannels"`,
15
+ );
16
+ await queryRunner.query(
17
+ `ALTER TABLE "Incident" DROP COLUMN "postUpdatesToWorkspaceChannels"`,
18
+ );
19
+ await queryRunner.query(
20
+ `ALTER TABLE "Incident" ADD "postUpdatesToWorkspaceChannels" jsonb`,
21
+ );
22
+ await queryRunner.query(
23
+ `ALTER TABLE "Alert" DROP COLUMN "postUpdatesToWorkspaceChannels"`,
24
+ );
25
+ await queryRunner.query(
26
+ `ALTER TABLE "Alert" ADD "postUpdatesToWorkspaceChannels" jsonb`,
27
+ );
28
+ await queryRunner.query(
29
+ `ALTER TABLE "ScheduledMaintenance" DROP COLUMN "postUpdatesToWorkspaceChannels"`,
30
+ );
31
+ await queryRunner.query(
32
+ `ALTER TABLE "ScheduledMaintenance" ADD "postUpdatesToWorkspaceChannels" jsonb`,
33
+ );
34
+ }
35
+
36
+ public async down(queryRunner: QueryRunner): Promise<void> {
37
+ await queryRunner.query(
38
+ `ALTER TABLE "ScheduledMaintenance" DROP COLUMN "postUpdatesToWorkspaceChannels"`,
39
+ );
40
+ await queryRunner.query(
41
+ `ALTER TABLE "ScheduledMaintenance" ADD "postUpdatesToWorkspaceChannels" character varying(100)`,
42
+ );
43
+ await queryRunner.query(
44
+ `ALTER TABLE "Alert" DROP COLUMN "postUpdatesToWorkspaceChannels"`,
45
+ );
46
+ await queryRunner.query(
47
+ `ALTER TABLE "Alert" ADD "postUpdatesToWorkspaceChannels" character varying(100)`,
48
+ );
49
+ await queryRunner.query(
50
+ `ALTER TABLE "Incident" DROP COLUMN "postUpdatesToWorkspaceChannels"`,
51
+ );
52
+ await queryRunner.query(
53
+ `ALTER TABLE "Incident" ADD "postUpdatesToWorkspaceChannels" character varying(100)`,
54
+ );
55
+ await queryRunner.query(
56
+ `ALTER TABLE "ScheduledMaintenance" RENAME COLUMN "postUpdatesToWorkspaceChannels" TO "postUpdatesToWorkspaceChannelName"`,
57
+ );
58
+ await queryRunner.query(
59
+ `ALTER TABLE "Alert" RENAME COLUMN "postUpdatesToWorkspaceChannels" TO "postUpdatesToWorkspaceChannelName"`,
60
+ );
61
+ await queryRunner.query(
62
+ `ALTER TABLE "Incident" RENAME COLUMN "postUpdatesToWorkspaceChannels" TO "postUpdatesToWorkspaceChannelName"`,
63
+ );
64
+ }
65
+ }
@@ -104,6 +104,7 @@ import { MigrationName1739210586538 } from "./1739210586538-MigrationName";
104
104
  import { MigrationName1739217257089 } from "./1739217257089-MigrationName";
105
105
  import { MigrationName1739282331053 } from "./1739282331053-MigrationName";
106
106
  import { MigrationName1739374537088 } from "./1739374537088-MigrationName";
107
+ import { MigrationName1739569321582 } from "./1739569321582-MigrationName";
107
108
 
108
109
  export default [
109
110
  InitialMigration,
@@ -212,4 +213,5 @@ export default [
212
213
  MigrationName1739217257089,
213
214
  MigrationName1739282331053,
214
215
  MigrationName1739374537088,
216
+ MigrationName1739569321582,
215
217
  ];
@@ -58,6 +58,9 @@ import {
58
58
  WorkspaceMessageBlock,
59
59
  WorkspacePayloadMarkdown,
60
60
  } from "../../Types/Workspace/WorkspaceMessagePayload";
61
+ import WorkspaceNotificationRuleService from "./WorkspaceNotificationRuleService";
62
+ import NotificationRuleEventType from "../../Types/Workspace/NotificationRules/EventType";
63
+ import { WorkspaceChannel } from "../Utils/Workspace/WorkspaceBase";
61
64
 
62
65
  export class Service extends DatabaseService<Model> {
63
66
  public constructor() {
@@ -472,6 +475,32 @@ ${createdItem.remediationNotes || "No remediation notes provided."}`,
472
475
  }
473
476
  }
474
477
 
478
+ // // send message to workspaces - slack, teams, etc.
479
+ // const createdChannels: {
480
+ // channelsCreated: Array<WorkspaceChannel>;
481
+ // } | null = await this.notifyWorkspaceOnIncidentCreate({
482
+ // projectId: createdItem.projectId,
483
+ // incidentId: createdItem.id!,
484
+ // incidentNumber: createdItem.incidentNumber!,
485
+ // });
486
+
487
+ // if (
488
+ // createdChannels &&
489
+ // createdChannels.channelsCreated &&
490
+ // createdChannels.channelsCreated.length > 0
491
+ // ) {
492
+ // // update incident with these channels.
493
+ // await this.updateOneById({
494
+ // id: createdItem.id!,
495
+ // data: {
496
+ // postUpdatesToWorkspaceChannels: createdChannels.channelsCreated,
497
+ // },
498
+ // props: {
499
+ // isRoot: true,
500
+ // },
501
+ // });
502
+ // }
503
+
475
504
  return createdItem;
476
505
  }
477
506
 
@@ -1319,6 +1348,35 @@ ${incidentSeverity.name}
1319
1348
  });
1320
1349
  }
1321
1350
 
1351
+ public async notifyWorkspaceOnIncidentCreate(data: {
1352
+ projectId: ObjectID;
1353
+ incidentId: ObjectID;
1354
+ incidentNumber: number;
1355
+ }): Promise<{
1356
+ channelsCreated: WorkspaceChannel[];
1357
+ } | null> {
1358
+ try {
1359
+ // we will notify the workspace about the incident creation with the bot tokken which is in WorkspaceProjectAuth Table.
1360
+ return await WorkspaceNotificationRuleService.createInviteAndPostToChannelsBasedOnRules(
1361
+ {
1362
+ projectId: data.projectId,
1363
+ notificationFor: {
1364
+ incidentId: data.incidentId,
1365
+ },
1366
+ notificationRuleEventType: NotificationRuleEventType.Incident,
1367
+ channelNameSiffix: data.incidentNumber.toString(),
1368
+ messageBlocks: await this.getWorkspaceMessageBlocksForIncidentCreate({
1369
+ incidentId: data.incidentId,
1370
+ }),
1371
+ },
1372
+ );
1373
+ } catch (err) {
1374
+ // log the error and continue.
1375
+ logger.error(err);
1376
+ return null;
1377
+ }
1378
+ }
1379
+
1322
1380
  public async getWorkspaceMessageBlocksForIncidentCreate(data: {
1323
1381
  incidentId: ObjectID;
1324
1382
  }): Promise<Array<WorkspaceMessageBlock>> {
@@ -67,7 +67,7 @@ import AlertSeverity from "../../Models/DatabaseModels/AlertSeverity";
67
67
  import AlertSeverityService from "./AlertSeverityService";
68
68
  import AlertState from "../../Models/DatabaseModels/AlertState";
69
69
  import AlertStateService from "./AlertStateService";
70
- import SlackUtil from "../Utils/Slack/Slack";
70
+ import SlackUtil from "../Utils/Workspace/Slack/Slack";
71
71
  import URL from "../../Types/API/URL";
72
72
  import Exception from "../../Types/Exception/Exception";
73
73
 
@@ -28,7 +28,7 @@ import Text from "../../Types/Text";
28
28
  import EmailVerificationToken from "Common/Models/DatabaseModels/EmailVerificationToken";
29
29
  import TeamMember from "Common/Models/DatabaseModels/TeamMember";
30
30
  import Model from "Common/Models/DatabaseModels/User";
31
- import SlackUtil from "../Utils/Slack/Slack";
31
+ import SlackUtil from "../Utils/Workspace/Slack/Slack";
32
32
  import UserTwoFactorAuth from "Common/Models/DatabaseModels/UserTwoFactorAuth";
33
33
  import UserTwoFactorAuthService from "./UserTwoFactorAuthService";
34
34
  import BadDataException from "../../Types/Exception/BadDataException";
@@ -20,9 +20,17 @@ import MonitorStatusTimelineService from "./MonitorStatusTimelineService";
20
20
  import { WorkspaceNotificationRuleUtil } from "../../Types/Workspace/NotificationRules/NotificationRuleUtil";
21
21
  import TeamMemberService from "./TeamMemberService";
22
22
  import User from "../../Models/DatabaseModels/User";
23
- import AlertNotificationRule from "../../Types/Workspace/NotificationRules/NotificationRuleTypes/AlertNotificationRule";
24
- import ScheduledMaintenanceNotificationRule from "../../Types/Workspace/NotificationRules/NotificationRuleTypes/ScheduledMaintenanceNotificationRule";
25
23
  import BaseNotificationRule from "../../Types/Workspace/NotificationRules/BaseNotificationRule";
24
+ import CreateChannelNotificationRule from "../../Types/Workspace/NotificationRules/CreateChannelNotificationRule";
25
+ import { WorkspaceChannel } from "../Utils/Workspace/WorkspaceBase";
26
+ import WorkspaceUtil from "../Utils/Workspace/Workspace";
27
+ import WorkspaceUserAuthToken from "../../Models/DatabaseModels/WorkspaceUserAuthToken";
28
+ import WorkspaceUserAuthTokenService from "./WorkspaceUserAuthTokenService";
29
+ import WorkspaceMessagePayload, {
30
+ WorkspaceMessageBlock,
31
+ } from "../../Types/Workspace/WorkspaceMessagePayload";
32
+ import WorkspaceProjectAuthToken from "../../Models/DatabaseModels/WorkspaceProjectAuthToken";
33
+ import WorkspaceProjectAuthTokenService from "./WorkspaceProjectAuthTokenService";
26
34
 
27
35
  export interface NotificationFor {
28
36
  incidentId?: ObjectID | undefined;
@@ -36,20 +44,235 @@ export class Service extends DatabaseService<Model> {
36
44
  super(Model);
37
45
  }
38
46
 
47
+ public async createInviteAndPostToChannelsBasedOnRules(data: {
48
+ projectId: ObjectID;
49
+ notificationRuleEventType: NotificationRuleEventType;
50
+ notificationFor: NotificationFor;
51
+ channelNameSiffix: string;
52
+ messageBlocks: Array<WorkspaceMessageBlock>;
53
+ }): Promise<{
54
+ channelsCreated: Array<WorkspaceChannel>;
55
+ } | null> {
56
+ const channelsCreated: Array<WorkspaceChannel> = [];
57
+
58
+ const projectAuths: Array<WorkspaceProjectAuthToken> =
59
+ await WorkspaceProjectAuthTokenService.getProjectAuths({
60
+ projectId: data.projectId,
61
+ });
62
+
63
+ if (!projectAuths || projectAuths.length === 0) {
64
+ // do nothing.
65
+ return null;
66
+ }
67
+
68
+ for (const projectAuth of projectAuths) {
69
+ if (!projectAuth.authToken) {
70
+ continue;
71
+ }
72
+
73
+ if (!projectAuth.workspaceType) {
74
+ continue;
75
+ }
76
+
77
+ const authToken: string = projectAuth.authToken;
78
+ const workspaceType: WorkspaceType = projectAuth.workspaceType;
79
+
80
+ const notificationRules: Array<Model> =
81
+ await this.getMatchingNotificationRules({
82
+ projectId: data.projectId,
83
+ workspaceType: workspaceType,
84
+ notificationRuleEventType: data.notificationRuleEventType,
85
+ notificationFor: data.notificationFor,
86
+ });
87
+
88
+ if (!notificationRules || notificationRules.length === 0) {
89
+ return null;
90
+ }
91
+
92
+ const createdWorkspaceChannels: Array<WorkspaceChannel> =
93
+ await this.createChannelsBasedOnRules({
94
+ projectOrUserAuthTokenForWorkspasce: authToken,
95
+ workspaceType: workspaceType,
96
+ notificationRules: notificationRules.map((rule: Model) => {
97
+ return rule.notificationRule as CreateChannelNotificationRule;
98
+ }),
99
+ channelNameSiffix: data.channelNameSiffix,
100
+ notificationEventType: data.notificationRuleEventType,
101
+ });
102
+
103
+ await this.inviteUsersAndTeamsToChannelsBasedOnRules({
104
+ projectId: data.projectId,
105
+ projectOrUserAuthTokenForWorkspasce: authToken,
106
+ workspaceType: workspaceType,
107
+ notificationRules: notificationRules.map((rule: Model) => {
108
+ return rule.notificationRule as CreateChannelNotificationRule;
109
+ }),
110
+ channelNames: createdWorkspaceChannels.map(
111
+ (channel: WorkspaceChannel) => {
112
+ return channel.name;
113
+ },
114
+ ),
115
+ });
116
+
117
+ const existingChannelNames: Array<string> =
118
+ this.getExistingChannelNamesFromNotificationRules({
119
+ notificationRules: notificationRules.map((rule: Model) => {
120
+ return rule.notificationRule as BaseNotificationRule;
121
+ }),
122
+ }) || [];
123
+
124
+ // add created channel names to existing channel names.
125
+ for (const channel of createdWorkspaceChannels) {
126
+ if (!existingChannelNames.includes(channel.name)) {
127
+ existingChannelNames.push(channel.name);
128
+ }
129
+ }
130
+
131
+ await this.postToWorkspaceChannels({
132
+ projectOrUserAuthTokenForWorkspasce: authToken,
133
+ workspaceType: workspaceType,
134
+ workspaceMessagePayload: {
135
+ _type: "WorkspaceMessagePayload",
136
+ channelNames: existingChannelNames,
137
+ messageBlocks: data.messageBlocks,
138
+ },
139
+ });
140
+
141
+ channelsCreated.push(...createdWorkspaceChannels);
142
+ }
143
+
144
+ return {
145
+ channelsCreated: channelsCreated,
146
+ };
147
+ }
148
+
149
+ public async postToWorkspaceChannels(data: {
150
+ projectOrUserAuthTokenForWorkspasce: string;
151
+ workspaceType: WorkspaceType;
152
+ workspaceMessagePayload: WorkspaceMessagePayload;
153
+ }): Promise<void> {
154
+ await WorkspaceUtil.getWorkspaceTypeUtil(data.workspaceType).sendMessage({
155
+ workspaceMessagePayload: data.workspaceMessagePayload,
156
+ authToken: data.projectOrUserAuthTokenForWorkspasce,
157
+ });
158
+ }
159
+
160
+ public async inviteUsersAndTeamsToChannelsBasedOnRules(data: {
161
+ projectId: ObjectID;
162
+ projectOrUserAuthTokenForWorkspasce: string;
163
+ workspaceType: WorkspaceType;
164
+ notificationRules: Array<CreateChannelNotificationRule>;
165
+ channelNames: Array<string>;
166
+ }): Promise<void> {
167
+ const inviteUserIds: Array<ObjectID> =
168
+ await this.getUsersIdsToInviteToChannel({
169
+ notificationRules: data.notificationRules,
170
+ });
171
+
172
+ const workspaceUserIds: Array<string> = [];
173
+
174
+ for (const userId of inviteUserIds) {
175
+ const workspaceUserId: string | null =
176
+ await this.getWorkspaceUserIdFromOneUptimeUserId({
177
+ projectId: data.projectId,
178
+ workspaceType: data.workspaceType,
179
+ oneupitmeUserId: userId,
180
+ });
181
+
182
+ if (workspaceUserId) {
183
+ workspaceUserIds.push(workspaceUserId);
184
+ }
185
+ }
186
+
187
+ await WorkspaceUtil.getWorkspaceTypeUtil(
188
+ data.workspaceType,
189
+ ).inviteUsersToChannels({
190
+ authToken: data.projectOrUserAuthTokenForWorkspasce,
191
+ workspaceChannelInvitationPayload: {
192
+ channelNames: data.channelNames,
193
+ workspaceUserIds: workspaceUserIds,
194
+ },
195
+ });
196
+ }
197
+
198
+ public async getWorkspaceUserIdFromOneUptimeUserId(data: {
199
+ projectId: ObjectID;
200
+ workspaceType: WorkspaceType;
201
+ oneupitmeUserId: ObjectID;
202
+ }): Promise<string | null> {
203
+ const userAuth: WorkspaceUserAuthToken | null =
204
+ await WorkspaceUserAuthTokenService.findOneBy({
205
+ query: {
206
+ projectId: data.projectId,
207
+ workspaceType: data.workspaceType,
208
+ userId: data.oneupitmeUserId,
209
+ },
210
+ select: {
211
+ workspaceUserId: true,
212
+ },
213
+ props: {
214
+ isRoot: true,
215
+ },
216
+ });
217
+
218
+ if (!userAuth) {
219
+ return null;
220
+ }
221
+
222
+ return userAuth.workspaceUserId?.toString() || null;
223
+ }
224
+
225
+ public async createChannelsBasedOnRules(data: {
226
+ projectOrUserAuthTokenForWorkspasce: string;
227
+ workspaceType: WorkspaceType;
228
+ notificationRules: Array<CreateChannelNotificationRule>;
229
+ channelNameSiffix: string;
230
+ notificationEventType: NotificationRuleEventType;
231
+ }): Promise<Array<WorkspaceChannel>> {
232
+ const createdWorkspaceChannels: Array<WorkspaceChannel> = [];
233
+ const createdChannelNames: Array<string> = [];
234
+
235
+ const newChannelNames: Array<string> =
236
+ this.getNewChannelNamesFromNotificationRules({
237
+ notificationRules: data.notificationRules,
238
+ channelNameSiffix: data.channelNameSiffix,
239
+ notificationEventType: data.notificationEventType,
240
+ });
241
+
242
+ if (!newChannelNames || newChannelNames.length === 0) {
243
+ return [];
244
+ }
245
+
246
+ for (const newChannelName of newChannelNames) {
247
+ // if already created then skip it.
248
+ if (createdChannelNames.includes(newChannelName)) {
249
+ continue;
250
+ }
251
+
252
+ // create channel.
253
+ const channel: WorkspaceChannel =
254
+ await WorkspaceUtil.getWorkspaceTypeUtil(
255
+ data.workspaceType,
256
+ ).createChannel({
257
+ authToken: data.projectOrUserAuthTokenForWorkspasce,
258
+ channelName: newChannelName,
259
+ });
260
+
261
+ createdChannelNames.push(channel.name);
262
+
263
+ createdWorkspaceChannels.push(channel);
264
+ }
265
+
266
+ return createdWorkspaceChannels;
267
+ }
268
+
39
269
  public async getUsersIdsToInviteToChannel(data: {
40
- notificationRules: Array<
41
- | IncidentNotificationRule
42
- | AlertNotificationRule
43
- | ScheduledMaintenanceNotificationRule
44
- >;
270
+ notificationRules: Array<CreateChannelNotificationRule>;
45
271
  }): Promise<Array<ObjectID>> {
46
272
  const inviteUserIds: Array<ObjectID> = [];
47
273
 
48
274
  for (const notificationRule of data.notificationRules) {
49
- const workspaceRules:
50
- | IncidentNotificationRule
51
- | AlertNotificationRule
52
- | ScheduledMaintenanceNotificationRule = notificationRule;
275
+ const workspaceRules: CreateChannelNotificationRule = notificationRule;
53
276
 
54
277
  if (workspaceRules.shouldCreateNewChannel) {
55
278
  if (
@@ -103,7 +326,7 @@ export class Service extends DatabaseService<Model> {
103
326
  return inviteUserIds;
104
327
  }
105
328
 
106
- public getChannelNamesFromNotificaitonRules(data: {
329
+ public getExistingChannelNamesFromNotificationRules(data: {
107
330
  notificationRules: Array<BaseNotificationRule>;
108
331
  }): Array<string> {
109
332
  const channelNames: Array<string> = [];
@@ -132,6 +355,37 @@ export class Service extends DatabaseService<Model> {
132
355
  return channelNames;
133
356
  }
134
357
 
358
+ public getNewChannelNamesFromNotificationRules(data: {
359
+ notificationEventType: NotificationRuleEventType;
360
+ notificationRules: Array<CreateChannelNotificationRule>;
361
+ channelNameSiffix: string;
362
+ }): Array<string> {
363
+ const channelNames: Array<string> = [];
364
+
365
+ for (const notificationRule of data.notificationRules) {
366
+ const workspaceRules: CreateChannelNotificationRule = notificationRule;
367
+
368
+ if (
369
+ workspaceRules.shouldCreateNewChannel &&
370
+ workspaceRules.newChannelTemplateName
371
+ ) {
372
+ const newChannelName: string =
373
+ workspaceRules.newChannelTemplateName ||
374
+ `oneuptime-${data.notificationEventType.toLowerCase()}-`;
375
+
376
+ // add suffix and then check if it is already added or not.
377
+ const channelName: string = newChannelName + data.channelNameSiffix;
378
+
379
+ if (!channelNames.includes(channelName)) {
380
+ // if channel name is not already added then add it.
381
+ channelNames.push(channelName);
382
+ }
383
+ }
384
+ }
385
+
386
+ return channelNames;
387
+ }
388
+
135
389
  private async getNotificationRules(data: {
136
390
  projectId: ObjectID;
137
391
  workspaceType: WorkspaceType;
@@ -8,7 +8,7 @@ import { JSONObject } from "Common/Types/JSON";
8
8
  import ComponentMetadata, { Port } from "Common/Types/Workflow/Component";
9
9
  import ComponentID from "Common/Types/Workflow/ComponentID";
10
10
  import SlackComponents from "Common/Types/Workflow/Components/Slack";
11
- import SlackUtil from "../../../../Utils/Slack/Slack";
11
+ import SlackUtil from "../../../../Utils/Workspace/Slack/Slack";
12
12
 
13
13
  export default class SendMessageToChannel extends ComponentCode {
14
14
  public constructor() {
@@ -0,0 +1,3 @@
1
+ import WorkspaceBase from "../WorkspaceBase";
2
+
3
+ export default class MicrosoftTeams extends WorkspaceBase {}