@oneuptime/common 7.0.3621 → 7.0.3655

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 (162) hide show
  1. package/Models/DatabaseModels/Alert.ts +48 -0
  2. package/Models/DatabaseModels/Incident.ts +19 -0
  3. package/Models/DatabaseModels/Index.ts +10 -0
  4. package/Models/DatabaseModels/ScheduledMaintenance.ts +48 -0
  5. package/Models/DatabaseModels/WorkspaceNotificationRule.ts +461 -0
  6. package/Models/DatabaseModels/WorkspaceProjectAuthToken.ts +379 -0
  7. package/Models/DatabaseModels/WorkspaceSetting.ts +230 -0
  8. package/Models/DatabaseModels/WorkspaceUserAuthToken.ts +312 -0
  9. package/Server/API/SlackAPI.ts +368 -0
  10. package/Server/EnvironmentConfig.ts +10 -0
  11. package/Server/Infrastructure/Postgres/SchemaMigrations/1739209832500-MigrationName.ts +147 -0
  12. package/Server/Infrastructure/Postgres/SchemaMigrations/1739210586538-MigrationName.ts +19 -0
  13. package/Server/Infrastructure/Postgres/SchemaMigrations/1739217257089-MigrationName.ts +23 -0
  14. package/Server/Infrastructure/Postgres/SchemaMigrations/1739282331053-MigrationName.ts +29 -0
  15. package/Server/Infrastructure/Postgres/SchemaMigrations/Index.ts +8 -0
  16. package/Server/Middleware/SlackAuthorization.ts +60 -0
  17. package/Server/Services/AlertService.ts +38 -2
  18. package/Server/Services/Index.ts +9 -0
  19. package/Server/Services/ProjectService.ts +6 -4
  20. package/Server/Services/ScheduledMaintenanceService.ts +39 -2
  21. package/Server/Services/TeamMemberService.ts +1 -0
  22. package/Server/Services/UserService.ts +7 -2
  23. package/Server/Services/WorkspaceCommunicationTools/Slack.ts +0 -0
  24. package/Server/Services/WorkspaceCommunicationTools/Teams.ts +0 -0
  25. package/Server/Services/WorkspaceCommunicationTools/WorkspaceCommunicationBaseService.ts +0 -0
  26. package/Server/Services/WorkspaceNotificationRuleService.ts +31 -0
  27. package/Server/Services/WorkspaceProjectAuthTokenService.ts +84 -0
  28. package/Server/Services/WorkspaceSettingService.ts +78 -0
  29. package/Server/Services/WorkspaceUserAuthTokenService.ts +89 -0
  30. package/Server/Types/Workflow/Components/Slack/SendMessageToChannel.ts +2 -2
  31. package/Server/Utils/Express.ts +2 -1
  32. package/Server/Utils/Monitor/MonitorResource.ts +2 -5
  33. package/Server/Utils/Slack/Slack.ts +271 -0
  34. package/Server/Utils/Slack/app-manifest-temp.json +198 -0
  35. package/Server/Utils/Slack/app-manifest.json +67 -0
  36. package/Server/Utils/StartServer.ts +2 -1
  37. package/Types/Filter/FilterCondition.ts +2 -2
  38. package/Types/Monitor/CriteriaFilter.ts +31 -5
  39. package/Types/Monitor/MonitorCriteriaInstance.ts +40 -10
  40. package/Types/Monitor/MonitorStep.ts +1 -1
  41. package/Types/Permission.ts +34 -0
  42. package/Types/Workspace/NotificationRules/BaseNotificationRule.ts +3 -0
  43. package/Types/Workspace/NotificationRules/EventType.ts +8 -0
  44. package/Types/Workspace/NotificationRules/NotificationRuleCondition.ts +355 -0
  45. package/Types/Workspace/NotificationRules/SlackNotificationRule.ts +19 -0
  46. package/Types/Workspace/WorkspaceNotificationPayload.ts +29 -0
  47. package/Types/Workspace/WorkspaceType.ts +6 -0
  48. package/UI/Components/Forms/BasicForm.tsx +9 -0
  49. package/UI/Components/Forms/Fields/FormField.tsx +36 -1
  50. package/UI/Components/Forms/Types/Field.ts +2 -0
  51. package/UI/Components/Forms/Types/FormFieldSchemaType.ts +1 -1
  52. package/UI/Components/Forms/Utils/FormFieldSchemaTypeUtil.ts +2 -2
  53. package/UI/Components/Icon/Icon.tsx +18 -5
  54. package/UI/Components/Radio/Radio.tsx +12 -10
  55. package/UI/Config.ts +3 -0
  56. package/build/dist/Models/DatabaseModels/Alert.js +52 -0
  57. package/build/dist/Models/DatabaseModels/Alert.js.map +1 -1
  58. package/build/dist/Models/DatabaseModels/Incident.js +21 -0
  59. package/build/dist/Models/DatabaseModels/Incident.js.map +1 -1
  60. package/build/dist/Models/DatabaseModels/Index.js +8 -0
  61. package/build/dist/Models/DatabaseModels/Index.js.map +1 -1
  62. package/build/dist/Models/DatabaseModels/ScheduledMaintenance.js +52 -0
  63. package/build/dist/Models/DatabaseModels/ScheduledMaintenance.js.map +1 -1
  64. package/build/dist/Models/DatabaseModels/WorkspaceNotificationRule.js +481 -0
  65. package/build/dist/Models/DatabaseModels/WorkspaceNotificationRule.js.map +1 -0
  66. package/build/dist/Models/DatabaseModels/WorkspaceProjectAuthToken.js +390 -0
  67. package/build/dist/Models/DatabaseModels/WorkspaceProjectAuthToken.js.map +1 -0
  68. package/build/dist/Models/DatabaseModels/WorkspaceSetting.js +236 -0
  69. package/build/dist/Models/DatabaseModels/WorkspaceSetting.js.map +1 -0
  70. package/build/dist/Models/DatabaseModels/WorkspaceUserAuthToken.js +326 -0
  71. package/build/dist/Models/DatabaseModels/WorkspaceUserAuthToken.js.map +1 -0
  72. package/build/dist/Server/API/SlackAPI.js +237 -0
  73. package/build/dist/Server/API/SlackAPI.js.map +1 -0
  74. package/build/dist/Server/EnvironmentConfig.js +5 -1
  75. package/build/dist/Server/EnvironmentConfig.js.map +1 -1
  76. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1739209832500-MigrationName.js +58 -0
  77. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1739209832500-MigrationName.js.map +1 -0
  78. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1739210586538-MigrationName.js +14 -0
  79. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1739210586538-MigrationName.js.map +1 -0
  80. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1739217257089-MigrationName.js +14 -0
  81. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1739217257089-MigrationName.js.map +1 -0
  82. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1739282331053-MigrationName.js +16 -0
  83. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1739282331053-MigrationName.js.map +1 -0
  84. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/Index.js +8 -0
  85. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/Index.js.map +1 -1
  86. package/build/dist/Server/Middleware/SlackAuthorization.js +28 -0
  87. package/build/dist/Server/Middleware/SlackAuthorization.js.map +1 -0
  88. package/build/dist/Server/Services/AlertService.js +31 -5
  89. package/build/dist/Server/Services/AlertService.js.map +1 -1
  90. package/build/dist/Server/Services/Index.js +8 -0
  91. package/build/dist/Server/Services/Index.js.map +1 -1
  92. package/build/dist/Server/Services/ProjectService.js +5 -4
  93. package/build/dist/Server/Services/ProjectService.js.map +1 -1
  94. package/build/dist/Server/Services/ScheduledMaintenanceService.js +30 -3
  95. package/build/dist/Server/Services/ScheduledMaintenanceService.js.map +1 -1
  96. package/build/dist/Server/Services/TeamMemberService.js +1 -0
  97. package/build/dist/Server/Services/TeamMemberService.js.map +1 -1
  98. package/build/dist/Server/Services/UserService.js +5 -2
  99. package/build/dist/Server/Services/UserService.js.map +1 -1
  100. package/build/dist/Server/Services/WorkspaceCommunicationTools/Slack.js +2 -0
  101. package/build/dist/Server/Services/WorkspaceCommunicationTools/Slack.js.map +1 -0
  102. package/build/dist/Server/Services/WorkspaceCommunicationTools/Teams.js +2 -0
  103. package/build/dist/Server/Services/WorkspaceCommunicationTools/Teams.js.map +1 -0
  104. package/build/dist/Server/Services/WorkspaceCommunicationTools/WorkspaceCommunicationBaseService.js +2 -0
  105. package/build/dist/Server/Services/WorkspaceCommunicationTools/WorkspaceCommunicationBaseService.js.map +1 -0
  106. package/build/dist/Server/Services/WorkspaceNotificationRuleService.js +22 -0
  107. package/build/dist/Server/Services/WorkspaceNotificationRuleService.js.map +1 -0
  108. package/build/dist/Server/Services/WorkspaceProjectAuthTokenService.js +63 -0
  109. package/build/dist/Server/Services/WorkspaceProjectAuthTokenService.js.map +1 -0
  110. package/build/dist/Server/Services/WorkspaceSettingService.js +59 -0
  111. package/build/dist/Server/Services/WorkspaceSettingService.js.map +1 -0
  112. package/build/dist/Server/Services/WorkspaceUserAuthTokenService.js +66 -0
  113. package/build/dist/Server/Services/WorkspaceUserAuthTokenService.js.map +1 -0
  114. package/build/dist/Server/Types/Workflow/Components/Slack/SendMessageToChannel.js +2 -2
  115. package/build/dist/Server/Types/Workflow/Components/Slack/SendMessageToChannel.js.map +1 -1
  116. package/build/dist/Server/Utils/Express.js.map +1 -1
  117. package/build/dist/Server/Utils/Monitor/MonitorResource.js +2 -1
  118. package/build/dist/Server/Utils/Monitor/MonitorResource.js.map +1 -1
  119. package/build/dist/Server/Utils/Slack/Slack.js +172 -0
  120. package/build/dist/Server/Utils/Slack/Slack.js.map +1 -0
  121. package/build/dist/Server/Utils/Slack/app-manifest.json +67 -0
  122. package/build/dist/Server/Utils/StartServer.js.map +1 -1
  123. package/build/dist/Types/Filter/FilterCondition.js +2 -2
  124. package/build/dist/Types/Filter/FilterCondition.js.map +1 -1
  125. package/build/dist/Types/Monitor/CriteriaFilter.js +19 -5
  126. package/build/dist/Types/Monitor/CriteriaFilter.js.map +1 -1
  127. package/build/dist/Types/Monitor/MonitorCriteriaInstance.js +33 -10
  128. package/build/dist/Types/Monitor/MonitorCriteriaInstance.js.map +1 -1
  129. package/build/dist/Types/Monitor/MonitorStep.js +1 -1
  130. package/build/dist/Types/Monitor/MonitorStep.js.map +1 -1
  131. package/build/dist/Types/Permission.js +32 -0
  132. package/build/dist/Types/Permission.js.map +1 -1
  133. package/build/dist/Types/Workspace/NotificationRules/BaseNotificationRule.js +2 -0
  134. package/build/dist/Types/Workspace/NotificationRules/BaseNotificationRule.js.map +1 -0
  135. package/build/dist/Types/Workspace/NotificationRules/EventType.js +9 -0
  136. package/build/dist/Types/Workspace/NotificationRules/EventType.js.map +1 -0
  137. package/build/dist/Types/Workspace/NotificationRules/NotificationRuleCondition.js +275 -0
  138. package/build/dist/Types/Workspace/NotificationRules/NotificationRuleCondition.js.map +1 -0
  139. package/build/dist/Types/Workspace/NotificationRules/SlackNotificationRule.js +2 -0
  140. package/build/dist/Types/Workspace/NotificationRules/SlackNotificationRule.js.map +1 -0
  141. package/build/dist/Types/Workspace/WorkspaceNotificationPayload.js +2 -0
  142. package/build/dist/Types/Workspace/WorkspaceNotificationPayload.js.map +1 -0
  143. package/build/dist/Types/Workspace/WorkspaceType.js +7 -0
  144. package/build/dist/Types/Workspace/WorkspaceType.js.map +1 -0
  145. package/build/dist/UI/Components/Forms/BasicForm.js +7 -0
  146. package/build/dist/UI/Components/Forms/BasicForm.js.map +1 -1
  147. package/build/dist/UI/Components/Forms/Fields/FormField.js +21 -4
  148. package/build/dist/UI/Components/Forms/Fields/FormField.js.map +1 -1
  149. package/build/dist/UI/Components/Forms/Types/FormFieldSchemaType.js +1 -1
  150. package/build/dist/UI/Components/Forms/Types/FormFieldSchemaType.js.map +1 -1
  151. package/build/dist/UI/Components/Forms/Utils/FormFieldSchemaTypeUtil.js +2 -2
  152. package/build/dist/UI/Components/Forms/Utils/FormFieldSchemaTypeUtil.js.map +1 -1
  153. package/build/dist/UI/Components/Icon/Icon.js +5 -1
  154. package/build/dist/UI/Components/Icon/Icon.js.map +1 -1
  155. package/build/dist/UI/Components/Radio/Radio.js +4 -4
  156. package/build/dist/UI/Components/Radio/Radio.js.map +1 -1
  157. package/build/dist/UI/Config.js +1 -0
  158. package/build/dist/UI/Config.js.map +1 -1
  159. package/package.json +2 -2
  160. package/Server/Utils/Slack.ts +0 -29
  161. package/build/dist/Server/Utils/Slack.js +0 -20
  162. package/build/dist/Server/Utils/Slack.js.map +0 -1
