[feat] Adding PagerDuty notification
This commit is contained in:
		
							parent
							
								
									35b8e89457
								
							
						
					
					
						commit
						5830f1e0b5
					
				
					 5 changed files with 166 additions and 0 deletions
				
			
		
							
								
								
									
										113
									
								
								server/notification-providers/pagerduty.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										113
									
								
								server/notification-providers/pagerduty.js
									
									
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,113 @@ | |||
| const NotificationProvider = require("./notification-provider"); | ||||
| const axios = require("axios"); | ||||
| const { UP, DOWN, getMonitorRelativeURL } = require("../../src/util"); | ||||
| const { setting } = require("../util-server"); | ||||
| let successMessage = "Sent Successfully."; | ||||
| 
 | ||||
| class PagerDuty extends NotificationProvider { | ||||
|     name = "PagerDuty"; | ||||
| 
 | ||||
|     /** | ||||
|      * @inheritdoc | ||||
|      */ | ||||
|     async send(notification, msg, monitorJSON = null, heartbeatJSON = null) { | ||||
|         try { | ||||
|             if (heartbeatJSON == null) { | ||||
|                 const title = "Uptime Kuma Alert"; | ||||
|                 const monitor = { | ||||
|                     type: "ping", | ||||
|                     url: "Uptime Kuma Test Button", | ||||
|                 }; | ||||
|                 return this.postNotification(notification, title, msg, monitor); | ||||
|             } | ||||
| 
 | ||||
|             if (heartbeatJSON.status === UP) { | ||||
|                 const title = "Uptime Kuma Monitor ✅ Up"; | ||||
|                 const eventAction = notification.pagerdutyAutoResolve || null; | ||||
| 
 | ||||
|                 return this.postNotification(notification, title, heartbeatJSON.msg, monitorJSON, eventAction); | ||||
|             } | ||||
| 
 | ||||
|             if (heartbeatJSON.status === DOWN) { | ||||
|                 const title = "Uptime Kuma Monitor 🔴 Down"; | ||||
|                 return this.postNotification(notification, title, heartbeatJSON.msg, monitorJSON, "trigger"); | ||||
|             } | ||||
|         } catch (error) { | ||||
|             this.throwGeneralAxiosError(error); | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * Check if result is successful, result code should be in range 2xx | ||||
|      * @param {Object} result Axios response object | ||||
|      * @throws {Error} The status code is not in range 2xx | ||||
|      */ | ||||
|     checkResult(result) { | ||||
|         if (result.status == null) { | ||||
|             throw new Error("PagerDuty notification failed with invalid response!"); | ||||
|         } | ||||
|         if (result.status < 200 || result.status >= 300) { | ||||
|             throw new Error("PagerDuty notification failed with status code " + result.status); | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * Send the message | ||||
|      * @param {BeanModel} notification Message title | ||||
|      * @param {string} title Message title | ||||
|      * @param {string} body Message | ||||
|      * @param {Object} monitorInfo Monitor details (For Up/Down only) | ||||
|      * @param {?string} eventAction Action event for PagerDuty (trigger, acknowledge, resolve) | ||||
|      * @returns {string} | ||||
|      */ | ||||
|     async postNotification(notification, title, body, monitorInfo, eventAction = "trigger") { | ||||
| 
 | ||||
|         if (eventAction == null) { | ||||
|             return "No action required"; | ||||
|         } | ||||
| 
 | ||||
|         let monitorUrl; | ||||
|         if (monitorInfo.type === "port") { | ||||
|             monitorUrl = monitorInfo.hostname; | ||||
|             if (monitorInfo.port) { | ||||
|                 monitorUrl += ":" + monitorInfo.port; | ||||
|             } | ||||
|         } else if (monitorInfo.hostname != null) { | ||||
|             monitorUrl = monitorInfo.hostname; | ||||
|         } else { | ||||
|             monitorUrl = monitorInfo.url; | ||||
|         } | ||||
| 
 | ||||
|         const options = { | ||||
|             method: "POST", | ||||
|             url: notification.pagerdutyIntegrationUrl, | ||||
|             headers: { "Content-Type": "application/json" }, | ||||
|             data: { | ||||
|                 payload: { | ||||
|                     summary: `[${title}] [${monitorInfo.name}] ${body}`, | ||||
|                     severity: notification.pagerdutyPriority || "warning", | ||||
|                     source: monitorUrl, | ||||
|                 }, | ||||
|                 routing_key: notification.pagerdutyIntegrationKey, | ||||
|                 event_action: eventAction, | ||||
|                 dedup_key: "Uptime Kuma/" + monitorInfo.id, | ||||
|             } | ||||
|         }; | ||||
| 
 | ||||
|         const baseURL = await setting("primaryBaseURL"); | ||||
|         if (baseURL && monitorInfo) { | ||||
|             options.client = "Uptime Kuma"; | ||||
|             options.client_url = baseURL + getMonitorRelativeURL(monitorInfo.id); | ||||
|         } | ||||
| 
 | ||||
|         let result = await axios.request(options); | ||||
|         this.checkResult(result); | ||||
|         if (result.statusText != null) { | ||||
|             return "PagerDuty notification succeed: " + result.statusText; | ||||
|         } | ||||
| 
 | ||||
|         return successMessage; | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| module.exports = PagerDuty; | ||||
|  | @ -29,6 +29,7 @@ const SerwerSMS = require("./notification-providers/serwersms"); | |||
| const Stackfield = require("./notification-providers/stackfield"); | ||||
| const WeCom = require("./notification-providers/wecom"); | ||||
| const GoogleChat = require("./notification-providers/google-chat"); | ||||
| const PagerDuty = require("./notification-providers/pagerduty"); | ||||
| const Gorush = require("./notification-providers/gorush"); | ||||
| const Alerta = require("./notification-providers/alerta"); | ||||
| const OneBot = require("./notification-providers/onebot"); | ||||
|  | @ -74,6 +75,7 @@ class Notification { | |||
|             new Stackfield(), | ||||
|             new WeCom(), | ||||
|             new GoogleChat(), | ||||
|             new PagerDuty(), | ||||
|             new Gorush(), | ||||
|             new Alerta(), | ||||
|             new OneBot(), | ||||
|  |  | |||
							
								
								
									
										40
									
								
								src/components/notifications/PagerDuty.vue
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										40
									
								
								src/components/notifications/PagerDuty.vue
									
									
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,40 @@ | |||
| <template> | ||||
|     <div class="mb-3"> | ||||
|         <label for="pagerduty-integration-key" class="form-label">{{ $t("Integration Key") }}</label> | ||||
|         <HiddenInput id="pagerduty-integration-key" v-model="$parent.notification.pagerdutyIntegrationKey" :required="true" autocomplete="false"></HiddenInput> | ||||
|         <i18n-t tag="div" keypath="wayToGetPagerDutyKey" class="form-text"> | ||||
|             <a href="https://support.pagerduty.com/docs/services-and-integrations" target="_blank">{{ $t("here") }}</a> | ||||
|         </i18n-t> | ||||
|     </div> | ||||
|     <div class="mb-3"> | ||||
|         <label for="pagerduty-integration-url" class="form-label">{{ $t("Integration URL") }}</label> | ||||
|         <input id="pagerduty-integration-url" v-model="$parent.notification.pagerdutyIntegrationUrl" type="text" class="form-control" autocomplete="false" value="https://events.pagerduty.com/v2/enqueue"> | ||||
|     </div> | ||||
|     <div class="mb-3"> | ||||
|         <label for="pagerduty-priority" class="form-label">{{ $t("Priority") }}</label> | ||||
|         <select id="pagerduty-priority" v-model="$parent.notification.pagerdutyPriority" class="form-select"> | ||||
|             <option value="info">{{ $t("info") }}</option> | ||||
|             <option value="warning" selected="selected">{{ $t("warning") }}</option> | ||||
|             <option value="error">{{ $t("error") }}</option> | ||||
|             <option value="critical">{{ $t("critical") }}</option> | ||||
|         </select> | ||||
|     </div> | ||||
|     <div class="mb-3"> | ||||
|         <label for="pagerduty-resolve" class="form-label">{{ $t("Auto resolve or acknowledged") }}</label> | ||||
|         <select id="pagerduty-resolve" v-model="$parent.notification.pagerdutyAutoResolve" class="form-select"> | ||||
|             <option value="0" selected="selected">{{ $t("do nothing") }}</option> | ||||
|             <option value="acknowledge">{{ $t("auto acknowledged") }}</option> | ||||
|             <option value="resolve">{{ $t("auto resolve") }}</option> | ||||
|         </select> | ||||
|     </div> | ||||
| </template> | ||||
| 
 | ||||
| <script> | ||||
| import HiddenInput from "../HiddenInput.vue"; | ||||
| 
 | ||||
| export default { | ||||
|     components: { | ||||
|         HiddenInput, | ||||
|     }, | ||||
| }; | ||||
| </script> | ||||
|  | @ -27,6 +27,7 @@ import SerwerSMS from "./SerwerSMS.vue"; | |||
| import Stackfield from "./Stackfield.vue"; | ||||
| import WeCom from "./WeCom.vue"; | ||||
| import GoogleChat from "./GoogleChat.vue"; | ||||
| import PagerDuty from "./PagerDuty.vue"; | ||||
| import Gorush from "./Gorush.vue"; | ||||
| import Alerta from "./Alerta.vue"; | ||||
| import OneBot from "./OneBot.vue"; | ||||
|  | @ -67,6 +68,7 @@ const NotificationFormList = { | |||
|     "stackfield": Stackfield, | ||||
|     "WeCom": WeCom, | ||||
|     "GoogleChat": GoogleChat, | ||||
|     "PagerDuty": PagerDuty, | ||||
|     "gorush": Gorush, | ||||
|     "alerta": Alerta, | ||||
|     "OneBot": OneBot, | ||||
|  |  | |||
|  | @ -331,6 +331,8 @@ export default { | |||
|     info: "info", | ||||
|     warning: "warning", | ||||
|     danger: "danger", | ||||
|     error: "error", | ||||
|     critical: "critical", | ||||
|     primary: "primary", | ||||
|     light: "light", | ||||
|     dark: "dark", | ||||
|  | @ -371,6 +373,13 @@ export default { | |||
|     smtpDkimHashAlgo: "Hash Algorithm (Optional)", | ||||
|     smtpDkimheaderFieldNames: "Header Keys to sign (Optional)", | ||||
|     smtpDkimskipFields: "Header Keys not to sign (Optional)", | ||||
|     wayToGetPagerDutyKey: "You can get this by going to Service -> Service Directory -> (Select a service) -> Integrations -> Add integration. Here you can search for \"Events API V2\". More info {0}", | ||||
|     "Integration Key": "Integration Key", | ||||
|     "Integration URL": "Integration URL", | ||||
|     "Auto resolve or acknowledged": "Auto resolve or acknowledged", | ||||
|     "do nothing": "do nothing", | ||||
|     "auto acknowledged": "auto acknowledged", | ||||
|     "auto resolve": "auto resolve", | ||||
|     gorush: "Gorush", | ||||
|     alerta: "Alerta", | ||||
|     alertaApiEndpoint: "API Endpoint", | ||||
|  |  | |||
		Loading…
	
		Reference in a new issue