Stale Contact Cleanup Notification
Monthly flow identifies Salesforce contacts with no activity in 12+ months, sends a cleanup review list to owning sales reps via email with an approval link to confirm keep or archive.
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 runs on a monthly schedule to identify Salesforce contacts that have had no activity in a configurable number of months (default: 12). It compiles the stale contacts into a styled HTML report, routes the list through an approval workflow, and sends the appropriate follow-up email based on whether the reviewer chooses to keep or archive the flagged contacts.
Use Case
Sales teams accumulate contacts over time, many of which become inactive. This flow automates the hygiene process by surfacing stale contacts to a sales manager for review, reducing manual CRM maintenance and keeping the Salesforce database clean. The approval gate ensures no contacts are archived without explicit human review.
Flow Architecture
Monthly Recurrence
RecurrenceFires on the 1st of each month at 8:00 AM EST.
Initialize Variables
Initialize variable (x4 parallel)Sets up varInactivityMonths (bound to flowlibs_StaleContactInactivityMonths env var, default 12), varCleanupRecipient (bound to flowlibs_StaleContactCleanupRecipient env var, default alerts@yourcompany.com), varStaleContactHtml (working string for HTML table rows), and varStaleContactCount (working integer counter).
Get Stale Contacts
Salesforce - GetItems_table_contactQueries the Salesforce contact table with an OData $filter using addToTime() to calculate the cutoff date dynamically, ordered by LastActivityDate asc, top 500.
For Each Stale Contact
Apply to eachIterates results: appends an HTML <tr> with Name, Email, Account, Last Activity Date, and Owner to varStaleContactHtml, then increments varStaleContactCount.
If stale contacts found
If conditionChecks whether varStaleContactCount is greater than 0 before composing and routing the report.
- Compose HTML Report — Builds a styled report with gradient header, stat badge, and a 5-column data table from the accumulated rows.
- Start Cleanup Approval — StartAndWaitForAnApproval (Basic type) assigned to the cleanup recipient with the HTML report as the approval details.
- Check Approval Outcome — Nested condition: if outcome equals 'Approve', sends a confirmation email that all contacts are retained (Keep). Otherwise, sends a high-importance email flagging contacts for archival with the full report attached (Archive).
Environment Variables
| Schema name | Type | Default | Description |
|---|---|---|---|
| flowlibs_StaleContactInactivityMonths | String | 12 | Number of months of inactivity used as the threshold for flagging a Salesforce contact as stale. |
| flowlibs_StaleContactCleanupRecipient | String | alerts@yourcompany.com | Email address of the reviewer who approves whether to keep or archive flagged stale contacts. |
Connectors & Connections
| Connector | API name | Actions used |
|---|---|---|
| Salesforce | shared_salesforce | GetItems_table_contact (queries stale contacts) |
| Office 365 Outlook | shared_office365 | SendEmailV2 (sends keep/archive notifications) |
| Approvals | shared_approvals | StartAndWaitForAnApproval (cleanup review gate) |
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.
- Import the solution
- Import the managed/unmanaged solution into your target Power Platform environment.
- Set environment variable values
- Set flowlibs_StaleContactInactivityMonths to your preferred inactivity threshold (e.g., 6 for 6 months) and flowlibs_StaleContactCleanupRecipient to the email address of the person who should review stale contacts.
- Authorize connections
- Create or authorize connections for Salesforce, Office 365 Outlook, and Approvals.
- Turn on the flow
- Enable the flow - it will then run automatically on its monthly schedule.
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.01Dynamic cutoff date
Calculates the date X months ago for the OData $filter against LastActivityDate.
EXPR.02Null-safe field display
Handles missing contact fields gracefully when rendering the report rows.
EXPR.03Approval outcome check
Routes execution to the keep vs. archive branches based on the reviewer's decision.
Comments
Sign in to join the conversation.
Sign inNo comments yet. Be the first to share your experience with this flow.