Multi-Channel Notification Hub
A centralized notification flow that receives requests via HTTP trigger and dispatches notifications to multiple channels: email, Teams, push notifications, and SMS. Acts as a reusable notification service for other flows.
Provided as-is, without warranty of any kind. Review and test each pattern in a non-production environment before deploying it to live automations. See our Terms.
Overview
Multi-Channel Notification Hub is a reusable notification service that other Power Automate flows can call instead of each one re-implementing its own email, Teams, and push notification logic. The flow exposes an HTTP Request trigger that accepts a JSON payload describing the message (title, body, severity) along with which channels to dispatch on (any combination of email, Teams chat, mobile push, and SMS) and the target recipients for each channel. Once the request lands, the hub parses and validates the payload, fans out to the requested channels in parallel — sending the email via Office 365 Outlook, posting an adaptive card or chat message via Microsoft Teams, firing a push notification to the recipient's mobile Flow app, and (when SMS is requested) calling out to a configured SMS gateway over HTTP — collects per-channel status, then returns a structured HTTP response listing which channels succeeded and which failed. The pattern lets dozens of upstream flows share one well-tested notification path so renderer changes (a new email template, a different Teams card, a swapped SMS provider) only have to be made once.
Use Case
Most organizations end up with a sprawl of notification logic copy-pasted across many flows: every approval flow has its own email template, every alert flow rebuilds its own Teams card, and changing the wording or the Teams channel means hunting through dozens of flows. This hub centralizes that surface: any flow can POST a JSON message to a single URL and the hub takes care of email, Teams, push, and SMS delivery according to the channels the caller requests. It is a good fit for developer / CoE teams that own multiple downstream flows and want a single notification contract to maintain, plus a single place to update branding, retry policy, or compliance logging across every alert the tenant sends.
The flow is ideal for teams that:
- Developer or Center of Excellence teams that own many flows and want a single shared notification contract rather than per-flow notification code.
- Organizations that need consistent branding, formatting, and audit logging across every automated alert (email, Teams, push, SMS).
- Teams that want to swap notification providers (e.g. change SMS gateways) in one place without editing every downstream flow.
- Solutions where the caller wants to specify channels and recipients at runtime — for example, sending a sev-1 alert by email + Teams + SMS, but a sev-3 alert by email only.
Flow Architecture
When an HTTP request is received
When an HTTP request is received (Request)Exposes a webhook URL that other flows or applications POST to. The expected JSON body carries the message metadata (title, body, severity), an array of channels to dispatch on (any of email | teams | push | sms), and per-channel recipient lists (email addresses, user UPNs for Teams and push, phone numbers for SMS).
Initialize tracking variables
Initialize variableInitializes a varDispatchResults array (used to collect per-channel succeeded / failed outcomes for the response) and a varCorrelationId string (a guid stamped into every outbound message and into the final response so callers can trace a notification across channels).
Parse and validate the request payload
Parse JSONParses the trigger body against a schema that enforces required fields (title, body, channels, recipients) and lists allowed channel names. If a required field is missing or a channel name is unknown the flow short-circuits to the failure response action with a 400-style status.
If 'email' is in the requested channels
If conditionChecks whether the parsed channels array contains 'email'. If yes, the hub sends a formatted HTML email to every address in the email recipients list; if no, this branch is skipped.
- Apply to each email recipient — Loops over the emailRecipients array from the request body.
- Send an email V2 (Outlook) — Sends the rendered HTML email to the current recipient using the configured From mailbox, with the title used as the subject and severity baked into the email template.
- Append result to varDispatchResults — Records { channel: 'email', recipient, status: 'sent' or 'failed', error } so the final HTTP response can report per-recipient success.
Environment Variables
| Schema name | Type | Default | Description |
|---|---|---|---|
| flowlibs_NotificationFromMailbox | String | alerts@yourcompany.com | Shared mailbox the email channel sends from. The Office 365 Outlook connection used by the flow must have Send As permission on this mailbox. |
| flowlibs_NotificationEmailTemplateSubjectPrefix | String | [Notification Hub] | Text prepended to the email subject (e.g. '[Notification Hub] Title from caller'). Useful so recipients can filter or rule on hub-sent emails. |
| flowlibs_SmsGatewayUrl | String | <configure> | HTTPS endpoint of your SMS gateway (e.g. Twilio Messages API, Azure Communication Services SMS, or any internal gateway) that the SMS branch POSTs to. Leave the SMS channel out of the request payload if you do not have a gateway configured. |
| flowlibs_SmsGatewayApiKeyHeaderName | String | Authorization | Name of the HTTP header used to pass the API key / bearer token to the SMS gateway. Override per provider (e.g. 'Authorization', 'X-API-Key'). |
| flowlibs_SmsGatewayApiKey | String | <configure> | Secret value placed in the API key header for the SMS gateway. Store this in an environment variable so it can be rotated without editing the flow; for production move it behind Azure Key Vault. |
| flowlibs_AdminAlertEmail | String | alerts@yourcompany.com | Mailbox that receives an alert if every requested channel fails for a given request, so an operator can investigate the underlying connector issue. |
Connectors & Connections
| Connector | API name | Actions used |
|---|---|---|
| Request | shared_request | manual (trigger (When an HTTP request is received)) Response (Returns the per-channel dispatch report) |
| Office 365 Outlook | shared_office365 | SendEmailV2 (Email channel dispatch and admin failure alert) |
| Microsoft Teams | shared_teams | PostCardInAChat (Teams channel — posts an adaptive card to each Teams recipient's 1:1 chat with Flow Bot) |
| Notifications | shared_powerappsnotification | SendNotification (Push channel — sends a mobile push to the recipient's Power Automate app) |
| HTTP | shared_http | HTTP (SMS channel — POSTs each SMS payload to the configured SMS gateway) |
Note — All connections are referenced as solution connection references; the flow is portable between environments as long as a connection is mapped at import time.
Customization Guide
Almost every realistic variant of this flow can be implemented by changing environment variable values. A few cases require small edits inside the flow definition — those are called out explicitly below.
- Add a sharedKey check on the HTTP trigger
- The Request trigger URL is callable by anyone who has the link. Add a Condition immediately after the trigger that compares a 'x-flowlibs-key' header against a flowlibs_NotificationHubSharedKey environment variable, and return HTTP 401 if it does not match, so only authorized upstream flows can dispatch notifications.
- Centralize templates with a switch on severity
- Replace the per-channel inline templates with a Switch action on payload.severity (info / warning / critical) that selects different colours, icons, and email subject prefixes. Lets you change the look of every notification in the tenant from one flow.
- Move recipients to a SharePoint subscription list
- Instead of having every caller pass recipient lists, look up subscribers from a SharePoint list keyed on the message 'topic' (e.g. 'deployments', 'security-alerts'). The caller only specifies topic + channels; the hub resolves the recipients. Easier to manage opt-in/opt-out centrally.
- Add retry + dead-letter for SMS
- Wrap the HTTP-to-SMS-gateway action in a Scope with Retry policy set to exponential, and on Run-After-Failed write the request + correlation id to a Dataverse 'Failed Notifications' table so they can be replayed by an operator.
- Include a tap-through deep link
- Add an optional 'link' field on the request schema and surface it as a button on the Teams adaptive card and the mobile push notification, so a notification about an approval lands the user directly in the approval UI.
Key Expressions
The flow is intentionally light on Power Fx / WDL gymnastics — the heaviest expressions are the branch-name concatenation and the approval outcome check. They are listed below in the order they appear in the flow.
EXPR.01Channel-selection check (email branch)
Used in the If action that gates the email branch. The same pattern (with 'teams', 'push', 'sms') is used for the other three channel branches.
EXPR.02Correlation id
Generated once at the top of the flow and reused in every outbound message (email header, Teams card footer, SMS header, push payload) so a single notification can be traced across all channels.
EXPR.03anyFailures flag for the response
Computed for the final response body so callers can branch on a single boolean instead of scanning the per-recipient array themselves.
EXPR.04SMS body trimmed to gateway limit
Combines title + body and truncates to 160 chars (with an ellipsis when truncated) before POSTing to the SMS gateway, so single-segment SMS pricing is preserved.
Comments
Sign in to join the conversation.
Sign inNo comments yet. Be the first to share your experience with this flow.