Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
45 changes: 45 additions & 0 deletions src/lib/server/notifications.ts
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,8 @@ async function sendToAppriseUrl(url: string, payload: NotificationPayload): Prom
case 'json':
case 'jsons':
return await sendGenericWebhook(url, payload);
case 'workflows':
return await sendWorkflows(url, payload);
default:
console.warn(`[Notifications] Unsupported Apprise protocol: ${protocol}`);
return false;
Expand Down Expand Up @@ -318,6 +320,49 @@ async function sendGenericWebhook(appriseUrl: string, payload: NotificationPaylo

return response.ok;
}
// Microsoft Power Automate Workflows, for e.g. Microsoft Teams
async function sendWorkflows(appriseUrl: string, payload: NotificationPayload): Promise<boolean> {
// workflows://hostname/workflow/signature
const match = appriseUrl.match(/^workflows?:\/\/([^/]+)\/(.+)\/(.+)/);
if (!match) return false;

const [, hostname, workflow, signature] = match;
const url = `https://${hostname}/powerautomate/automations/direct/workflows/${workflow}/triggers/manual/paths/invoke?api-version=1&sp=%2Ftriggers%2Fmanual%2Frun&sv=1.0&sig=${signature}`;

const response = await fetch(url, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
type: 'message',
attachments: [
{
contentType: 'application/vnd.microsoft.card.adaptive',
content: {
$schema: 'https://adaptivecards.io/schemas/adaptive-card.json',
type: 'AdaptiveCard',
version: '1.2',
body: [
{
type: 'TextBlock',
style: 'heading',
wrap: true,
text: payload.title
},
{
type: 'TextBlock',
style: 'default',
wrap: true,
text: payload.message
}
]
}
}
]
})
});

return response.ok;
}

// Send notification to all enabled channels
export async function sendNotification(payload: NotificationPayload): Promise<{ success: boolean; results: { name: string; success: boolean }[] }> {
Expand Down
3 changes: 2 additions & 1 deletion src/routes/settings/notifications/NotificationModal.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -417,11 +417,12 @@ slack://token_a/token_b/token_c
tgram://bot_token/chat_id
ntfy://my-topic
pushover://user_key/api_token
workflows://hostname/workflow/signature
jsons://hostname/webhook/path"
class="flex min-h-[220px] w-full rounded-md border border-input bg-transparent px-3 py-2 text-sm shadow-sm placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring"
></textarea>
<p class="text-xs text-muted-foreground">
Supports Gotify (gotify:// or gotifys:// for HTTPS), Discord, Slack, Telegram, ntfy, Pushover, and generic JSON webhooks.
Supports Gotify (gotify:// or gotifys:// for HTTPS), Discord, Slack, Telegram, ntfy, Pushover, Workflows (for e.g. Microsoft Teams), and generic JSON webhooks.
</p>
</div>
</div>
Expand Down