

How to Send Daily Sales Digests from Zoho CRM to Slack with Power Automate
A scheduled Power Automate flow queries Zoho CRM for deal and pipeline data each morning, formats a summary, and posts it to a Slack channel so your sales team starts the day with current numbers.
Steps and UI details are based on platform versions at time of writing — check each platform for the latest interface.
Best for
Sales teams already in the Microsoft 365 ecosystem who want a daily Slack digest of Zoho CRM pipeline metrics without writing code.
Not ideal for
Teams needing real-time deal alerts — use a webhook-triggered flow or Zapier's Zoho CRM instant trigger instead.
Sync type
scheduledUse case type
reportingReal-World Example
A 12-person SaaS sales team runs this flow at 8:00 AM every weekday. Before automation, the sales manager pulled a Zoho CRM report manually each morning, copied numbers into Slack, and the team still had stale data by 9 AM. Now the digest posts automatically to #sales-daily with open deal count, total pipeline value, deals closing this week, and top rep by new revenue — zero manual effort.
What Will This Cost?
Drag the slider to your expected monthly volume.
Each platform counts differently — Zapier: 1 task per trigger. Make: 1 operation per module per record. n8n: 1 execution per run.





Prices shown for annual billing. Based on published pricing as of April 2026.
Estimated ROI
1000
min saved/mo
$583
labor value/mo
Free
no platform cost
Based on ~2 min manual effort per operation at $35/hr fully loaded labor cost.
Implementation
Import this workflow directly into Power Automate
Copy the pre-built Power Automate blueprint and paste it straight into Power Automate. All modules, filters, and field mappings are already configured — you just need to connect your accounts.
Before You Start
Make sure you have everything ready.
Field Mapping
Map these fields between your apps.
| Field | API Name | |
|---|---|---|
| Required | ||
| Deal Name | Deal_Name | |
| Amount | Amount | |
| Stage | Stage | |
| Closing Date | Closing_Date | |
4 optional fields▸ show
| Owner Name | Owner.name |
| Account Name | Account_Name |
| Probability | Probability |
| Modified Time | Modified_Time |
Step-by-Step Setup
make.powerautomate.com > + Create > Scheduled cloud flow
Create a Scheduled Cloud Flow
Go to make.powerautomate.com and sign in. Click '+ Create' in the left sidebar, then select 'Scheduled cloud flow'. Name the flow something specific like 'Zoho CRM Daily Sales Digest'. Set the recurrence to every 1 day at your preferred send time — 8:00 AM works well for most teams. This flow type runs on a timer, not an event, which is exactly right for a digest.
- 1Click '+ Create' in the left sidebar
- 2Select 'Scheduled cloud flow'
- 3Enter a flow name: 'Zoho CRM Daily Sales Digest'
- 4Set 'Starting' to today's date and your target send time (e.g. 8:00 AM)
- 5Set 'Repeat every' to 1 Day, then click 'Create'
Flow canvas > + New step > Search 'Zoho CRM' > Search Records
Connect Your Zoho CRM Account
Click '+ New step' below the Recurrence trigger. In the search bar type 'Zoho CRM' and select the Zoho CRM connector. Choose the action 'Search Records'. A connection panel will appear — click 'Sign in' and authenticate with your Zoho CRM admin credentials. Power Automate stores this as a named Connection reusable across flows.
- 1Click '+ New step'
- 2Type 'Zoho CRM' in the connector search bar
- 3Select the 'Zoho CRM' connector from results
- 4Choose action: 'Search Records'
- 5Click 'Sign in' and complete OAuth with your Zoho admin account
Flow canvas > Search Records action > Module / Criteria fields
Query Open Deals from Zoho CRM
In the 'Search Records' action, set Module to 'Deals'. In the Criteria field, enter a COQL-style filter to pull only open deals: Stage not equal to 'Closed Won' and Stage not equal to 'Closed Lost'. Set Max Records to 200 to capture your full active pipeline. This single query returns the raw deal list you'll summarize in the next steps.
- 1Set 'Module Name' dropdown to 'Deals'
- 2In 'Criteria', enter: ((Stage:equals:not:Closed Won)and(Stage:equals:not:Closed Lost))
- 3Set 'Max Records' to 200
- 4Leave 'Sort By' as default (Modified Time descending)
Flow canvas > + New step > Built-in > Variables > Initialize variable
Initialize Variables for Digest Metrics
Add three 'Initialize variable' actions after the search step — one for each metric you want in the digest. Name them: TotalPipelineValue (Float, initial value 0), OpenDealCount (Integer, initial value 0), and DealsClosingThisWeek (Integer, initial value 0). Keeping metrics in named variables makes the Slack message step much cleaner to build. Add each variable as a separate action block.
- 1Click '+ New step', search 'Initialize variable', select it
- 2Set Name: TotalPipelineValue, Type: Float, Value: 0
- 3Add another 'Initialize variable': Name: OpenDealCount, Type: Integer, Value: 0
- 4Add a third 'Initialize variable': Name: DealsClosingThisWeek, Type: Integer, Value: 0
Flow canvas > + New step > Control > Apply to each
Loop Through Deals and Calculate Metrics
Add an 'Apply to each' control action. Set the input to the body/records output from the 'Search Records' step — use the dynamic content picker and select 'Records'. Inside the loop, add 'Increment variable' for OpenDealCount by 1 each iteration. Add another 'Increment variable' for TotalPipelineValue using the Amount dynamic field from the current deal. Add a Condition block to check if Closing_Date is within the next 7 days, and if true, increment DealsClosingThisWeek by 1.
- 1Click '+ New step', select 'Control', then 'Apply to each'
- 2In 'Select an output from previous steps', pick 'Records' from Search Records dynamic content
- 3Inside the loop, add 'Increment variable' → Name: OpenDealCount, Value: 1
- 4Add 'Increment variable' → Name: TotalPipelineValue, Value: Amount (dynamic content from current item)
- 5Add a 'Condition': formatDateTime(items('Apply_to_each')?['Closing_Date'], 'yyyy-MM-dd') is less than or equal to formatDateTime(addDays(utcNow(), 7), 'yyyy-MM-dd')
- 6In the 'Yes' branch, add 'Increment variable' → Name: DealsClosingThisWeek, Value: 1
Flow canvas > + New step > Built-in > Data Operation > Compose
Compose the Digest Message Text
Add a 'Compose' action after the Apply to each loop. This is where you build the Slack message string. Use Power Automate expressions to embed your variable values inline. Write the message body directly in the Inputs field, mixing plain text with dynamic content tokens. Format the TotalPipelineValue as currency using the formatNumber expression so it reads as $1,234,500 rather than 1234500.
- 1Click '+ New step', search 'Compose', select 'Data Operation > Compose'
- 2In the Inputs field, click in the text area
- 3Type the message structure, inserting dynamic content tokens for each variable
- 4Wrap TotalPipelineValue with expression: concat('$', formatNumber(variables('TotalPipelineValue'), 'N0'))
- 5Preview the full message text before moving to the next step
Flow canvas > + New step > Search 'Slack' > Post message (V2)
Connect Your Slack Workspace
Add a new step and search for the 'Slack' connector. Select the action 'Post message (V2)'. Click 'Sign in' to create a Slack connection — this opens an OAuth window where you authorize Power Automate to post to your workspace. You need to be a Slack workspace admin or have permission to install apps. Once connected, your workspace name appears in the Connection label.
- 1Click '+ New step', type 'Slack' in the search bar
- 2Select the 'Slack' connector
- 3Choose action 'Post message (V2)'
- 4Click 'Sign in' and complete Slack OAuth in the popup window
- 5Grant the requested permissions and click 'Allow'
Flow canvas > Post message (V2) > Channel Name / Message Text
Configure the Slack Post Action
In the 'Post message (V2)' action, set the Channel Name to the target channel — type the channel name directly (e.g. #sales-daily) or select it from the dropdown. For Message Text, use the dynamic content picker and select 'Outputs' from the Compose step. This passes your fully formatted digest string to Slack. Leave all other fields at their defaults.
- 1Click the 'Channel Name' field and select or type your target channel (e.g. #sales-daily)
- 2Click the 'Message Text' field
- 3Open dynamic content and select 'Outputs' from the Compose step
- 4Leave 'Bot username' and 'Icon URL' blank unless overriding appearance
Flow canvas > Action menu (...) > Configure run after
Add Error Handling with a Parallel Branch
Click the three-dot menu ('...') on the Post message action and select 'Configure run after'. You can also add a Scope action around steps 2–8 and add a parallel branch that runs only on failure. In the failure branch, add a second Slack post to a #ops-alerts channel with the error message using the expression: outputs('Post_message_(V2)')?['statusCode']. This ensures silent failures don't go unnoticed.
- 1Click the '...' menu on the 'Post message' action
- 2Select 'Configure run after'
- 3Check 'has failed' and 'has timed out' checkboxes
- 4Add a new Slack 'Post message' action in the failure path targeting #ops-alerts
- 5Set its message to: concat('Daily digest failed. Error: ', outputs('Post_message_(V2)')?['statusCode'])
Flow canvas > Save > Test > Manually > Run flow
Test the Flow End-to-End
Click 'Save' in the top right, then click 'Test' and choose 'Manually'. Power Automate runs the flow immediately regardless of the schedule. Watch each step turn green as it completes. Check the Outputs of the Search Records step to confirm real Zoho deals came back. Check the Compose step output to confirm the message looks right. Then verify the Slack channel received the post.
- 1Click 'Save' in the top toolbar
- 2Click 'Test' (beaker icon)
- 3Select 'Manually' and click 'Run flow'
- 4Watch the run detail page — each step shows green (success) or red (failure)
- 5Open your Slack channel and confirm the digest message arrived
My flows > [Flow Name] > Run history
Turn On the Flow and Verify First Scheduled Run
Click the back arrow to exit the editor. On the flow detail page, confirm the toggle shows 'On'. Power Automate displays the next scheduled run time at the top of the page — verify it matches the time and timezone you intend. Check back after the first scheduled run by clicking 'Run history' to see whether it succeeded or failed. A successful run shows a green checkmark with the timestamp.
- 1Exit the editor using the back arrow
- 2Confirm the flow status toggle is set to 'On'
- 3Note the 'Next run' time displayed on the flow detail page
- 4After the first scheduled run, click '28 day run history' to review results
- 5Open the run detail to inspect individual step outputs if anything looks off
Paste this expression block into a Power Automate 'Compose' action placed after your Apply to each loop. It calculates weighted pipeline value inline using a single expression rather than a separate loop variable, and formats the final digest string with all metrics in one step. Use the output of this Compose action as the Message Text in your Slack post action.
JavaScript — Code Step// Power Automate Expression — paste into Compose action Inputs field▸ Show code
// Power Automate Expression — paste into Compose action Inputs field // Calculates weighted pipeline and formats the full digest string concat(
... expand to see full code
// Power Automate Expression — paste into Compose action Inputs field
// Calculates weighted pipeline and formats the full digest string
concat(
'📊 Sales Digest — ', formatDateTime(utcNow(), 'ddd MMM d'), decodeUriComponent('%0A'),
'Open Deals: ', string(variables('OpenDealCount')), decodeUriComponent('%0A'),
'Total Pipeline: $', formatNumber(variables('TotalPipelineValue'), 'N0'), decodeUriComponent('%0A'),
'Closing This Week: ', string(variables('DealsClosingThisWeek')), decodeUriComponent('%0A'),
decodeUriComponent('%0A'),
'📅 Next run: ', formatDateTime(addDays(utcNow(), 1), 'ddd MMM d, h:mm tt')
)
// Weighted pipeline — use this as a separate Compose or variable
// Place AFTER the Apply to each loop, reference WeightedTotal variable
// Initialize WeightedTotal as Float = 0 alongside your other variables
// Inside loop, increment with:
// mul(float(items('Apply_to_each')?['Amount']), div(float(if(empty(items('Apply_to_each')?['Probability']), '0', items('Apply_to_each')?['Probability'])), 100))Scaling Beyond 200+ open deals in Zoho CRM pipeline+ Records
If your volume exceeds 200+ open deals in Zoho CRM pipeline records, apply these adjustments.
Raise the Max Records cap
The Zoho CRM Search Records action defaults to 200 records. If your team carries more than 200 open deals, set Max Records to 2000 — the connector supports it. Beyond 2000, you'll need to paginate using the 'Page' parameter and loop through multiple Search Records calls, incrementing the page number until the result count drops below your page size.
Avoid per-deal API calls inside the loop
Each action inside Apply to each that makes an API call (like a secondary Get Record for owner details) counts as a separate Power Automate action run and a separate Zoho API call. On a 500-deal pipeline this costs 500+ extra runs and risks Zoho's API rate limit (5000 API calls/day on Professional plan). Pull all needed fields in the initial Search Records query using the Fields parameter.
Aggregate on the Zoho side, not Power Automate
For large pipelines, consider using Zoho Analytics or Zoho CRM's built-in Reports to pre-aggregate metrics, then query the report output via the Zoho Analytics connector instead of raw deal records. This returns one summary row instead of 500 individual deal rows — faster flow execution and zero loop overhead.
Going live
Production Checklist
Before you turn this on for real, confirm each item.
Troubleshooting
Common errors and how to fix them.
Frequently Asked Questions
Common questions about this workflow.
Analysis
Use Power Automate for this if your team already pays for Microsoft 365 and your IT policy restricts third-party automation tools. The Zoho CRM and Slack connectors exist, authentication is handled through your Microsoft account, and admins can manage the flow centrally in the Power Automate admin center. It also works well if you want to post the digest to both Slack and Microsoft Teams from the same flow — add a second branch and a Teams connector action in under 5 minutes. Pick a different platform if your team has no Microsoft licenses; you'll pay $15/user/month just for premium connector access, which makes Make or Zapier cheaper for a standalone digest workflow.
The cost math on Power Automate is straightforward but easy to underestimate. A per-user plan is $15/month and covers one user's flows. This digest runs once daily — 30 runs/month. Each run consumes roughly 200–600 action executions depending on deal count (1 recurrence + 1 search + 3 variable inits + N loop iterations + 1 compose + 1 Slack post). At 200 deals per run, that's ~207 actions × 30 runs = 6,210 actions/month. Per-user plans include 40,000 actions/month, so you're well within limits. The per-flow plan at $100/month is overkill for a single digest. By comparison, Make handles the same workflow on the $9/month Core plan with 10,000 operations — cheaper by $6/month if this is your only automation.
Make's Zoho CRM module has one real edge here: it supports COQL (Zoho Query Language) natively in its Search Records module, which gives you more expressive filtering than Power Automate's connector criteria syntax. Zapier's Zoho CRM integration supports a 'Find Record' search trigger but requires a workaround with Formatter steps to aggregate metrics — it's not designed for batch math. n8n handles this cleanly with a Zoho CRM node plus a Code node for JavaScript aggregation, and it's self-hosted so there's no per-action cost. Pipedream gives you full Node.js with Zoho's REST API directly, which is the most flexible option if you need complex digest logic. Power Automate wins here specifically when the decision-maker is an IT department that already controls Microsoft licenses and wants governance over automation tools — not when a developer is choosing freely.
Three things you'll hit after setup. First, Zoho CRM's API returns Amount as a float but occasionally returns null for deals with no amount entered — your TotalPipelineValue will corrupt silently if you don't add a null check (use the if/empty expression pattern described in Step 5). Second, the Power Automate Slack connector does not support Slack Block Kit — you get plain text only. If your team wants rich Slack formatting with buttons or sections, you'll need to switch to the HTTP action and call the Slack Web API directly using a Bot Token, which adds setup complexity. Third, if your Zoho CRM org is on a data center region other than US (EU or AU), the Power Automate connector may fail to authenticate until you update the connection's base URL in the connector settings — this is a known issue not documented in the connector's help page.
Ideas for what to build next
- →Add a Weekly Pipeline Trend Digest — Clone this flow, change the Recurrence to weekly (Monday 8 AM), and add a second Zoho CRM Search Records query filtered to deals created in the past 7 days. Post both the current snapshot and the week-over-week change to give the team a trend view, not just a point-in-time count.
- →Post Per-Rep Breakdowns to Individual DMs — Extend the flow with a second Apply to each loop that groups deals by Owner.name, then uses the Slack 'Send direct message' action to post each rep's personal numbers directly to their DMs. Reps see only their pipeline; managers see the full channel digest.
- →Log Each Digest Run to a SharePoint List — Add a SharePoint 'Create item' action at the end of the flow to write the digest metrics (date, open deal count, pipeline value, closing this week) to a SharePoint list row. After 30 runs you'll have a queryable history of pipeline trends without buying a BI tool.
Related guides
How to Share Notion Meeting Notes to Slack with Pipedream
~15 min setup
How to Share Notion Meeting Notes to Slack with Power Automate
~15 min setup
How to Share Notion Meeting Notes to Slack with n8n
~20 min setup
How to Send Notion Meeting Notes to Slack with Zapier
~8 min setup
How to Share Notion Meeting Notes to Slack with Make
~12 min setup
How to Create Notion Tasks from Slack with Pipedream
~15 min setup