@@ -0,0 +1,84 @@
1
+ import ObjectID from "../../Types/ObjectID";
2
+ import WorkspaceType from "../../Types/Workspace/WorkspaceType";
3
+ import DatabaseService from "./DatabaseService";
4
+ import Model, {
5
+ SlackMiscData,
6
+ } from "Common/Models/DatabaseModels/WorkspaceProjectAuthToken";
7
+
8
+ export class Service extends DatabaseService<Model> {
9
+ public constructor() {
10
+ super(Model);
11
+ }
12
+
13
+ public async doesExist(data: {
14
+ projectId: ObjectID;
15
+ workspaceType: WorkspaceType;
16
+ }): Promise<boolean> {
17
+ return (
18
+ (
19
+ await this.countBy({
20
+ query: {
21
+ projectId: data.projectId,
22
+ workspaceType: data.workspaceType,
23
+ },
24
+ skip: 0,
25
+ limit: 1,
26
+ props: {
27
+ isRoot: true,
28
+ },
29
+ })
30
+ ).toNumber() > 0
31
+ );
32
+ }
33
+
34
+ public async refreshAuthToken(data: {
35
+ projectId: ObjectID;
36
+ workspaceType: WorkspaceType;
37
+ authToken: string;
38
+ workspaceProjectId: string;
39
+ miscData: SlackMiscData;
40
+ }): Promise<void> {
41
+ let projectAuth: Model | null = await this.findOneBy({
42
+ query: {
43
+ projectId: data.projectId,
44
+ workspaceType: data.workspaceType,
45
+ },
46
+ select: {
47
+ _id: true,
48
+ },
49
+ props: {
50
+ isRoot: true,
51
+ },
52
+ });
53
+
54
+ if (!projectAuth) {
55
+ projectAuth = new Model();
56
+
57
+ projectAuth.projectId = data.projectId;
58
+ projectAuth.authToken = data.authToken;
59
+ projectAuth.workspaceType = data.workspaceType;
60
+ projectAuth.workspaceProjectId = data.workspaceProjectId;
61
+ projectAuth.miscData = data.miscData;
62
+
63
+ await this.create({
64
+ data: projectAuth,
65
+ props: {
66
+ isRoot: true,
67
+ },
68
+ });
69
+ } else {
70
+ await this.updateOneById({
71
+ id: projectAuth.id!,
72
+ data: {
73
+ authToken: data.authToken,
74
+ workspaceProjectId: data.workspaceProjectId,
75
+ miscData: data.miscData,
76
+ },
77
+ props: {
78
+ isRoot: true,
79
+ },
80
+ });
81
+ }
82
+ }
83
+ }
84
+ export default new Service();
@@ -0,0 +1,78 @@
1
+ import ObjectID from "../../Types/ObjectID";
2
+ import WorkspaceType from "../../Types/Workspace/WorkspaceType";
3
+ import DatabaseService from "./DatabaseService";
4
+ import Model, {
5
+ SlackSettings,
6
+ } from "Common/Models/DatabaseModels/WorkspaceSetting";
7
+
8
+ export class Service extends DatabaseService<Model> {
9
+ public constructor() {
10
+ super(Model);
11
+ }
12
+
13
+ public async doesExist(data: {
14
+ projectId: ObjectID;
15
+ workspaceType: WorkspaceType;
16
+ }): Promise<boolean> {
17
+ return (
18
+ (
19
+ await this.countBy({
20
+ query: {
21
+ projectId: data.projectId,
22
+ workspaceType: data.workspaceType,
23
+ },
24
+ skip: 0,
25
+ limit: 1,
26
+ props: {
27
+ isRoot: true,
28
+ },
29
+ })
30
+ ).toNumber() > 0
31
+ );
32
+ }
33
+
34
+ public async refreshSetting(data: {
35
+ projectId: ObjectID;
36
+ workspaceType: WorkspaceType;
37
+ settings: SlackSettings;
38
+ }): Promise<void> {
39
+ let workspaceSetting: Model | null = await this.findOneBy({
40
+ query: {
41
+ projectId: data.projectId,
42
+ workspaceType: data.workspaceType,
43
+ },
44
+ select: {
45
+ _id: true,
46
+ },
47
+ props: {
48
+ isRoot: true,
49
+ },
50
+ });
51
+
52
+ if (!workspaceSetting) {
53
+ workspaceSetting = new Model();
54
+
55
+ workspaceSetting.projectId = data.projectId;
56
+ workspaceSetting.settings = data.settings;
57
+ workspaceSetting.workspaceType = data.workspaceType;
58
+
59
+ await this.create({
60
+ data: workspaceSetting,
61
+ props: {
62
+ isRoot: true,
63
+ },
64
+ });
65
+ } else {
66
+ await this.updateOneById({
67
+ id: workspaceSetting.id!,
68
+ data: {
69
+ settings: data.settings,
70
+ },
71
+ props: {
72
+ isRoot: true,
73
+ },
74
+ });
75
+ }
76
+ }
77
+ }
78
+ export default new Service();
@@ -0,0 +1,89 @@
1
+ import ObjectID from "../../Types/ObjectID";
2
+ import WorkspaceType from "../../Types/Workspace/WorkspaceType";
3
+ import DatabaseService from "./DatabaseService";
4
+ import Model, {
5
+ SlackMiscData,
6
+ } from "Common/Models/DatabaseModels/WorkspaceUserAuthToken";
7
+
8
+ export class Service extends DatabaseService<Model> {
9
+ public constructor() {
10
+ super(Model);
11
+ }
12
+
13
+ public async doesExist(data: {
14
+ projectId: ObjectID;
15
+ userId: ObjectID;
16
+ workspaceType: WorkspaceType;
17
+ }): Promise<boolean> {
18
+ return (
19
+ (
20
+ await this.countBy({
21
+ query: {
22
+ projectId: data.projectId,
23
+ userId: data.userId,
24
+ workspaceType: data.workspaceType,
25
+ },
26
+ skip: 0,
27
+ limit: 1,
28
+ props: {
29
+ isRoot: true,
30
+ },
31
+ })
32
+ ).toNumber() > 0
33
+ );
34
+ }
35
+
36
+ public async refreshAuthToken(data: {
37
+ projectId: ObjectID;
38
+ userId: ObjectID;
39
+ workspaceType: WorkspaceType;
40
+ authToken: string;
41
+ workspaceUserId: string;
42
+ miscData: SlackMiscData;
43
+ }): Promise<void> {
44
+ let userAuth: Model | null = await this.findOneBy({
45
+ query: {
46
+ projectId: data.projectId,
47
+ userId: data.userId,
48
+ workspaceType: data.workspaceType,
49
+ },
50
+ select: {
51
+ _id: true,
52
+ },
53
+ props: {
54
+ isRoot: true,
55
+ },
56
+ });
57
+
58
+ if (!userAuth) {
59
+ userAuth = new Model();
60
+
61
+ userAuth.projectId = data.projectId;
62
+ userAuth.userId = data.userId;
63
+ userAuth.authToken = data.authToken;
64
+ userAuth.workspaceType = data.workspaceType;
65
+ userAuth.workspaceUserId = data.workspaceUserId;
66
+ userAuth.miscData = data.miscData;
67
+
68
+ await this.create({
69
+ data: userAuth,
70
+ props: {
71
+ isRoot: true,
72
+ },
73
+ });
74
+ } else {
75
+ await this.updateOneById({
76
+ id: userAuth.id!,
77
+ data: {
78
+ authToken: data.authToken,
79
+ workspaceUserId: data.workspaceUserId,
80
+ miscData: data.miscData,
81
+ },
82
+ props: {
83
+ isRoot: true,
84
+ },
85
+ });
86
+ }
87
+ }
88
+ }
89
+ export default new Service();
@@ -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";
11
+ import SlackUtil from "../../../../Utils/Slack/Slack";
12
12
 
