mirror of
https://github.com/louislam/uptime-kuma.git
synced 2026-01-31 11:03:11 +08:00
feat(notification): add Jira Service Management as a notification provider (#6830)
This commit is contained in:
105
server/notification-providers/jira-service-management.js
Normal file
105
server/notification-providers/jira-service-management.js
Normal file
@@ -0,0 +1,105 @@
|
||||
const NotificationProvider = require("./notification-provider");
|
||||
const axios = require("axios");
|
||||
const { UP, DOWN } = require("../../src/util");
|
||||
|
||||
const okMsg = "Sent Successfully.";
|
||||
|
||||
class JiraServiceManagement extends NotificationProvider {
|
||||
name = "JiraServiceManagement";
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
async send(notification, msg, monitorJSON = null, heartbeatJSON = null) {
|
||||
const priority = notification.jsmPriority || 3;
|
||||
const baseUrl = `https://api.atlassian.com/jsm/ops/api/${notification.jsmCloudId}/v1`;
|
||||
const textMsg = "Uptime Kuma Alert";
|
||||
|
||||
try {
|
||||
if (heartbeatJSON == null) {
|
||||
// Test notification
|
||||
let notificationTestAlias = "uptime-kuma-notification-test";
|
||||
let data = {
|
||||
message: msg,
|
||||
alias: notificationTestAlias,
|
||||
source: "Uptime Kuma",
|
||||
priority: "P5",
|
||||
tags: ["Uptime Kuma"],
|
||||
};
|
||||
|
||||
return this.post(notification, `${baseUrl}/alerts`, data);
|
||||
}
|
||||
|
||||
if (heartbeatJSON.status === DOWN) {
|
||||
let data = {
|
||||
message: monitorJSON ? `${textMsg}: ${monitorJSON.name}` : textMsg,
|
||||
alias: monitorJSON.name,
|
||||
description: msg,
|
||||
source: "Uptime Kuma",
|
||||
priority: `P${priority}`,
|
||||
tags: ["Uptime Kuma"],
|
||||
};
|
||||
|
||||
return this.post(notification, `${baseUrl}/alerts`, data);
|
||||
}
|
||||
|
||||
if (heartbeatJSON.status === UP) {
|
||||
// JSM requires getting the alert ID first, then closing by ID
|
||||
const getUrl = `${baseUrl}/alerts/alias?alias=${encodeURIComponent(monitorJSON.name)}`;
|
||||
const config = this.getConfig(notification);
|
||||
|
||||
let alertResponse = await axios.get(getUrl, config);
|
||||
const alertId = alertResponse.data.id;
|
||||
|
||||
const closeUrl = `${baseUrl}/alerts/${alertId}/close`;
|
||||
let data = {
|
||||
source: "Uptime Kuma",
|
||||
};
|
||||
|
||||
return this.post(notification, closeUrl, data);
|
||||
}
|
||||
} catch (error) {
|
||||
this.throwGeneralAxiosError(error);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get axios config with Basic Auth for JSM
|
||||
* @param {BeanModel} notification Notification details
|
||||
* @returns {object} Axios config object
|
||||
*/
|
||||
getConfig(notification) {
|
||||
const authToken = Buffer.from(`${notification.jsmEmail}:${notification.jsmApiToken}`).toString("base64");
|
||||
let config = {
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
Accept: "application/json",
|
||||
Authorization: `Basic ${authToken}`,
|
||||
},
|
||||
};
|
||||
return this.getAxiosConfigWithProxy(config);
|
||||
}
|
||||
|
||||
/**
|
||||
* Make POST request to Jira Service Management
|
||||
* @param {BeanModel} notification Notification to send
|
||||
* @param {string} url Request url
|
||||
* @param {object} data Request body
|
||||
* @returns {Promise<string>} Success message
|
||||
*/
|
||||
async post(notification, url, data) {
|
||||
let config = this.getConfig(notification);
|
||||
|
||||
let res = await axios.post(url, data, config);
|
||||
if (res.status == null) {
|
||||
return "Jira Service Management notification failed with invalid response!";
|
||||
}
|
||||
if (res.status < 200 || res.status >= 300) {
|
||||
return `Jira Service Management notification failed with status code ${res.status}`;
|
||||
}
|
||||
|
||||
return okMsg;
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = JiraServiceManagement;
|
||||
@@ -36,6 +36,7 @@ const Octopush = require("./notification-providers/octopush");
|
||||
const OneChat = require("./notification-providers/onechat");
|
||||
const OneBot = require("./notification-providers/onebot");
|
||||
const Opsgenie = require("./notification-providers/opsgenie");
|
||||
const JiraServiceManagement = require("./notification-providers/jira-service-management");
|
||||
const PagerDuty = require("./notification-providers/pagerduty");
|
||||
const Pumble = require("./notification-providers/pumble");
|
||||
const FlashDuty = require("./notification-providers/flashduty");
|
||||
@@ -138,6 +139,7 @@ class Notification {
|
||||
new OneBot(),
|
||||
new Onesender(),
|
||||
new Opsgenie(),
|
||||
new JiraServiceManagement(),
|
||||
new PagerDuty(),
|
||||
new FlashDuty(),
|
||||
new PagerTree(),
|
||||
|
||||
@@ -292,6 +292,7 @@ export default {
|
||||
HeiiOnCall: "Heii On-Call",
|
||||
Keep: "Keep",
|
||||
Opsgenie: "Opsgenie",
|
||||
JiraServiceManagement: this.$t("Jira Service Management"),
|
||||
PagerDuty: "PagerDuty",
|
||||
PagerTree: "PagerTree",
|
||||
SIGNL4: "SIGNL4",
|
||||
|
||||
58
src/components/notifications/JiraServiceManagement.vue
Normal file
58
src/components/notifications/JiraServiceManagement.vue
Normal file
@@ -0,0 +1,58 @@
|
||||
<template>
|
||||
<div class="mb-3">
|
||||
<label for="jsm-cloud-id" class="form-label">
|
||||
{{ $t("Cloud ID") }}
|
||||
<span style="color: red"><sup>*</sup></span>
|
||||
</label>
|
||||
<input id="jsm-cloud-id" v-model="$parent.notification.jsmCloudId" type="text" class="form-control" required />
|
||||
<i18n-t tag="p" keypath="aboutJiraCloudId" style="margin-top: 8px">
|
||||
<a href="https://support.atlassian.com/jira/kb/retrieve-my-atlassian-sites-cloud-id/" target="_blank">
|
||||
{{ $t("see Jira Cloud Docs") }}
|
||||
</a>
|
||||
</i18n-t>
|
||||
</div>
|
||||
<div class="mb-3">
|
||||
<label for="jsm-email" class="form-label">
|
||||
{{ $t("Email") }}
|
||||
<span style="color: red"><sup>*</sup></span>
|
||||
</label>
|
||||
<input id="jsm-email" v-model="$parent.notification.jsmEmail" type="email" class="form-control" required />
|
||||
</div>
|
||||
<div class="mb-3">
|
||||
<label for="jsm-api-token" class="form-label">
|
||||
{{ $t("API Token") }}
|
||||
<span style="color: red"><sup>*</sup></span>
|
||||
</label>
|
||||
<HiddenInput
|
||||
id="jsm-api-token"
|
||||
v-model="$parent.notification.jsmApiToken"
|
||||
required="true"
|
||||
autocomplete="false"
|
||||
></HiddenInput>
|
||||
</div>
|
||||
<div class="mb-3">
|
||||
<label for="jsm-priority" class="form-label">{{ $t("Priority") }}</label>
|
||||
<input
|
||||
id="jsm-priority"
|
||||
v-model="$parent.notification.jsmPriority"
|
||||
type="number"
|
||||
class="form-control"
|
||||
min="1"
|
||||
max="5"
|
||||
step="1"
|
||||
/>
|
||||
</div>
|
||||
<div class="form-text">
|
||||
<span style="color: red"><sup>*</sup></span>
|
||||
{{ $t("Required") }}
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import HiddenInput from "../HiddenInput.vue";
|
||||
export default {
|
||||
components: {
|
||||
HiddenInput,
|
||||
},
|
||||
};
|
||||
</script>
|
||||
@@ -36,6 +36,7 @@ import OneChat from "./OneChat.vue";
|
||||
import OneBot from "./OneBot.vue";
|
||||
import Onesender from "./Onesender.vue";
|
||||
import Opsgenie from "./Opsgenie.vue";
|
||||
import JiraServiceManagement from "./JiraServiceManagement.vue";
|
||||
import PagerDuty from "./PagerDuty.vue";
|
||||
import FlashDuty from "./FlashDuty.vue";
|
||||
import PagerTree from "./PagerTree.vue";
|
||||
@@ -126,6 +127,7 @@ const NotificationFormList = {
|
||||
OneBot: OneBot,
|
||||
Onesender: Onesender,
|
||||
Opsgenie: Opsgenie,
|
||||
JiraServiceManagement: JiraServiceManagement,
|
||||
PagerDuty: PagerDuty,
|
||||
FlashDuty: FlashDuty,
|
||||
PagerTree: PagerTree,
|
||||
|
||||
@@ -441,8 +441,11 @@
|
||||
"RadiusCallingStationId": "Calling Station Id",
|
||||
"RadiusCallingStationIdDescription": "Identifier of the calling device",
|
||||
"Certificate Expiry Notification": "Certificate Expiry Notification",
|
||||
"Cloud ID": "Cloud ID",
|
||||
"API Username": "API Username",
|
||||
"API Key": "API Key",
|
||||
"API Token": "API Token",
|
||||
"See Jira Cloud Docs": "See Jira Cloud Docs",
|
||||
"Show update if available": "Show update if available",
|
||||
"Also check beta release": "Also check beta release",
|
||||
"Using a Reverse Proxy?": "Using a Reverse Proxy?",
|
||||
@@ -856,6 +859,9 @@
|
||||
"Icon Emoji": "Icon Emoji",
|
||||
"signalImportant": "IMPORTANT: You cannot mix groups and numbers in recipients!",
|
||||
"aboutWebhooks": "More info about Webhooks on: {0}",
|
||||
"aboutJiraCloudId": "More info about Jira Cloud ID: {0}",
|
||||
"see Jira Cloud Docs": "see Jira Cloud Docs",
|
||||
"Jira Service Management": "Jira Service Management",
|
||||
"aboutSlackUsername": "Changes the display name of the message sender. If you want to mention someone, include it in the friendly name instead.",
|
||||
"aboutChannelName": "Enter the channel name on {0} Channel Name field if you want to bypass the Webhook channel. Ex: #other-channel",
|
||||
"aboutKumaURL": "If you leave the Uptime Kuma URL field blank, it will default to the Project GitHub page.",
|
||||
|
||||
Reference in New Issue
Block a user