mirror of
https://github.com/rcourtman/Pulse.git
synced 2026-10-16 00:52:27 +00:00
349 lines
11 KiB
TypeScript
349 lines
11 KiB
TypeScript
import type { WebhookTemplate as AlertWebhookTemplate } from '@/api/notifications';
|
|
|
|
type AlertWebhookService =
|
|
| 'generic'
|
|
| 'discord'
|
|
| 'slack'
|
|
| 'mattermost'
|
|
| 'telegram'
|
|
| 'teams'
|
|
| 'teams-adaptive'
|
|
| 'pagerduty'
|
|
| 'pushover'
|
|
| 'gotify'
|
|
| 'ntfy';
|
|
|
|
type AlertWebhookServicePresentation = {
|
|
label: string;
|
|
mentionPlaceholder?: string;
|
|
mentionHelp?: string;
|
|
};
|
|
|
|
type AlertWebhookCustomFieldPreset = {
|
|
key: string;
|
|
label: string;
|
|
placeholder?: string;
|
|
required?: boolean;
|
|
};
|
|
|
|
export interface AlertWebhookCustomFieldInput {
|
|
key: string;
|
|
value: string;
|
|
label?: string;
|
|
placeholder?: string;
|
|
required?: boolean;
|
|
}
|
|
|
|
const ALERT_WEBHOOK_SERVICE_PRESENTATION: Record<
|
|
AlertWebhookService,
|
|
AlertWebhookServicePresentation
|
|
> = {
|
|
generic: {
|
|
label: 'Generic',
|
|
},
|
|
discord: {
|
|
label: 'Discord',
|
|
mentionPlaceholder: '@everyone or <@USER_ID> or <@&ROLE_ID>',
|
|
mentionHelp: 'Discord: Use @everyone, @here, <@USER_ID>, or <@&ROLE_ID>',
|
|
},
|
|
slack: {
|
|
label: 'Slack',
|
|
mentionPlaceholder: '@channel, @here, or <@USER_ID>',
|
|
mentionHelp: 'Slack: Use @channel, @here, <@USER_ID>, or <!subteam^ID>',
|
|
},
|
|
mattermost: {
|
|
label: 'Mattermost',
|
|
mentionPlaceholder: '@channel, @all, or @username',
|
|
mentionHelp: 'Mattermost: Use @channel, @all, or @username',
|
|
},
|
|
telegram: {
|
|
label: 'Telegram',
|
|
},
|
|
teams: {
|
|
label: 'Microsoft Teams',
|
|
mentionPlaceholder: '@General or user email',
|
|
mentionHelp: 'Teams: Use channel names like @General',
|
|
},
|
|
'teams-adaptive': {
|
|
label: 'Teams (Adaptive)',
|
|
mentionPlaceholder: '@General or user email',
|
|
mentionHelp: 'Teams: Use channel names like @General',
|
|
},
|
|
pagerduty: {
|
|
label: 'PagerDuty',
|
|
},
|
|
pushover: {
|
|
label: 'Pushover',
|
|
},
|
|
gotify: {
|
|
label: 'Gotify',
|
|
},
|
|
ntfy: {
|
|
label: 'ntfy',
|
|
},
|
|
};
|
|
|
|
const ALERT_WEBHOOK_CUSTOM_FIELD_PRESETS: Partial<
|
|
Record<string, readonly AlertWebhookCustomFieldPreset[]>
|
|
> = {
|
|
pushover: [
|
|
{
|
|
key: 'token',
|
|
label: 'Application Token',
|
|
placeholder: 'Your Pushover application token',
|
|
required: true,
|
|
},
|
|
{
|
|
key: 'user',
|
|
label: 'User Key',
|
|
placeholder: 'Primary user key or group key',
|
|
required: true,
|
|
},
|
|
],
|
|
};
|
|
|
|
export const ALERT_WEBHOOK_SETUP_INSTRUCTIONS_TITLE = 'Setup Instructions';
|
|
export const ALERT_WEBHOOK_NAME_PLACEHOLDER = 'My Webhook';
|
|
export const ALERT_WEBHOOK_URL_PLACEHOLDER = 'https://example.com/webhook';
|
|
export const ALERT_WEBHOOK_URL_HELP_TEMPLATE_VARIABLE = '{{.Message}}';
|
|
export const ALERT_WEBHOOK_URL_HELP_PATH = '{{urlpath ...}}';
|
|
export const ALERT_WEBHOOK_URL_HELP_QUERY = '{{urlquery ...}}';
|
|
export const ALERT_WEBHOOK_MENTION_HELP_LABEL = 'Optional — tag users or groups';
|
|
export const ALERT_WEBHOOK_MENTION_FALLBACK_PLACEHOLDER = '@everyone';
|
|
export const ALERT_WEBHOOK_PAYLOAD_HELP_LABEL = 'Optional — leave empty to use default';
|
|
export const ALERT_WEBHOOK_PAYLOAD_TEMPLATE_PLACEHOLDER = `{
|
|
"text": "Alert: {{.Level}} - {{.Message}}",
|
|
"resource": "{{.ResourceName}}",
|
|
"value": {{.Value}},
|
|
"threshold": {{.Threshold}}
|
|
}`;
|
|
export const ALERT_WEBHOOK_PAYLOAD_VARIABLES =
|
|
'{{.ID}}, {{.Level}}, {{.Type}}, {{.ResourceName}}, {{.Node}}, {{.Message}}, {{.Value}}, {{.Threshold}}, {{.Duration}}, {{.Timestamp}}';
|
|
export const ALERT_WEBHOOK_CUSTOM_FIELDS_HELP = 'Available as';
|
|
export const ALERT_WEBHOOK_CUSTOM_FIELDS_REFERENCE = '{{.CustomFields.<name>}}';
|
|
export const ALERT_WEBHOOK_CUSTOM_FIELD_KEY_PLACEHOLDER = 'Field name';
|
|
export const ALERT_WEBHOOK_CUSTOM_FIELD_VALUE_PLACEHOLDER = 'Value';
|
|
export const ALERT_WEBHOOK_CUSTOM_FIELD_REMOVE_LABEL = 'Remove';
|
|
export const ALERT_WEBHOOK_CUSTOM_FIELD_ADD_LABEL = '+ Add custom field';
|
|
export const ALERT_WEBHOOK_CUSTOM_FIELDS_PUSHHOVER_HELP =
|
|
'Need Pushover? Provide your Application Token and User Key here.';
|
|
export const ALERT_WEBHOOK_HEADERS_HELP_LABEL = 'Add authentication tokens or custom headers';
|
|
export const ALERT_WEBHOOK_HEADER_KEY_PLACEHOLDER = 'Header name';
|
|
export const ALERT_WEBHOOK_HEADER_VALUE_PLACEHOLDER = 'Header value';
|
|
export const ALERT_WEBHOOK_HEADER_REMOVE_LABEL = 'Remove';
|
|
export const ALERT_WEBHOOK_HEADER_ADD_LABEL = '+ Add header';
|
|
export const ALERT_WEBHOOK_HEADER_HELP =
|
|
'Common headers: Authorization (Bearer token), X-API-Key, X-Auth-Token';
|
|
export const ALERT_WEBHOOK_ENABLE_LABEL = 'Enable this webhook';
|
|
export const ALERT_WEBHOOK_CANCEL_LABEL = 'Cancel';
|
|
export const ALERT_WEBHOOK_TEST_LABEL = 'Test';
|
|
export const ALERT_WEBHOOK_TESTING_LABEL = 'Testing…';
|
|
export const ALERT_WEBHOOK_TESTING_ASCII_LABEL = 'Testing...';
|
|
export const ALERT_WEBHOOK_TEST_SUCCESS = 'Test webhook sent successfully!';
|
|
export const ALERT_WEBHOOK_TEST_FAILURE = 'Failed to send test webhook';
|
|
export const ALERT_WEBHOOKS_SECTION_TITLE = 'Webhooks';
|
|
export const ALERT_WEBHOOKS_SECTION_DESCRIPTION = 'Push alerts to chat apps or automation systems.';
|
|
export const ALERT_WEBHOOK_ADD_SUCCESS = 'Webhook added successfully';
|
|
export const ALERT_WEBHOOK_ADD_FAILURE = 'Failed to add webhook';
|
|
export const ALERT_WEBHOOK_UPDATE_SUCCESS = 'Webhook updated successfully';
|
|
export const ALERT_WEBHOOK_UPDATE_FAILURE = 'Failed to update webhook';
|
|
export const ALERT_WEBHOOK_DELETE_SUCCESS = 'Webhook deleted successfully';
|
|
export const ALERT_WEBHOOK_DELETE_FAILURE = 'Failed to delete webhook';
|
|
export const ALERT_WEBHOOK_ADD_LABEL = 'Add Webhook';
|
|
export const ALERT_WEBHOOK_UPDATE_LABEL = 'Update Webhook';
|
|
export const ALERT_WEBHOOK_EDIT_LABEL = 'Edit';
|
|
export const ALERT_WEBHOOK_DELETE_LABEL = 'Delete';
|
|
export const ALERT_WEBHOOK_ENABLED_LABEL = 'Enabled';
|
|
export const ALERT_WEBHOOK_DISABLED_LABEL = 'Disabled';
|
|
export const ALERT_WEBHOOK_DISABLE_ALL_LABEL = 'Disable All';
|
|
export const ALERT_WEBHOOK_ENABLE_ALL_LABEL = 'Enable All';
|
|
|
|
export function getAlertWebhookServices(templates: AlertWebhookTemplate[] = []) {
|
|
return templates.map((template) => ({
|
|
id: template.service,
|
|
label: template.label || getAlertWebhookServiceLabel(template.service),
|
|
description: template.description || template.name,
|
|
}));
|
|
}
|
|
|
|
export function getAlertWebhookServiceLabel(service: string) {
|
|
return ALERT_WEBHOOK_SERVICE_PRESENTATION[service as AlertWebhookService]?.label || service;
|
|
}
|
|
|
|
export function getAlertWebhookServiceLabelFromTemplates(
|
|
service: string,
|
|
templates: AlertWebhookTemplate[] = [],
|
|
) {
|
|
const template = templates.find((item) => item.service === service);
|
|
if (template?.label?.trim()) {
|
|
return template.label.trim();
|
|
}
|
|
return getAlertWebhookServiceLabel(service);
|
|
}
|
|
|
|
export function getAlertWebhookMentionPlaceholderFromTemplates(
|
|
service: string,
|
|
templates: AlertWebhookTemplate[] = [],
|
|
) {
|
|
const template = templates.find((item) => item.service === service);
|
|
return template?.mentionPlaceholder?.trim() || ALERT_WEBHOOK_MENTION_FALLBACK_PLACEHOLDER;
|
|
}
|
|
|
|
export function getAlertWebhookMentionHelpFromTemplates(
|
|
service: string,
|
|
templates: AlertWebhookTemplate[] = [],
|
|
) {
|
|
const template = templates.find((item) => item.service === service);
|
|
return template?.mentionHelp?.trim() || '';
|
|
}
|
|
|
|
export function hasAlertWebhookMentionSupportFromTemplates(
|
|
service: string,
|
|
templates: AlertWebhookTemplate[] = [],
|
|
) {
|
|
const template = templates.find((item) => item.service === service);
|
|
return Boolean(template?.mentionPlaceholder?.trim() || template?.mentionHelp?.trim());
|
|
}
|
|
|
|
export function getAlertWebhookCustomFieldPresets(service: string) {
|
|
return ALERT_WEBHOOK_CUSTOM_FIELD_PRESETS[service.trim().toLowerCase()];
|
|
}
|
|
|
|
export function getAlertWebhookCustomFieldInputs(
|
|
service: string,
|
|
existing: Record<string, string> = {},
|
|
): AlertWebhookCustomFieldInput[] {
|
|
const presets = getAlertWebhookCustomFieldPresets(service);
|
|
const normalizedExisting = normalizeAlertWebhookCustomFields(service, existing);
|
|
|
|
if (!presets) {
|
|
return Object.entries(normalizedExisting).map(([key, value]) => ({
|
|
key,
|
|
value,
|
|
}));
|
|
}
|
|
|
|
const inputs: AlertWebhookCustomFieldInput[] = presets.map((preset) => ({
|
|
key: preset.key,
|
|
value: normalizedExisting[preset.key] ?? '',
|
|
label: preset.label,
|
|
placeholder: preset.placeholder,
|
|
required: preset.required,
|
|
}));
|
|
|
|
Object.entries(normalizedExisting)
|
|
.filter(([key]) => !presets.some((preset) => preset.key === key))
|
|
.forEach(([key, value]) => {
|
|
inputs.push({
|
|
key,
|
|
value,
|
|
});
|
|
});
|
|
|
|
return inputs;
|
|
}
|
|
|
|
export function normalizeAlertWebhookCustomFields(
|
|
service: string,
|
|
fields: Record<string, string> = {},
|
|
) {
|
|
if (service.trim().toLowerCase() !== 'pushover') {
|
|
return { ...fields };
|
|
}
|
|
|
|
const normalized = { ...fields };
|
|
if (!normalized.token?.trim() && normalized.app_token?.trim()) {
|
|
normalized.token = normalized.app_token;
|
|
}
|
|
if (!normalized.user?.trim() && normalized.user_token?.trim()) {
|
|
normalized.user = normalized.user_token;
|
|
}
|
|
delete normalized.app_token;
|
|
delete normalized.user_token;
|
|
return normalized;
|
|
}
|
|
|
|
export function getAlertWebhookSetupInstructionsTitle() {
|
|
return ALERT_WEBHOOK_SETUP_INSTRUCTIONS_TITLE;
|
|
}
|
|
|
|
export function getAlertWebhookNamePlaceholder(templateName?: string) {
|
|
return templateName || ALERT_WEBHOOK_NAME_PLACEHOLDER;
|
|
}
|
|
|
|
export function getAlertWebhookUrlPlaceholder(urlPattern?: string) {
|
|
return urlPattern || ALERT_WEBHOOK_URL_PLACEHOLDER;
|
|
}
|
|
|
|
export function getAlertWebhookMentionPlaceholder(service: string) {
|
|
return (
|
|
ALERT_WEBHOOK_SERVICE_PRESENTATION[service as AlertWebhookService]?.mentionPlaceholder ||
|
|
ALERT_WEBHOOK_MENTION_FALLBACK_PLACEHOLDER
|
|
);
|
|
}
|
|
|
|
export function getAlertWebhookMentionHelp(service: string) {
|
|
return ALERT_WEBHOOK_SERVICE_PRESENTATION[service as AlertWebhookService]?.mentionHelp || '';
|
|
}
|
|
|
|
export function getAlertWebhookSummaryLabel(enabledCount: number, totalCount: number) {
|
|
return `${enabledCount} of ${totalCount} webhooks enabled`;
|
|
}
|
|
|
|
export function getAlertWebhookToggleAllLabel(enabled: boolean) {
|
|
return enabled ? ALERT_WEBHOOK_ENABLE_ALL_LABEL : ALERT_WEBHOOK_DISABLE_ALL_LABEL;
|
|
}
|
|
|
|
export function getAlertWebhookToggleLabel(enabled: boolean) {
|
|
return enabled ? ALERT_WEBHOOK_ENABLED_LABEL : ALERT_WEBHOOK_DISABLED_LABEL;
|
|
}
|
|
|
|
export function getAlertWebhookTestLabel(isTesting: boolean, ascii = false) {
|
|
if (!isTesting) {
|
|
return ALERT_WEBHOOK_TEST_LABEL;
|
|
}
|
|
return ascii ? ALERT_WEBHOOK_TESTING_ASCII_LABEL : ALERT_WEBHOOK_TESTING_LABEL;
|
|
}
|
|
|
|
export function getAlertWebhookSubmitLabel(isEditing: boolean) {
|
|
return isEditing ? ALERT_WEBHOOK_UPDATE_LABEL : ALERT_WEBHOOK_ADD_LABEL;
|
|
}
|
|
|
|
export function getAlertWebhookTestSuccess() {
|
|
return ALERT_WEBHOOK_TEST_SUCCESS;
|
|
}
|
|
|
|
export function getAlertWebhookTestFailure() {
|
|
return ALERT_WEBHOOK_TEST_FAILURE;
|
|
}
|
|
|
|
export function getAlertWebhooksSectionTitle() {
|
|
return ALERT_WEBHOOKS_SECTION_TITLE;
|
|
}
|
|
|
|
export function getAlertWebhooksSectionDescription() {
|
|
return ALERT_WEBHOOKS_SECTION_DESCRIPTION;
|
|
}
|
|
|
|
export function getAlertWebhookMutationSuccess(action: 'add' | 'update' | 'delete') {
|
|
switch (action) {
|
|
case 'add':
|
|
return ALERT_WEBHOOK_ADD_SUCCESS;
|
|
case 'update':
|
|
return ALERT_WEBHOOK_UPDATE_SUCCESS;
|
|
default:
|
|
return ALERT_WEBHOOK_DELETE_SUCCESS;
|
|
}
|
|
}
|
|
|
|
export function getAlertWebhookMutationFailure(action: 'add' | 'update' | 'delete') {
|
|
switch (action) {
|
|
case 'add':
|
|
return ALERT_WEBHOOK_ADD_FAILURE;
|
|
case 'update':
|
|
return ALERT_WEBHOOK_UPDATE_FAILURE;
|
|
default:
|
|
return ALERT_WEBHOOK_DELETE_FAILURE;
|
|
}
|
|
}
|