13
13
  export default class SendMessageToChannel extends ComponentCode {
14
14
  public constructor() {
@@ -69,7 +69,7 @@ export default class SendMessageToChannel extends ComponentCode {
69
69
 
70
70
  try {
71
71
  // https://api.slack.com/messaging/webhooks#advanced_message_formatting
72
- apiResult = await SlackUtil.sendMessageToChannel({
72
+ apiResult = await SlackUtil.sendMessageToChannelViaIncomingWebhook({
73
73
  url: args["webhook-url"] as URL,
74
74
  text: args["text"] as string,
75
75
  });
@@ -37,7 +37,8 @@ export interface OneUptimeRequest extends express.Request {
37
37
  userAuthorization?: JSONWebTokenData;
38
38
  tenantId?: ObjectID;
39
39
  userGlobalAccessPermission?: UserGlobalAccessPermission;
40
- userTenantAccessPermission?: Dictionary<UserTenantAccessPermission>; // tenantId <-> UserTenantAccessPermission
40
+ userTenantAccessPermission?: Dictionary<UserTenantAccessPermission>; // tenantId <-> UserTenantAccessPermission;
41
+ rawBody?: string; // raw body of the request before json parsing.
41
42
  }
42
43
 
43
44
  export interface OneUptimeResponse extends express.Response {
@@ -16,11 +16,7 @@ import BadDataException from "Common/Types/Exception/BadDataException";
16
16
  import BasicInfrastructureMetrics from "Common/Types/Infrastructure/BasicMetrics";
17
17
  import ReturnResult from "Common/Types/IsolatedVM/ReturnResult";
18
18
  import { JSONObject } from "Common/Types/JSON";
19
- import {
20
- CheckOn,
21
- CriteriaFilter,
22
- FilterCondition,
23
- } from "Common/Types/Monitor/CriteriaFilter";
19
+ import { CheckOn, CriteriaFilter } from "Common/Types/Monitor/CriteriaFilter";
24
20
  import IncomingMonitorRequest from "Common/Types/Monitor/IncomingMonitor/IncomingMonitorRequest";
25
21
  import MonitorCriteria from "Common/Types/Monitor/MonitorCriteria";
26
22
  import MonitorCriteriaInstance from "Common/Types/Monitor/MonitorCriteriaInstance";
@@ -57,6 +53,7 @@ import MonitorMetricType from "../../../Types/Monitor/MonitorMetricType";
57
53
  import TelemetryUtil from "../Telemetry/Telemetry";
58
54
  import MetricMonitorCriteria from "./Criteria/MetricMonitorCriteria";
59
55
  import MetricMonitorResponse from "../../../Types/Monitor/MetricMonitor/MetricMonitorResponse";
56
+ import FilterCondition from "../../../Types/Filter/FilterCondition";
60
57
 
61
58
  export default class MonitorResourceUtil {
62
59
  public static async monitorResource(
@@ -0,0 +1,271 @@
1
+ import HTTPErrorResponse from "Common/Types/API/HTTPErrorResponse";
2
+ import HTTPResponse from "Common/Types/API/HTTPResponse";
3
+ import URL from "Common/Types/API/URL";
4
+ import { JSONObject } from "Common/Types/JSON";
5
+ import API from "Common/Utils/API";
6
+ import WorkspaceNotificationPayload, {
7
+ WorkspaceNotificationPayloadButton,
8
+ WorkspacePayloadButtons,
9
+ WorkspacePayloadHeader,
10
+ WorkspacePayloadMarkdown,
11
+ } from "../../../Types/Workspace/WorkspaceNotificationPayload";
12
+ import logger from "../Logger";
13
+ import Dictionary from "../../../Types/Dictionary";
14
+ import BadRequestException from "../../../Types/Exception/BadRequestException";
15
+
16
+ export interface JobResponse {
17
+ isSuccessful: boolean;
18
+ errorMessage?: string | undefined;
19
+ }
20
+
21
+ export interface SlackChannel {
22
+ id: string;
23
+ name: string;
24
+ }
25
+
26
+ export default class SlackUtil {
27
+ public static async sendMessage(data: {
28
+ workspaceNotificationPayload: WorkspaceNotificationPayload;
29
+ authToken: string; // which auth token should we use to send.
30
+ }): Promise<void> {
31
+ logger.debug("Notify Slack");
32
+ logger.debug(data);
33
+
34
+ const blocks: Array<JSONObject> =
35
+ this.getSlackBlocksFromWorkspaceNotificationPayload(
36
+ data.workspaceNotificationPayload,
37
+ );
38
+
39
+ const existingSlackChannels: Dictionary<SlackChannel> =
40
+ await this.getSlackChannels({
41
+ authToken: data.authToken,
42
+ });
43
+
44
+ for (const channelName of data.workspaceNotificationPayload.channelNames) {
45
+ // get channel ids from existingSlackChannels. IF channel doesn't exist, create it if createChannelsIfItDoesNotExist is true.
46
+ let channel: SlackChannel | null = null;
47
+
48
+ if (existingSlackChannels[channelName]) {
49
+ channel = existingSlackChannels[channelName]!;
50
+ } else if (
51
+ data.workspaceNotificationPayload.createChannelsIfItDoesNotExist
52
+ ) {
53
+ channel = await this.createChannel({
54
+ authToken: data.authToken,
55
+ channelName: channelName,
56
+ });
57
+ }
58
+
59
+ if (channel) {
60
+ await this.sendPayloadBlocksToChannel({
61
+ authToken: data.authToken,
62
+ channelId: channel.id,
63
+ blocks: blocks,
64
+ });
65
+ } else {
66
+ logger.debug(
67
+ `Channel ${channelName} does not exist and createChannelsIfItDoesNotExist is false.`,
68
+ );
69
+ }
70
+ }
71
+ }
72
+
73
+ public static async sendPayloadBlocksToChannel(data: {
74
+ authToken: string;
75
+ channelId: string;
76
+ blocks: Array<JSONObject>;
77
+ }): Promise<void> {
78
+ const response: HTTPErrorResponse | HTTPResponse<JSONObject> =
79
+ await API.post(
80
+ URL.fromString("https://slack.com/api/chat.postMessage"),
81
+ {
82
+ channel: data.channelId,
83
+ blocks: data.blocks,
84
+ },
85
+ {
86
+ Authorization: `Bearer ${data.authToken}`,
87
+ },
88
+ );
89
+
90
+ if (response instanceof HTTPErrorResponse) {
91
+ throw response;
92
+ }
93
+
94
+ if ((response.jsonData as JSONObject)?.["ok"] !== true) {
95
+ throw new BadRequestException("Invalid response");
96
+ }
97
+ }
98
+
99
+ public static async createChannel(data: {
100
+ authToken: string;
101
+ channelName: string;
102
+ }): Promise<SlackChannel> {
103
+ const response: HTTPResponse<JSONObject> | HTTPErrorResponse =
104
+ await API.post(
105
+ URL.fromString("https://slack.com/api/conversations.create"),
106
+ {
107
+ name: data.channelName,
108
+ },
109
+ {
110
+ Authorization: `Bearer ${data.authToken}`,
111
+ },
112
+ );
113
+
114
+ if (response instanceof HTTPErrorResponse) {
115
+ throw response;
116
+ }
117
+
118
+ if (
119
+ !((response.jsonData as JSONObject)?.["channel"] as JSONObject)?.["id"] ||
120
+ !((response.jsonData as JSONObject)?.["channel"] as JSONObject)?.["name"]
121
+ ) {
122
+ throw new Error("Invalid response");
123
+ }
124
+
125
+ return {
126
+ id: ((response.jsonData as JSONObject)["channel"] as JSONObject)[
127
+ "id"
128
+ ] as string,
129
+ name: ((response.jsonData as JSONObject)["channel"] as JSONObject)[
130
+ "name"
131
+ ] as string,
132
+ };
133
+ }
134
+
135
+ public static getHeaderBlock(data: {
136
+ payloadHeaderBlock: WorkspacePayloadHeader;
137
+ }): JSONObject {
138
+ return {
139
+ type: "header",
140
+ text: {
141
+ type: "plain_text",
142
+ text: data.payloadHeaderBlock.text,
143
+ },
144
+ };
145
+ }
146
+
147
+ public static getMarkdownBlock(data: {
148
+ payloadMarkdownBlock: WorkspacePayloadMarkdown;
149
+ }): JSONObject {
150
+ return {
151
+ type: "section",
152
+ text: {
153
+ type: "mrkdwn",
154
+ text: data.payloadMarkdownBlock.text,
155
+ },
156
+ };
157
+ }
158
+
159
+ public static async getSlackChannels(data: {
160
+ authToken: string;
161
+ }): Promise<Dictionary<SlackChannel>> {
162
+ const response: HTTPErrorResponse | HTTPResponse<JSONObject> =
163
+ await API.get<JSONObject>(
164
+ URL.fromString("https://slack.com/api/conversations.list"),
165
+ {
166
+ headers: {
167
+ Authorization: `Bearer ${data.authToken}`,
168
+ },
169
+ },
170
+ );
171
+
172
+ if (response instanceof HTTPErrorResponse) {
173
+ throw response;
174
+ }
175
+
176
+ const channels: Dictionary<SlackChannel> = {};
177
+
178
+ for (const channel of (response.jsonData as JSONObject)[
179
+ "channels"
180
+ ] as Array<JSONObject>) {
181
+ if (!channel["id"] || !channel["name"]) {
182
+ continue;
183
+ }
184
+
185
+ channels[channel["name"].toString()] = {
186
+ id: channel["id"] as string,
187
+ name: channel["name"] as string,
188
+ };
189
+ }
190
+
191
+ return channels;
192
+ }
193
+
194
+ public static getButtonBlock(data: {
195
+ payloadButtonBlock: WorkspaceNotificationPayloadButton;
196
+ }): JSONObject {
197
+ return {
198
+ type: "button",
199
+ text: {
200
+ type: "plain_text",
201
+ text: data.payloadButtonBlock.title,
202
+ },
203
+ value: data.payloadButtonBlock.title,
204
+ action_id: data.payloadButtonBlock.title,
205
+ };
206
+ }
207
+
208
+ public static async sendMessageToChannelViaIncomingWebhook(data: {
209
+ url: URL;
210
+ text: string;
211
+ }): Promise<HTTPResponse<JSONObject> | HTTPErrorResponse> {
212
+ let apiResult: HTTPResponse<JSONObject> | HTTPErrorResponse | null = null;
213
+
214
+ // https://api.slack.com/messaging/webhooks#advanced_message_formatting
215
+ apiResult = await API.post(data.url, {
216
+ blocks: [
217
+ {
218
+ type: "section",
219
+ text: {
220
+ type: "mrkdwn",
221
+ text: `${data.text}`,
222
+ },
223
+ },
224
+ ],
225
+ });
226
+
227
+ return apiResult;
228
+ }
229
+
230
+ private static getSlackBlocksFromWorkspaceNotificationPayload(
231
+ data: WorkspaceNotificationPayload,
232
+ ): Array<JSONObject> {
233
+ const blocks: Array<JSONObject> = [];
234
+ const buttons: Array<JSONObject> = [];
235
+ for (const block of data.blocks) {
236
+ switch (block._type) {
237
+ case "WorkspacePayloadHeader":
238
+ blocks.push(
239
+ this.getHeaderBlock({
240
+ payloadHeaderBlock: block as WorkspacePayloadHeader,
241
+ }),
242
+ );
243
+ break;
244
+ case "WorkspacePayloadMarkdown":
245
+ blocks.push(
246
+ this.getMarkdownBlock({
247
+ payloadMarkdownBlock: block as WorkspacePayloadMarkdown,
248
+ }),
249
+ );
250
+ break;
251
+ case "WorkspacePayloadButtons":
252
+ for (const button of (block as WorkspacePayloadButtons).buttons) {
253
+ buttons.push(
254
+ this.getButtonBlock({
255
+ payloadButtonBlock: button,
256
+ }),
257
+ );
258
+ }
259
+ blocks.push({
260
+ type: "actions",
261
+ elements: buttons,
262
+ });
263
+ break;
264
+ default:
265
+ logger.error("Unknown block type: " + block._type);
266
+ break;
267
+ }
268
+ }
269
+ return blocks;
270
+ }
271
+ }