@oneuptime/common 7.0.4349 → 7.0.4372
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/AnalyticsModels/ExceptionInstance.ts +2 -2
- package/Models/DatabaseModels/OnCallDutyPolicyEscalationRuleSchedule.ts +2 -2
- package/Models/DatabaseModels/OnCallDutyPolicyEscalationRuleTeam.ts +2 -2
- package/Models/DatabaseModels/OnCallDutyPolicyEscalationRuleUser.ts +2 -2
- package/Models/DatabaseModels/OnCallDutyPolicyTimeLog.ts +2 -2
- package/Models/DatabaseModels/Probe.ts +7 -1
- package/Models/DatabaseModels/ServiceCatalog.ts +2 -2
- package/Models/DatabaseModels/ServiceCopilotCodeRepository.ts +2 -2
- package/Models/DatabaseModels/StatusPage.ts +37 -0
- package/Models/DatabaseModels/StatusPageSubscriber.ts +60 -0
- package/Server/API/StatusPageAPI.ts +104 -10
- package/Server/Infrastructure/Postgres/SchemaMigrations/1749065784320-MigrationName.ts +23 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/1749133333893-MigrationName.ts +17 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/Index.ts +4 -0
- package/Server/Services/ScheduledMaintenanceService.ts +21 -0
- package/Server/Services/StatusPageSubscriberService.ts +116 -1
- package/Server/Utils/OpenAPI.ts +738 -11
- package/Server/Utils/Workspace/Slack/Slack.ts +14 -0
- package/Utils/Schema/AnalyticsModelSchema.ts +764 -0
- package/Utils/Schema/BaseSchema.ts +450 -0
- package/Utils/Schema/ModelSchema.ts +1099 -38
- package/build/dist/Models/AnalyticsModels/ExceptionInstance.js +2 -2
- package/build/dist/Models/AnalyticsModels/ExceptionInstance.js.map +1 -1
- package/build/dist/Models/DatabaseModels/OnCallDutyPolicyEscalationRuleSchedule.js +2 -2
- package/build/dist/Models/DatabaseModels/OnCallDutyPolicyEscalationRuleSchedule.js.map +1 -1
- package/build/dist/Models/DatabaseModels/OnCallDutyPolicyEscalationRuleTeam.js +2 -2
- package/build/dist/Models/DatabaseModels/OnCallDutyPolicyEscalationRuleTeam.js.map +1 -1
- package/build/dist/Models/DatabaseModels/OnCallDutyPolicyEscalationRuleUser.js +2 -2
- package/build/dist/Models/DatabaseModels/OnCallDutyPolicyEscalationRuleUser.js.map +1 -1
- package/build/dist/Models/DatabaseModels/OnCallDutyPolicyTimeLog.js +2 -2
- package/build/dist/Models/DatabaseModels/OnCallDutyPolicyTimeLog.js.map +1 -1
- package/build/dist/Models/DatabaseModels/Probe.js +7 -1
- package/build/dist/Models/DatabaseModels/Probe.js.map +1 -1
- package/build/dist/Models/DatabaseModels/ServiceCatalog.js +2 -2
- package/build/dist/Models/DatabaseModels/ServiceCatalog.js.map +1 -1
- package/build/dist/Models/DatabaseModels/ServiceCopilotCodeRepository.js +2 -2
- package/build/dist/Models/DatabaseModels/ServiceCopilotCodeRepository.js.map +1 -1
- package/build/dist/Models/DatabaseModels/StatusPage.js +39 -0
- package/build/dist/Models/DatabaseModels/StatusPage.js.map +1 -1
- package/build/dist/Models/DatabaseModels/StatusPageSubscriber.js +62 -0
- package/build/dist/Models/DatabaseModels/StatusPageSubscriber.js.map +1 -1
- package/build/dist/Server/API/StatusPageAPI.js +73 -10
- package/build/dist/Server/API/StatusPageAPI.js.map +1 -1
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1749065784320-MigrationName.js +14 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1749065784320-MigrationName.js.map +1 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1749133333893-MigrationName.js +12 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1749133333893-MigrationName.js.map +1 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/Index.js +4 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/Index.js.map +1 -1
- package/build/dist/Server/Services/ScheduledMaintenanceService.js +19 -0
- package/build/dist/Server/Services/ScheduledMaintenanceService.js.map +1 -1
- package/build/dist/Server/Services/StatusPageSubscriberService.js +98 -1
- package/build/dist/Server/Services/StatusPageSubscriberService.js.map +1 -1
- package/build/dist/Server/Utils/OpenAPI.js +578 -11
- package/build/dist/Server/Utils/OpenAPI.js.map +1 -1
- package/build/dist/Server/Utils/Workspace/Slack/Slack.js +15 -0
- package/build/dist/Server/Utils/Workspace/Slack/Slack.js.map +1 -1
- package/build/dist/Utils/Schema/AnalyticsModelSchema.js +636 -0
- package/build/dist/Utils/Schema/AnalyticsModelSchema.js.map +1 -0
- package/build/dist/Utils/Schema/BaseSchema.js +295 -0
- package/build/dist/Utils/Schema/BaseSchema.js.map +1 -0
- package/build/dist/Utils/Schema/ModelSchema.js +940 -27
- package/build/dist/Utils/Schema/ModelSchema.js.map +1 -1
- package/package.json +1 -1
|
@@ -31,6 +31,7 @@ import Model from "../../Models/DatabaseModels/StatusPageSubscriber";
|
|
|
31
31
|
import PositiveNumber from "../../Types/PositiveNumber";
|
|
32
32
|
import StatusPageEventType from "../../Types/StatusPage/StatusPageEventType";
|
|
33
33
|
import NumberUtil from "../../Utils/Number";
|
|
34
|
+
import SlackUtil from "../Utils/Workspace/Slack/Slack";
|
|
34
35
|
|
|
35
36
|
export class Service extends DatabaseService<Model> {
|
|
36
37
|
public constructor() {
|
|
@@ -143,6 +144,7 @@ export class Service extends DatabaseService<Model> {
|
|
|
143
144
|
ignoreHooks: true,
|
|
144
145
|
},
|
|
145
146
|
});
|
|
147
|
+
|
|
146
148
|
logger.debug(`Found Subscriber by Phone: ${JSON.stringify(subscriber)}`);
|
|
147
149
|
}
|
|
148
150
|
|
|
@@ -197,12 +199,28 @@ export class Service extends DatabaseService<Model> {
|
|
|
197
199
|
if (isEmailSubscriber && !isSubscriptionConfirmed) {
|
|
198
200
|
data.data.isSubscriptionConfirmed = false;
|
|
199
201
|
} else {
|
|
200
|
-
data.data.isSubscriptionConfirmed = true; // if the subscriber is not email, then set it to true for SMS subscribers.
|
|
202
|
+
data.data.isSubscriptionConfirmed = true; // if the subscriber is not email, then set it to true for SMS subscribers / slack subscribers.
|
|
201
203
|
}
|
|
202
204
|
logger.debug(
|
|
203
205
|
`Final Subscription Confirmed: ${data.data.isSubscriptionConfirmed}`,
|
|
204
206
|
);
|
|
205
207
|
|
|
208
|
+
// if slack incoming webhook is provided, then see if it starts with https://hooks.slack.com/services/
|
|
209
|
+
|
|
210
|
+
if (data.data.slackIncomingWebhookUrl) {
|
|
211
|
+
logger.debug(
|
|
212
|
+
`Slack Incoming Webhook URL: ${data.data.slackIncomingWebhookUrl}`,
|
|
213
|
+
);
|
|
214
|
+
if (
|
|
215
|
+
!SlackUtil.isValidSlackIncomingWebhookUrl(
|
|
216
|
+
data.data.slackIncomingWebhookUrl,
|
|
217
|
+
)
|
|
218
|
+
) {
|
|
219
|
+
logger.debug("Invalid Slack Incoming Webhook URL.");
|
|
220
|
+
throw new BadDataException("Invalid Slack Incoming Webhook URL.");
|
|
221
|
+
}
|
|
222
|
+
}
|
|
223
|
+
|
|
206
224
|
data.data.subscriptionConfirmationToken = NumberUtil.getRandomNumber(
|
|
207
225
|
100000,
|
|
208
226
|
999999,
|
|
@@ -331,6 +349,38 @@ export class Service extends DatabaseService<Model> {
|
|
|
331
349
|
}
|
|
332
350
|
}
|
|
333
351
|
|
|
352
|
+
// if slack incoming webhook is provided, then send a message to the slack channel.
|
|
353
|
+
if (createdItem.slackIncomingWebhookUrl) {
|
|
354
|
+
logger.debug("Sending Slack notification for new subscriber.");
|
|
355
|
+
const slackMessage: string = `## 📢 New Subscription to ${statusPageName}
|
|
356
|
+
|
|
357
|
+
**You have successfully subscribed to receive status updates!**
|
|
358
|
+
|
|
359
|
+
🔗 **Status Page:** [${statusPageName}](${statusPageURL})
|
|
360
|
+
📧 **Manage Subscription:** [Update preferences or unsubscribe](${unsubscribeLink})
|
|
361
|
+
|
|
362
|
+
You will receive real-time notifications for:
|
|
363
|
+
• Incidents and outages
|
|
364
|
+
• Scheduled maintenance events
|
|
365
|
+
• Service announcements
|
|
366
|
+
• Status updates
|
|
367
|
+
|
|
368
|
+
Stay informed about service availability! 🚀`;
|
|
369
|
+
|
|
370
|
+
logger.debug(`Slack Message: ${slackMessage}`);
|
|
371
|
+
|
|
372
|
+
try {
|
|
373
|
+
await SlackUtil.sendMessageToChannelViaIncomingWebhook({
|
|
374
|
+
url: URL.fromString(createdItem.slackIncomingWebhookUrl.toString()),
|
|
375
|
+
text: SlackUtil.convertMarkdownToSlackRichText(slackMessage),
|
|
376
|
+
});
|
|
377
|
+
logger.debug("Slack notification sent successfully.");
|
|
378
|
+
} catch (error) {
|
|
379
|
+
logger.error("Error sending Slack notification:");
|
|
380
|
+
logger.error(error);
|
|
381
|
+
}
|
|
382
|
+
}
|
|
383
|
+
|
|
334
384
|
logger.debug("onCreateSuccess completed.");
|
|
335
385
|
return createdItem;
|
|
336
386
|
}
|
|
@@ -637,6 +687,7 @@ export class Service extends DatabaseService<Model> {
|
|
|
637
687
|
subscriberEmail: true,
|
|
638
688
|
subscriberPhone: true,
|
|
639
689
|
subscriberWebhook: true,
|
|
690
|
+
slackIncomingWebhookUrl: true,
|
|
640
691
|
isSubscribedToAllResources: true,
|
|
641
692
|
statusPageResources: true,
|
|
642
693
|
isSubscribedToAllEventTypes: true,
|
|
@@ -820,5 +871,69 @@ export class Service extends DatabaseService<Model> {
|
|
|
820
871
|
|
|
821
872
|
return statusPages;
|
|
822
873
|
}
|
|
874
|
+
|
|
875
|
+
@CaptureSpan()
|
|
876
|
+
public async testSlackWebhook(data: {
|
|
877
|
+
webhookUrl: string;
|
|
878
|
+
statusPageId: ObjectID;
|
|
879
|
+
}): Promise<void> {
|
|
880
|
+
// Validate the webhook URL
|
|
881
|
+
if (!data.webhookUrl.startsWith("https://hooks.slack.com/services/")) {
|
|
882
|
+
throw new BadDataException("Invalid Slack webhook URL");
|
|
883
|
+
}
|
|
884
|
+
|
|
885
|
+
// Get status page info
|
|
886
|
+
const statusPage: StatusPage | null = await StatusPageService.findOneById({
|
|
887
|
+
id: data.statusPageId,
|
|
888
|
+
props: {
|
|
889
|
+
isRoot: true,
|
|
890
|
+
},
|
|
891
|
+
select: {
|
|
892
|
+
name: true,
|
|
893
|
+
pageTitle: true,
|
|
894
|
+
projectId: true,
|
|
895
|
+
_id: true,
|
|
896
|
+
},
|
|
897
|
+
});
|
|
898
|
+
|
|
899
|
+
if (!statusPage) {
|
|
900
|
+
throw new BadDataException("Status page not found");
|
|
901
|
+
}
|
|
902
|
+
|
|
903
|
+
// Create test notification message
|
|
904
|
+
const statusPageName: string =
|
|
905
|
+
statusPage.pageTitle || statusPage.name || "Status Page";
|
|
906
|
+
const statusPageURL: string = await StatusPageService.getStatusPageURL(
|
|
907
|
+
statusPage.id!,
|
|
908
|
+
);
|
|
909
|
+
|
|
910
|
+
// Create markdown message for Slack
|
|
911
|
+
const markdownMessage: string = `## Test Notification - ${statusPageName}
|
|
912
|
+
|
|
913
|
+
**This is a test notification from OneUptime.**
|
|
914
|
+
|
|
915
|
+
You have successfully configured Slack notifications for this status page.
|
|
916
|
+
|
|
917
|
+
You will receive real-time notifications for:
|
|
918
|
+
- Incidents
|
|
919
|
+
- Scheduled Maintenance Events
|
|
920
|
+
- Status Updates
|
|
921
|
+
- Announcements
|
|
922
|
+
|
|
923
|
+
[View Status Page](${statusPageURL})`;
|
|
924
|
+
|
|
925
|
+
// Send the test notification
|
|
926
|
+
try {
|
|
927
|
+
await SlackUtil.sendMessageToChannelViaIncomingWebhook({
|
|
928
|
+
url: URL.fromString(data.webhookUrl),
|
|
929
|
+
text: SlackUtil.convertMarkdownToSlackRichText(markdownMessage),
|
|
930
|
+
});
|
|
931
|
+
} catch (error) {
|
|
932
|
+
logger.error("Error sending test Slack notification:");
|
|
933
|
+
logger.error(error);
|
|
934
|
+
throw error;
|
|
935
|
+
}
|
|
936
|
+
}
|
|
823
937
|
}
|
|
938
|
+
|
|
824
939
|
export default new Service();
|