SLA Breach Early Warning System
Runs every hour, pulls open Salesforce cases approaching SLA deadlines (within 2 hours of breach), calculates remaining time, and sends escalation alerts to case owners via email and a Teams channel post.
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
This flow proactively monitors open Salesforce Cases that are approaching their SLA deadlines and escalates them before the SLA is breached. It runs on an hourly recurrence, executes a parameterized SOQL query to identify at-risk Cases (those whose SLA_Target_Date__c falls within a configurable breach window), calculates the minutes remaining for each, and sends two escalation touchpoints: (1) a Teams channel post for team visibility, and (2) a coaching email to the Case owner (falling back to a notification mailbox if the owner has no email on record). The flow is fully parameterized via Dataverse environment variables so it can be redeployed to any Salesforce org, Team, or notification mailbox without editing the flow logic.
Use Case
Customer support organizations are accountable to SLA commitments tied to case response and resolution times. Missed SLAs damage customer trust and trigger credits or penalties under support contracts. Most teams rely on dashboards or manual triage reviews that discover breaches *after* they happen. This flow flips the model: every hour it scans the open queue for Cases within a configurable warning window (default 2 hours) of their target date, so owners and managers get a heads-up with enough time to act. The Teams post gives the broader support team situational awareness (a manager can re-assign or escalate), while the email gives the individual case owner actionable context and suggested next steps.
Flow Architecture
Recurrence Every Hour
RecurrenceRuns every 1 hour (Eastern Standard Time). Hourly is a good default for SLA windows of 2-8 hours; tighten to 15 minutes for tighter SLAs or loosen to 4 hours for lower-volume queues.
Init varBreachWindowHours
Initialize variableInteger variable populated from `flowlibs_SalesforceSlaBreachWindowHours` via `int(parameters('...'))`. Controls how far into the future we look for pending SLA deadlines.
Init varCaseStatusFilter
Initialize variableString variable holding the comma-separated list of Case Status values to include (e.g., `New,Working,Escalated`).
Init varTeamsGroupId
Initialize variableTeams Group (Team) ID where escalation alerts are posted.
Init varTeamsChannelId
Initialize variableChannel ID within the Team where escalation alerts are posted.
Init varNotificationEmail
Initialize variableFallback email address used when the Case owner has no email on record.
Compose SlaCutoffIso
ComposeComputes `addHours(utcNow(), varBreachWindowHours)` to build the upper bound for the SOQL window.
Compose StatusSoqlList
ComposeConverts `New,Working,Escalated` into the SOQL-safe quoted list `'New','Working','Escalated'` using `concat("'", replace(..., ',', "','"), "'")`.
Compose SOQLQuery
ComposeConcatenates the final SOQL string pulling `Id, CaseNumber, Subject, Status, Priority, OwnerId, Owner.Name, Owner.Email, Account.Name, CreatedDate, SLA_Target_Date__c` from `Case` with `IsClosed = false`, the status filter, and the `SLA_Target_Date__c` range from `utcNow()` to the cutoff. Results are ordered ascending by SLA target date and capped at 100 rows.
Environment Variables
| Schema name | Type | Default | Description |
|---|---|---|---|
| flowlibs_SalesforceSlaBreachWindowHours | String | 2 | Hours before SLA breach that trigger escalation. Cast to integer via `int(...)` inside the flow. |
| flowlibs_SalesforceCaseStatusFilter | String | New,Working,Escalated | Comma-separated Case Status values included in monitoring. |
| flowlibs_TeamsGroupId | String | <configure> | Teams Group (Team) ID where alerts are posted. Reused across FlowLibs demos. |
| flowlibs_TeamsChannelId | String | <configure> | Channel ID within the Team where alerts are posted. Reused across FlowLibs demos. |
| flowlibs_NotificationEmailAddress | String | alerts@yourcompany.com | Fallback email recipient when `Case.Owner.Email` is null. Reused across FlowLibs demos. |
Connectors & Connections
| Connector | API name | Actions used |
|---|---|---|
| Salesforce | shared_salesforce | ExecuteSOQLQuery |
| Microsoft Teams | shared_teams | PostMessageToConversation |
| Office 365 Outlook | shared_office365 | SendEmailV2 |
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.
- Change the SLA warning window
- Update flowlibs_SalesforceSlaBreachWindowHours default value. Any positive integer works; values between 1 and 24 are typical.
- Include or exclude Case statuses
- Update flowlibs_SalesforceCaseStatusFilter with a comma-separated list (no spaces, no surrounding quotes). Example: New,Working,Escalated,On Hold. The Compose action adds the SOQL quoting at runtime.
- Retarget the Teams destination
- Update flowlibs_TeamsGroupId and flowlibs_TeamsChannelId to the Team/Channel you want alerts posted to. Both IDs can be copied from the Teams channel URL.
- Change the fallback email
- Update flowlibs_NotificationEmailAddress to the mailbox that should receive alerts when the Case owner has no email (e.g., an unassigned-queue owner).
- Change the trigger frequency
- Edit the Recurrence trigger in the designer. For tighter SLAs, set to every 15 or 30 minutes. Keep the recurrence frequency aligned with or shorter than the warning window to avoid missed cases.
- Use a different SLA field
- The SOQL references SLA_Target_Date__c, a common custom field on Case. If your org uses a different field (e.g., Entitlement_Expiration_Date__c or a milestone TargetDate), edit the Compose_SOQLQuery action's expression to reference that field in both the SELECT and WHERE clauses. If you use standard Salesforce Milestones, replace the query with a two-step flow: query CaseMilestone for unfulfilled milestones approaching
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.01SLA cutoff timestamp
Builds the upper bound for the SOQL window by adding the configurable warning hours to the current UTC time.
EXPR.02SOQL-safe status list
Turns the comma-separated env-var value (e.g., `New,Working,Escalated`) into the SOQL-safe quoted list `'New','Working','Escalated'`.
EXPR.03Full SOQL query
Composes the full SOQL string with the dynamic status list and the SLA-target date range; capped at 100 rows.
EXPR.04Minutes remaining to SLA target
Ticks are 100-nanosecond intervals; divide by 600,000,000 to convert to minutes.
EXPR.05Email recipient with owner-email fallback
Sends the coaching email to the Case owner when available; otherwise falls back to the notification mailbox.
EXPR.06Null-safe field access for Account name
Renders cleanly for Cases that have no related Account.
Comments
Sign in to join the conversation.
Sign inNo comments yet. Be the first to share your experience with this flow.