@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.
- package/Models/DatabaseModels/Alert.ts +4 -4
- package/Models/DatabaseModels/Incident.ts +4 -4
- package/Models/DatabaseModels/ScheduledMaintenance.ts +4 -4
- package/Server/API/SlackAPI.ts +1 -1
- package/Server/EnvironmentConfig.ts +4 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/1739569321582-MigrationName.ts +65 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/Index.ts +2 -0
- package/Server/Services/IncidentService.ts +58 -0
- package/Server/Services/ProjectService.ts +1 -1
- package/Server/Services/UserService.ts +1 -1
- package/Server/Services/WorkspaceNotificationRuleService.ts +266 -12
- package/Server/Types/Workflow/Components/Slack/SendMessageToChannel.ts +1 -1
- package/Server/Utils/Workspace/MicrosoftTeams/MicrosoftTeams.ts +3 -0
- package/Server/Utils/{Slack → Workspace/Slack}/Slack.ts +93 -172
- package/Server/Utils/Workspace/Workspace.ts +23 -0
- package/Server/Utils/Workspace/WorkspaceBase.ts +169 -0
- package/Types/Workspace/NotificationRules/CreateChannelNotificationRule.ts +14 -0
- package/Types/Workspace/NotificationRules/NotificationRuleCondition.ts +23 -11
- package/Types/Workspace/NotificationRules/NotificationRuleTypes/AlertNotificationRule.ts +3 -10
- package/Types/Workspace/NotificationRules/NotificationRuleTypes/IncidentNotificationRule.ts +3 -10
- package/Types/Workspace/NotificationRules/NotificationRuleTypes/ScheduledMaintenanceNotificationRule.ts +2 -10
- package/Types/Workspace/WorkspaceChannelInvitationPayload.ts +1 -1
- package/build/dist/Models/DatabaseModels/Alert.js +5 -6
- package/build/dist/Models/DatabaseModels/Alert.js.map +1 -1
- package/build/dist/Models/DatabaseModels/Incident.js +5 -6
- package/build/dist/Models/DatabaseModels/Incident.js.map +1 -1
- package/build/dist/Models/DatabaseModels/ScheduledMaintenance.js +5 -6
- package/build/dist/Models/DatabaseModels/ScheduledMaintenance.js.map +1 -1
- package/build/dist/Server/API/SlackAPI.js +1 -1
- package/build/dist/Server/API/SlackAPI.js.map +1 -1
- package/build/dist/Server/EnvironmentConfig.js +3 -0
- package/build/dist/Server/EnvironmentConfig.js.map +1 -1
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1739569321582-MigrationName.js +28 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1739569321582-MigrationName.js.map +1 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/Index.js +2 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/Index.js.map +1 -1
- package/build/dist/Server/Services/IncidentService.js +47 -0
- package/build/dist/Server/Services/IncidentService.js.map +1 -1
- package/build/dist/Server/Services/ProjectService.js +1 -1
- package/build/dist/Server/Services/ProjectService.js.map +1 -1
- package/build/dist/Server/Services/UserService.js +1 -1
- package/build/dist/Server/Services/UserService.js.map +1 -1
- package/build/dist/Server/Services/WorkspaceNotificationRuleService.js +170 -1
- package/build/dist/Server/Services/WorkspaceNotificationRuleService.js.map +1 -1
- package/build/dist/Server/Types/Workflow/Components/Slack/SendMessageToChannel.js +1 -1
- package/build/dist/Server/Types/Workflow/Components/Slack/SendMessageToChannel.js.map +1 -1
- package/build/dist/Server/Utils/Workspace/MicrosoftTeams/MicrosoftTeams.js +4 -0
- package/build/dist/Server/Utils/Workspace/MicrosoftTeams/MicrosoftTeams.js.map +1 -0
- package/build/dist/Server/Utils/{Slack → Workspace/Slack}/Slack.js +53 -101
- package/build/dist/Server/Utils/Workspace/Slack/Slack.js.map +1 -0
- package/build/dist/Server/Utils/Workspace/Workspace.js +16 -0
- package/build/dist/Server/Utils/Workspace/Workspace.js.map +1 -0
- package/build/dist/Server/Utils/Workspace/WorkspaceBase.js +90 -0
- package/build/dist/Server/Utils/Workspace/WorkspaceBase.js.map +1 -0
- package/build/dist/Types/Workspace/NotificationRules/CreateChannelNotificationRule.js +2 -0
- package/build/dist/Types/Workspace/NotificationRules/CreateChannelNotificationRule.js.map +1 -0
- package/build/dist/Types/Workspace/NotificationRules/NotificationRuleCondition.js +17 -11
- package/build/dist/Types/Workspace/NotificationRules/NotificationRuleCondition.js.map +1 -1
- package/package.json +2 -2
- package/build/dist/Server/Utils/Slack/Slack.js.map +0 -1
- /package/Server/Utils/{Slack → Workspace/Slack}/app-manifest-temp.json +0 -0
- /package/Server/Utils/{Slack → Workspace/Slack}/app-manifest.json +0 -0
- /package/build/dist/Server/Utils/{Slack → Workspace/Slack}/app-manifest.json +0 -0
|
@@ -5,76 +5,34 @@ import { JSONObject } from "Common/Types/JSON";
|
|
|
5
5
|
import API from "Common/Utils/API";
|
|
6
6
|
import WorkspaceMessagePayload, {
|
|
7
7
|
WorkspaceMessagePayloadButton,
|
|
8
|
-
WorkspacePayloadButtons,
|
|
9
8
|
WorkspacePayloadHeader,
|
|
10
9
|
WorkspacePayloadMarkdown,
|
|
11
|
-
} from "
|
|
12
|
-
import logger from "
|
|
13
|
-
import Dictionary from "
|
|
14
|
-
import BadRequestException from "
|
|
15
|
-
import
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
export interface SlackChannel {
|
|
23
|
-
id: string;
|
|
24
|
-
name: string;
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
export default class SlackUtil {
|
|
28
|
-
public static async inviteUsersToChannels(data: {
|
|
29
|
-
authToken: string;
|
|
30
|
-
workspaceChannelInvitationPayload: WorkspaceChannelInvitationPayload;
|
|
31
|
-
}): Promise<void> {
|
|
32
|
-
const channelIds: Array<string> = [];
|
|
33
|
-
|
|
34
|
-
for (const channelName of data.workspaceChannelInvitationPayload
|
|
35
|
-
.workspaceChannelNames) {
|
|
36
|
-
const channel: SlackChannel = await this.createChannel({
|
|
37
|
-
authToken: data.authToken,
|
|
38
|
-
channelName: channelName,
|
|
39
|
-
});
|
|
40
|
-
|
|
41
|
-
channelIds.push(channel.id);
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
for (const channelId of channelIds) {
|
|
45
|
-
await this.inviteUsersToChannel({
|
|
46
|
-
authToken: data.authToken,
|
|
47
|
-
channelId: channelId,
|
|
48
|
-
userIds: data.workspaceChannelInvitationPayload.workspaceUserIds,
|
|
49
|
-
});
|
|
50
|
-
}
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
private static async inviteUsersToChannel(data: {
|
|
10
|
+
} from "../../../../Types/Workspace/WorkspaceMessagePayload";
|
|
11
|
+
import logger from "../../Logger";
|
|
12
|
+
import Dictionary from "../../../../Types/Dictionary";
|
|
13
|
+
import BadRequestException from "../../../../Types/Exception/BadRequestException";
|
|
14
|
+
import WorkspaceBase, { WorkspaceChannel } from "../WorkspaceBase";
|
|
15
|
+
import WorkspaceType from "../../../../Types/Workspace/WorkspaceType";
|
|
16
|
+
|
|
17
|
+
export default class SlackUtil extends WorkspaceBase {
|
|
18
|
+
public static override async inviteUserToChannel(data: {
|
|
54
19
|
authToken: string;
|
|
55
|
-
|
|
56
|
-
|
|
20
|
+
channelName: string;
|
|
21
|
+
workspaceUserId: string;
|
|
57
22
|
}): Promise<void> {
|
|
58
|
-
|
|
59
|
-
await this.
|
|
23
|
+
const channelId: string = (
|
|
24
|
+
await this.getWorkspaceChannelFromChannelId({
|
|
60
25
|
authToken: data.authToken,
|
|
61
|
-
channelId: data.
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
}
|
|
65
|
-
}
|
|
26
|
+
channelId: data.channelName,
|
|
27
|
+
})
|
|
28
|
+
).id;
|
|
66
29
|
|
|
67
|
-
private static async inviteUserToChannel(data: {
|
|
68
|
-
authToken: string;
|
|
69
|
-
channelId: string;
|
|
70
|
-
userId: string;
|
|
71
|
-
}): Promise<void> {
|
|
72
30
|
const response: HTTPErrorResponse | HTTPResponse<JSONObject> =
|
|
73
31
|
await API.post(
|
|
74
32
|
URL.fromString("https://slack.com/api/conversations.invite"),
|
|
75
33
|
{
|
|
76
|
-
channel:
|
|
77
|
-
users: data.
|
|
34
|
+
channel: channelId,
|
|
35
|
+
users: data.workspaceUserId,
|
|
78
36
|
},
|
|
79
37
|
{
|
|
80
38
|
Authorization: `Bearer ${data.authToken}`,
|
|
@@ -90,43 +48,43 @@ export default class SlackUtil {
|
|
|
90
48
|
}
|
|
91
49
|
}
|
|
92
50
|
|
|
93
|
-
public static async
|
|
51
|
+
public static override async createChannelsIfDoesNotExist(data: {
|
|
94
52
|
authToken: string;
|
|
95
|
-
|
|
96
|
-
}): Promise<Array<
|
|
53
|
+
channelNames: Array<string>;
|
|
54
|
+
}): Promise<Array<WorkspaceChannel>> {
|
|
97
55
|
// check existing channels and only create if they dont exist.
|
|
98
|
-
const
|
|
99
|
-
const
|
|
100
|
-
await this.
|
|
56
|
+
const workspaceChannels: Array<WorkspaceChannel> = [];
|
|
57
|
+
const existingWorkspaceChannels: Dictionary<WorkspaceChannel> =
|
|
58
|
+
await this.getAllWorkspaceChannels({
|
|
101
59
|
authToken: data.authToken,
|
|
102
60
|
});
|
|
103
61
|
|
|
104
|
-
for (const channelName of data.
|
|
105
|
-
if (
|
|
62
|
+
for (const channelName of data.channelNames) {
|
|
63
|
+
if (existingWorkspaceChannels[channelName]) {
|
|
106
64
|
logger.debug(`Channel ${channelName} already exists.`);
|
|
107
65
|
|
|
108
|
-
|
|
66
|
+
workspaceChannels.push(existingWorkspaceChannels[channelName]!);
|
|
109
67
|
|
|
110
68
|
continue;
|
|
111
69
|
}
|
|
112
70
|
|
|
113
|
-
const channel:
|
|
71
|
+
const channel: WorkspaceChannel = await this.createChannel({
|
|
114
72
|
authToken: data.authToken,
|
|
115
73
|
channelName: channelName,
|
|
116
74
|
});
|
|
117
75
|
|
|
118
76
|
if (channel) {
|
|
119
|
-
|
|
77
|
+
workspaceChannels.push(channel);
|
|
120
78
|
}
|
|
121
79
|
}
|
|
122
80
|
|
|
123
|
-
return
|
|
81
|
+
return workspaceChannels;
|
|
124
82
|
}
|
|
125
83
|
|
|
126
|
-
public static async
|
|
84
|
+
public static override async getWorkspaceChannelFromChannelId(data: {
|
|
127
85
|
authToken: string;
|
|
128
86
|
channelId: string;
|
|
129
|
-
}): Promise<
|
|
87
|
+
}): Promise<WorkspaceChannel> {
|
|
130
88
|
const response: HTTPErrorResponse | HTTPResponse<JSONObject> =
|
|
131
89
|
await API.get<JSONObject>(
|
|
132
90
|
URL.fromString("https://slack.com/api/conversations.info"),
|
|
@@ -150,36 +108,75 @@ export default class SlackUtil {
|
|
|
150
108
|
throw new Error("Invalid response");
|
|
151
109
|
}
|
|
152
110
|
|
|
153
|
-
return
|
|
154
|
-
|
|
155
|
-
|
|
111
|
+
return {
|
|
112
|
+
name: ((response.jsonData as JSONObject)["channel"] as JSONObject)[
|
|
113
|
+
"name"
|
|
114
|
+
] as string,
|
|
115
|
+
id: data.channelId,
|
|
116
|
+
workspaceType: WorkspaceType.Slack,
|
|
117
|
+
};
|
|
156
118
|
}
|
|
157
119
|
|
|
158
|
-
public static async
|
|
120
|
+
public static override async getAllWorkspaceChannels(data: {
|
|
121
|
+
authToken: string;
|
|
122
|
+
}): Promise<Dictionary<WorkspaceChannel>> {
|
|
123
|
+
const response: HTTPErrorResponse | HTTPResponse<JSONObject> =
|
|
124
|
+
await API.get<JSONObject>(
|
|
125
|
+
URL.fromString("https://slack.com/api/conversations.list"),
|
|
126
|
+
{
|
|
127
|
+
headers: {
|
|
128
|
+
Authorization: `Bearer ${data.authToken}`,
|
|
129
|
+
},
|
|
130
|
+
},
|
|
131
|
+
);
|
|
132
|
+
|
|
133
|
+
if (response instanceof HTTPErrorResponse) {
|
|
134
|
+
throw response;
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
const channels: Dictionary<WorkspaceChannel> = {};
|
|
138
|
+
|
|
139
|
+
for (const channel of (response.jsonData as JSONObject)[
|
|
140
|
+
"channels"
|
|
141
|
+
] as Array<JSONObject>) {
|
|
142
|
+
if (!channel["id"] || !channel["name"]) {
|
|
143
|
+
continue;
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
channels[channel["name"].toString()] = {
|
|
147
|
+
id: channel["id"] as string,
|
|
148
|
+
name: channel["name"] as string,
|
|
149
|
+
workspaceType: WorkspaceType.Slack,
|
|
150
|
+
};
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
return channels;
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
public static override async sendMessage(data: {
|
|
159
157
|
workspaceMessagePayload: WorkspaceMessagePayload;
|
|
160
158
|
authToken: string; // which auth token should we use to send.
|
|
161
159
|
}): Promise<void> {
|
|
162
160
|
logger.debug("Notify Slack");
|
|
163
161
|
logger.debug(data);
|
|
164
162
|
|
|
165
|
-
const blocks: Array<JSONObject> =
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
);
|
|
163
|
+
const blocks: Array<JSONObject> = this.getBlocksFromWorkspaceMessagePayload(
|
|
164
|
+
data.workspaceMessagePayload,
|
|
165
|
+
);
|
|
169
166
|
|
|
170
|
-
const
|
|
171
|
-
await this.
|
|
167
|
+
const existingWorkspaceChannels: Dictionary<WorkspaceChannel> =
|
|
168
|
+
await this.getAllWorkspaceChannels({
|
|
172
169
|
authToken: data.authToken,
|
|
173
170
|
});
|
|
174
171
|
|
|
175
172
|
const channelIdsToPostTo: Array<string> = [];
|
|
176
173
|
|
|
177
174
|
for (const channelName of data.workspaceMessagePayload.channelNames) {
|
|
178
|
-
// get channel ids from
|
|
179
|
-
let channel:
|
|
175
|
+
// get channel ids from existingWorkspaceChannels. IF channel doesn't exist, create it if createChannelsIfItDoesNotExist is true.
|
|
176
|
+
let channel: WorkspaceChannel | null = null;
|
|
180
177
|
|
|
181
|
-
if (
|
|
182
|
-
channel =
|
|
178
|
+
if (existingWorkspaceChannels[channelName]) {
|
|
179
|
+
channel = existingWorkspaceChannels[channelName]!;
|
|
183
180
|
}
|
|
184
181
|
|
|
185
182
|
if (channel) {
|
|
@@ -203,7 +200,7 @@ export default class SlackUtil {
|
|
|
203
200
|
}
|
|
204
201
|
}
|
|
205
202
|
|
|
206
|
-
public static async sendPayloadBlocksToChannel(data: {
|
|
203
|
+
public static override async sendPayloadBlocksToChannel(data: {
|
|
207
204
|
authToken: string;
|
|
208
205
|
channelId: string;
|
|
209
206
|
blocks: Array<JSONObject>;
|
|
@@ -229,10 +226,10 @@ export default class SlackUtil {
|
|
|
229
226
|
}
|
|
230
227
|
}
|
|
231
228
|
|
|
232
|
-
public static async createChannel(data: {
|
|
229
|
+
public static override async createChannel(data: {
|
|
233
230
|
authToken: string;
|
|
234
231
|
channelName: string;
|
|
235
|
-
}): Promise<
|
|
232
|
+
}): Promise<WorkspaceChannel> {
|
|
236
233
|
const response: HTTPResponse<JSONObject> | HTTPErrorResponse =
|
|
237
234
|
await API.post(
|
|
238
235
|
URL.fromString("https://slack.com/api/conversations.create"),
|
|
@@ -262,10 +259,11 @@ export default class SlackUtil {
|
|
|
262
259
|
name: ((response.jsonData as JSONObject)["channel"] as JSONObject)[
|
|
263
260
|
"name"
|
|
264
261
|
] as string,
|
|
262
|
+
workspaceType: WorkspaceType.Slack,
|
|
265
263
|
};
|
|
266
264
|
}
|
|
267
265
|
|
|
268
|
-
public static getHeaderBlock(data: {
|
|
266
|
+
public static override getHeaderBlock(data: {
|
|
269
267
|
payloadHeaderBlock: WorkspacePayloadHeader;
|
|
270
268
|
}): JSONObject {
|
|
271
269
|
return {
|
|
@@ -277,7 +275,7 @@ export default class SlackUtil {
|
|
|
277
275
|
};
|
|
278
276
|
}
|
|
279
277
|
|
|
280
|
-
public static getMarkdownBlock(data: {
|
|
278
|
+
public static override getMarkdownBlock(data: {
|
|
281
279
|
payloadMarkdownBlock: WorkspacePayloadMarkdown;
|
|
282
280
|
}): JSONObject {
|
|
283
281
|
return {
|
|
@@ -289,42 +287,7 @@ export default class SlackUtil {
|
|
|
289
287
|
};
|
|
290
288
|
}
|
|
291
289
|
|
|
292
|
-
public static
|
|
293
|
-
authToken: string;
|
|
294
|
-
}): Promise<Dictionary<SlackChannel>> {
|
|
295
|
-
const response: HTTPErrorResponse | HTTPResponse<JSONObject> =
|
|
296
|
-
await API.get<JSONObject>(
|
|
297
|
-
URL.fromString("https://slack.com/api/conversations.list"),
|
|
298
|
-
{
|
|
299
|
-
headers: {
|
|
300
|
-
Authorization: `Bearer ${data.authToken}`,
|
|
301
|
-
},
|
|
302
|
-
},
|
|
303
|
-
);
|
|
304
|
-
|
|
305
|
-
if (response instanceof HTTPErrorResponse) {
|
|
306
|
-
throw response;
|
|
307
|
-
}
|
|
308
|
-
|
|
309
|
-
const channels: Dictionary<SlackChannel> = {};
|
|
310
|
-
|
|
311
|
-
for (const channel of (response.jsonData as JSONObject)[
|
|
312
|
-
"channels"
|
|
313
|
-
] as Array<JSONObject>) {
|
|
314
|
-
if (!channel["id"] || !channel["name"]) {
|
|
315
|
-
continue;
|
|
316
|
-
}
|
|
317
|
-
|
|
318
|
-
channels[channel["name"].toString()] = {
|
|
319
|
-
id: channel["id"] as string,
|
|
320
|
-
name: channel["name"] as string,
|
|
321
|
-
};
|
|
322
|
-
}
|
|
323
|
-
|
|
324
|
-
return channels;
|
|
325
|
-
}
|
|
326
|
-
|
|
327
|
-
public static getButtonBlock(data: {
|
|
290
|
+
public static override getButtonBlock(data: {
|
|
328
291
|
payloadButtonBlock: WorkspaceMessagePayloadButton;
|
|
329
292
|
}): JSONObject {
|
|
330
293
|
return {
|
|
@@ -338,7 +301,7 @@ export default class SlackUtil {
|
|
|
338
301
|
};
|
|
339
302
|
}
|
|
340
303
|
|
|
341
|
-
public static async sendMessageToChannelViaIncomingWebhook(data: {
|
|
304
|
+
public static override async sendMessageToChannelViaIncomingWebhook(data: {
|
|
342
305
|
url: URL;
|
|
343
306
|
text: string;
|
|
344
307
|
}): Promise<HTTPResponse<JSONObject> | HTTPErrorResponse> {
|
|
@@ -359,46 +322,4 @@ export default class SlackUtil {
|
|
|
359
322
|
|
|
360
323
|
return apiResult;
|
|
361
324
|
}
|
|
362
|
-
|
|
363
|
-
private static getSlackBlocksFromWorkspaceMessagePayload(
|
|
364
|
-
data: WorkspaceMessagePayload,
|
|
365
|
-
): Array<JSONObject> {
|
|
366
|
-
const blocks: Array<JSONObject> = [];
|
|
367
|
-
const buttons: Array<JSONObject> = [];
|
|
368
|
-
for (const block of data.messageBlocks) {
|
|
369
|
-
switch (block._type) {
|
|
370
|
-
case "WorkspacePayloadHeader":
|
|
371
|
-
blocks.push(
|
|
372
|
-
this.getHeaderBlock({
|
|
373
|
-
payloadHeaderBlock: block as WorkspacePayloadHeader,
|
|
374
|
-
}),
|
|
375
|
-
);
|
|
376
|
-
break;
|
|
377
|
-
case "WorkspacePayloadMarkdown":
|
|
378
|
-
blocks.push(
|
|
379
|
-
this.getMarkdownBlock({
|
|
380
|
-
payloadMarkdownBlock: block as WorkspacePayloadMarkdown,
|
|
381
|
-
}),
|
|
382
|
-
);
|
|
383
|
-
break;
|
|
384
|
-
case "WorkspacePayloadButtons":
|
|
385
|
-
for (const button of (block as WorkspacePayloadButtons).buttons) {
|
|
386
|
-
buttons.push(
|
|
387
|
-
this.getButtonBlock({
|
|
388
|
-
payloadButtonBlock: button,
|
|
389
|
-
}),
|
|
390
|
-
);
|
|
391
|
-
}
|
|
392
|
-
blocks.push({
|
|
393
|
-
type: "actions",
|
|
394
|
-
elements: buttons,
|
|
395
|
-
});
|
|
396
|
-
break;
|
|
397
|
-
default:
|
|
398
|
-
logger.error("Unknown block type: " + block._type);
|
|
399
|
-
break;
|
|
400
|
-
}
|
|
401
|
-
}
|
|
402
|
-
return blocks;
|
|
403
|
-
}
|
|
404
325
|
}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import WorkspaceType from "../../../Types/Workspace/WorkspaceType";
|
|
2
|
+
import WorkspaceBase from "./WorkspaceBase";
|
|
3
|
+
import SlackWorkspace from "./Slack/Slack";
|
|
4
|
+
import MicrosoftTeamsWorkspace from "./MicrosoftTeams/MicrosoftTeams";
|
|
5
|
+
import BadDataException from "../../../Types/Exception/BadDataException";
|
|
6
|
+
|
|
7
|
+
export default class WorkspaceUtil {
|
|
8
|
+
public static getWorkspaceTypeUtil(
|
|
9
|
+
workspaceType: WorkspaceType,
|
|
10
|
+
): typeof WorkspaceBase {
|
|
11
|
+
if (workspaceType === WorkspaceType.Slack) {
|
|
12
|
+
return SlackWorkspace;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
if (workspaceType === WorkspaceType.MicrosoftTeams) {
|
|
16
|
+
return MicrosoftTeamsWorkspace;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
throw new BadDataException(
|
|
20
|
+
`Workspace type ${workspaceType} is not supported`,
|
|
21
|
+
);
|
|
22
|
+
}
|
|
23
|
+
}
|
|
@@ -0,0 +1,169 @@
|
|
|
1
|
+
import HTTPErrorResponse from "../../../Types/API/HTTPErrorResponse";
|
|
2
|
+
import HTTPResponse from "../../../Types/API/HTTPResponse";
|
|
3
|
+
import Dictionary from "../../../Types/Dictionary";
|
|
4
|
+
import NotImplementedException from "../../../Types/Exception/NotImplementedException";
|
|
5
|
+
import { JSONObject } from "../../../Types/JSON";
|
|
6
|
+
import WorkspaceChannelInvitationPayload from "../../../Types/Workspace/WorkspaceChannelInvitationPayload";
|
|
7
|
+
import WorkspaceMessagePayload, {
|
|
8
|
+
WorkspaceMessagePayloadButton,
|
|
9
|
+
WorkspacePayloadButtons,
|
|
10
|
+
WorkspacePayloadHeader,
|
|
11
|
+
WorkspacePayloadMarkdown,
|
|
12
|
+
} from "../../../Types/Workspace/WorkspaceMessagePayload";
|
|
13
|
+
import WorkspaceType from "../../../Types/Workspace/WorkspaceType";
|
|
14
|
+
import logger from "../Logger";
|
|
15
|
+
import URL from "Common/Types/API/URL";
|
|
16
|
+
|
|
17
|
+
export interface WorkspaceChannel {
|
|
18
|
+
id: string;
|
|
19
|
+
name: string;
|
|
20
|
+
workspaceType: WorkspaceType;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
export default class WorkspaceBase {
|
|
24
|
+
public static async sendPayloadBlocksToChannel(_data: {
|
|
25
|
+
authToken: string;
|
|
26
|
+
channelId: string;
|
|
27
|
+
blocks: Array<JSONObject>;
|
|
28
|
+
}): Promise<void> {
|
|
29
|
+
throw new NotImplementedException();
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
public static async inviteUsersToChannels(data: {
|
|
33
|
+
authToken: string;
|
|
34
|
+
workspaceChannelInvitationPayload: WorkspaceChannelInvitationPayload;
|
|
35
|
+
}): Promise<void> {
|
|
36
|
+
for (const channelName of data.workspaceChannelInvitationPayload
|
|
37
|
+
.channelNames) {
|
|
38
|
+
await this.inviteUsersToChannel({
|
|
39
|
+
authToken: data.authToken,
|
|
40
|
+
channelName: channelName,
|
|
41
|
+
workspaceUserIds:
|
|
42
|
+
data.workspaceChannelInvitationPayload.workspaceUserIds,
|
|
43
|
+
});
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
public static async inviteUsersToChannel(data: {
|
|
48
|
+
authToken: string;
|
|
49
|
+
channelName: string;
|
|
50
|
+
workspaceUserIds: Array<string>;
|
|
51
|
+
}): Promise<void> {
|
|
52
|
+
for (const userId of data.workspaceUserIds) {
|
|
53
|
+
await this.inviteUserToChannel({
|
|
54
|
+
authToken: data.authToken,
|
|
55
|
+
channelName: data.channelName,
|
|
56
|
+
workspaceUserId: userId,
|
|
57
|
+
});
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
public static async inviteUserToChannel(_data: {
|
|
62
|
+
authToken: string;
|
|
63
|
+
channelName: string;
|
|
64
|
+
workspaceUserId: string;
|
|
65
|
+
}): Promise<void> {
|
|
66
|
+
throw new NotImplementedException();
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
public static async createChannelsIfDoesNotExist(_data: {
|
|
70
|
+
authToken: string;
|
|
71
|
+
channelNames: Array<string>;
|
|
72
|
+
}): Promise<Array<WorkspaceChannel>> {
|
|
73
|
+
throw new NotImplementedException();
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
public static async getWorkspaceChannelFromChannelId(_data: {
|
|
77
|
+
authToken: string;
|
|
78
|
+
channelId: string;
|
|
79
|
+
}): Promise<WorkspaceChannel> {
|
|
80
|
+
throw new NotImplementedException();
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
public static async sendMessage(_data: {
|
|
84
|
+
workspaceMessagePayload: WorkspaceMessagePayload;
|
|
85
|
+
authToken: string; // which auth token should we use to send.
|
|
86
|
+
}): Promise<void> {
|
|
87
|
+
throw new NotImplementedException();
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
public static async getAllWorkspaceChannels(_data: {
|
|
91
|
+
authToken: string;
|
|
92
|
+
}): Promise<Dictionary<WorkspaceChannel>> {
|
|
93
|
+
throw new NotImplementedException();
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
public static async createChannel(_data: {
|
|
97
|
+
authToken: string;
|
|
98
|
+
channelName: string;
|
|
99
|
+
}): Promise<WorkspaceChannel> {
|
|
100
|
+
throw new NotImplementedException();
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
public static getHeaderBlock(_data: {
|
|
104
|
+
payloadHeaderBlock: WorkspacePayloadHeader;
|
|
105
|
+
}): JSONObject {
|
|
106
|
+
throw new NotImplementedException();
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
public static getMarkdownBlock(_data: {
|
|
110
|
+
payloadMarkdownBlock: WorkspacePayloadMarkdown;
|
|
111
|
+
}): JSONObject {
|
|
112
|
+
throw new NotImplementedException();
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
public static getButtonBlock(_data: {
|
|
116
|
+
payloadButtonBlock: WorkspaceMessagePayloadButton;
|
|
117
|
+
}): JSONObject {
|
|
118
|
+
throw new NotImplementedException();
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
public static getBlocksFromWorkspaceMessagePayload(
|
|
122
|
+
data: WorkspaceMessagePayload,
|
|
123
|
+
): Array<JSONObject> {
|
|
124
|
+
const blocks: Array<JSONObject> = [];
|
|
125
|
+
const buttons: Array<JSONObject> = [];
|
|
126
|
+
for (const block of data.messageBlocks) {
|
|
127
|
+
switch (block._type) {
|
|
128
|
+
case "WorkspacePayloadHeader":
|
|
129
|
+
blocks.push(
|
|
130
|
+
this.getHeaderBlock({
|
|
131
|
+
payloadHeaderBlock: block as WorkspacePayloadHeader,
|
|
132
|
+
}),
|
|
133
|
+
);
|
|
134
|
+
break;
|
|
135
|
+
case "WorkspacePayloadMarkdown":
|
|
136
|
+
blocks.push(
|
|
137
|
+
this.getMarkdownBlock({
|
|
138
|
+
payloadMarkdownBlock: block as WorkspacePayloadMarkdown,
|
|
139
|
+
}),
|
|
140
|
+
);
|
|
141
|
+
break;
|
|
142
|
+
case "WorkspacePayloadButtons":
|
|
143
|
+
for (const button of (block as WorkspacePayloadButtons).buttons) {
|
|
144
|
+
buttons.push(
|
|
145
|
+
this.getButtonBlock({
|
|
146
|
+
payloadButtonBlock: button,
|
|
147
|
+
}),
|
|
148
|
+
);
|
|
149
|
+
}
|
|
150
|
+
blocks.push({
|
|
151
|
+
type: "actions",
|
|
152
|
+
elements: buttons,
|
|
153
|
+
});
|
|
154
|
+
break;
|
|
155
|
+
default:
|
|
156
|
+
logger.error("Unknown block type: " + block._type);
|
|
157
|
+
break;
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
return blocks;
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
public static async sendMessageToChannelViaIncomingWebhook(_data: {
|
|
164
|
+
url: URL;
|
|
165
|
+
text: string;
|
|
166
|
+
}): Promise<HTTPResponse<JSONObject> | HTTPErrorResponse> {
|
|
167
|
+
throw new NotImplementedException();
|
|
168
|
+
}
|
|
169
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import ObjectID from "../../ObjectID";
|
|
2
|
+
import BaseNotificationRule from "./BaseNotificationRule";
|
|
3
|
+
|
|
4
|
+
export default interface CreateChannelNotificationRule
|
|
5
|
+
extends BaseNotificationRule {
|
|
6
|
+
_type: string;
|
|
7
|
+
|
|
8
|
+
// if filters match then do:
|
|
9
|
+
shouldCreateNewChannel: boolean;
|
|
10
|
+
inviteTeamsToNewChannel: Array<ObjectID>;
|
|
11
|
+
inviteUsersToNewChannel: Array<ObjectID>;
|
|
12
|
+
shouldInviteOwnersToNewChannel: boolean;
|
|
13
|
+
newChannelTemplateName: string;
|
|
14
|
+
}
|
|
@@ -83,21 +83,33 @@ export class NotificationRuleConditionUtil {
|
|
|
83
83
|
}
|
|
84
84
|
}
|
|
85
85
|
|
|
86
|
-
if (
|
|
86
|
+
if (
|
|
87
|
+
eventType === NotificationRuleEventType.Incident ||
|
|
88
|
+
eventType === NotificationRuleEventType.Alert ||
|
|
89
|
+
eventType === NotificationRuleEventType.ScheduledMaintenance
|
|
90
|
+
) {
|
|
87
91
|
// either create slack channel or select existing one should be active.
|
|
88
92
|
|
|
89
|
-
if (
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
93
|
+
if (
|
|
94
|
+
!notificationRule.shouldCreateNewChannel &&
|
|
95
|
+
!notificationRule.shouldPostToExistingChannel
|
|
96
|
+
) {
|
|
97
|
+
return (
|
|
98
|
+
"Please select either create slack channel or post to existing " +
|
|
99
|
+
workspaceType +
|
|
100
|
+
" channel"
|
|
101
|
+
);
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
if (notificationRule.shouldPostToExistingChannel) {
|
|
105
|
+
if (!notificationRule.existingChannelNames?.trim()) {
|
|
106
|
+
return "Existing " + workspaceType + " channel name is required";
|
|
95
107
|
}
|
|
108
|
+
}
|
|
96
109
|
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
}
|
|
110
|
+
if (notificationRule.shouldCreateNewChannel) {
|
|
111
|
+
if (!notificationRule.newChannelTemplateName?.trim()) {
|
|
112
|
+
return "New " + workspaceType + " channel name is required";
|
|
101
113
|
}
|
|
102
114
|
}
|
|
103
115
|
}
|
|
@@ -1,15 +1,8 @@
|
|
|
1
|
-
import
|
|
2
|
-
import BaseNotificationRule from "../BaseNotificationRule";
|
|
1
|
+
import CreateChannelNotificationRule from "../CreateChannelNotificationRule";
|
|
3
2
|
|
|
4
|
-
export default interface AlertNotificationRule
|
|
3
|
+
export default interface AlertNotificationRule
|
|
4
|
+
extends CreateChannelNotificationRule {
|
|
5
5
|
_type: "AlertNotificationRule";
|
|
6
6
|
|
|
7
|
-
// if filters match then do:
|
|
8
|
-
shouldCreateNewChannel: boolean;
|
|
9
|
-
inviteTeamsToNewChannel: Array<ObjectID>;
|
|
10
|
-
inviteUsersToNewChannel: Array<ObjectID>;
|
|
11
|
-
|
|
12
|
-
shouldInviteOwnersToNewChannel: boolean;
|
|
13
|
-
|
|
14
7
|
shouldAutomaticallyInviteOnCallUsersToNewChannel: boolean;
|
|
15
8
|
}
|
|
@@ -1,15 +1,8 @@
|
|
|
1
|
-
import
|
|
2
|
-
import BaseNotificationRule from "../BaseNotificationRule";
|
|
1
|
+
import CreateChannelNotificationRule from "../CreateChannelNotificationRule";
|
|
3
2
|
|
|
4
|
-
export default interface IncidentNotificationRule
|
|
3
|
+
export default interface IncidentNotificationRule
|
|
4
|
+
extends CreateChannelNotificationRule {
|
|
5
5
|
_type: "IncidentNotificationRule";
|
|
6
6
|
|
|
7
|
-
// if filters match then do:
|
|
8
|
-
shouldCreateNewChannel: boolean;
|
|
9
|
-
inviteTeamsToNewChannel: Array<ObjectID>;
|
|
10
|
-
inviteUsersToNewChannel: Array<ObjectID>;
|
|
11
|
-
|
|
12
|
-
shouldInviteOwnersToNewChannel: boolean;
|
|
13
|
-
|
|
14
7
|
shouldAutomaticallyInviteOnCallUsersToNewChannel: boolean;
|
|
15
8
|
}
|