Intermediate~20 min setupCommunication & CRMVerified April 2026
Slack logo
Zoho CRM logo

How to Send Zoho CRM Follow-up Reminders to Slack with n8n

Polls Zoho CRM on a schedule, finds tasks and activities due today or overdue, and sends a direct Slack message to the assigned sales rep.

Steps and UI details are based on platform versions at time of writing — check each platform for the latest interface.

Best for

Sales teams where reps own specific CRM records and need a daily push notification in Slack when follow-up tasks are due.

Not ideal for

Teams using Zoho CRM's built-in notification emails — duplicate reminders will frustrate reps; disable the native ones first.

Sync type

scheduled

Use case type

notification

Real-World Example

💡

A 12-person SaaS sales team runs this workflow every morning at 8 AM and again at 1 PM. Before it existed, reps missed follow-up tasks until they happened to open Zoho CRM — roughly 30% of tasks slipped past their due date each week. Now each rep gets a Slack DM listing exactly which accounts need a call or email that day, with a direct link to the Zoho record.

What Will This Cost?

Drag the slider to your expected monthly volume.

/mo
505005K50K

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

Skip the setup

Import this workflow directly into n8n

Copy the pre-built n8n blueprint and paste it straight into n8n. 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.

Zoho CRM account with API access enabled and an OAuth app created in the Zoho API Console (Client ID + Client Secret required)
Zoho CRM user must have permission to read Activities and Users — 'CRM Administrator' or a custom profile with API read access to both modules
Slack workspace with a bot app that has the scopes: users:read, users:read.email, chat:write, and im:write — all required to look up users by email and send DMs
n8n instance (cloud or self-hosted v1.0+) with the Zoho CRM and Slack nodes available — both are built-in, no additional installation needed
All sales reps must use the same email address in both Zoho CRM (as their user profile email) and in Slack — mismatches will cause the user lookup to fail silently

Field Mapping

Map these fields between your apps.

FieldAPI Name
Required
Task SubjectSubject
Due DateDue_Date
Task StatusStatus
Task Owner IDOwner.id
Related Contact / Lead NameWho_Id.name
Related Contact IDWho_Id.id
Task Record IDid
3 optional fields▸ show
Task Owner NameOwner.name
Activity TypeActivity_Type
Description / NotesDescription

Step-by-Step Setup

1

n8n Dashboard > Workflows > New workflow

Create a new n8n workflow

Log into your n8n instance (cloud at app.n8n.cloud or self-hosted). Click the orange 'New workflow' button in the top-right corner of the Workflows list. Give it a clear name like 'Zoho CRM Follow-up Reminders → Slack'. You'll land on a blank canvas with a single '+' node in the center.

  1. 1Click 'New workflow' in the top-right corner
  2. 2Click the pencil icon next to 'My workflow' and rename it to 'Zoho CRM Follow-up Reminders → Slack'
  3. 3Click the '+' node in the center of the canvas to open the node picker
What you should see: You should see a blank canvas with the node search panel open on the right side.
2

Canvas > Node Picker > Schedule Trigger

Add a Schedule trigger

Search for 'Schedule Trigger' in the node picker and select it. Set the trigger to run at 8:00 AM and 1:00 PM local time on weekdays — use the 'Cron' mode and enter two separate cron expressions. The morning run catches overnight-due tasks; the afternoon run catches anything added that morning. Make sure your n8n instance timezone matches your sales team's timezone, set under Settings > Personal > Timezone.

  1. 1Search 'Schedule Trigger' and click to add it
  2. 2Set Mode to 'Custom (Cron)'
  3. 3Enter '0 8 * * 1-5' for the 8 AM weekday trigger
  4. 4Click 'Add Rule' and enter '0 13 * * 1-5' for the 1 PM run
  5. 5Click 'Save' to confirm
What you should see: The Schedule Trigger node shows two cron rules listed below the mode selector.
Common mistake — n8n evaluates cron expressions in the server's timezone, not your browser's. If your n8n instance runs on UTC and your team is in US/Eastern, adjust the cron hour accordingly — 8 AM Eastern = '0 13 * * 1-5' in UTC.
n8n
+
click +
search apps
Slack
SL
Slack
Add a Schedule trigger
Slack
SL
module added
3

Canvas > + > Zoho CRM > Credentials > Create New

Connect Zoho CRM credentials

Add a 'Zoho CRM' node after the Schedule Trigger. Click 'Create New Credential' in the credential dropdown. n8n uses OAuth2 for Zoho CRM — you'll need to register an app in the Zoho API Console first to get a Client ID and Client Secret. Set the redirect URI in Zoho's console to the URL n8n shows you in the credential dialog before clicking Connect.

  1. 1Click '+' after the Schedule Trigger node
  2. 2Search 'Zoho CRM' and select the node
  3. 3Click the Credential dropdown and select 'Create New Credential'
  4. 4Copy the OAuth redirect URL from n8n
  5. 5Paste that URL into your Zoho API Console app settings, then copy the Client ID and Secret back into n8n
  6. 6Click 'Connect my account' and approve access in the Zoho popup
What you should see: The credential field shows your Zoho account name with a green checkmark next to it.
Common mistake — Zoho's API Console has data center options (US, EU, IN, AU, CN). Pick the one matching your Zoho CRM account region — mismatching regions causes a silent auth failure where the OAuth popup succeeds but API calls return 401.
4

Zoho CRM Node > Resource: Activity > Operation: Get All

Fetch due tasks from Zoho CRM

Configure the Zoho CRM node to search for Activities (Tasks) due today or earlier. Set Resource to 'Activity', Operation to 'Get All', and add a Search Criteria filter. Use the COQL query approach by switching to 'Search By Criteria' and filtering where Due_Date is less than or equal to today and Status is not equal to 'Completed'. Set Return All to true so you get every matching task, not just the first page.

  1. 1Set Resource to 'Activity'
  2. 2Set Operation to 'Get All'
  3. 3Toggle 'Return All' to true
  4. 4Under Filters, add criterion: Due_Date <= {{$today}}
  5. 5Add second criterion: Status != Completed
  6. 6Click 'Execute Node' to test
What you should see: The node output panel shows a list of task objects, each with fields like Subject, Due_Date, Owner, and Who_Id visible in the JSON.
Common mistake — Zoho CRM's Activity API returns tasks, calls, and meetings in the same endpoint. If you only want Tasks, add a third filter: Activity_Type = Task — otherwise call reminders will also fire and reps will get confused.
5

Canvas > + > Code Node > JavaScript

Deduplicate with a Code node

Add a Code node after the Zoho CRM fetch. This is where n8n earns its place — you'll track which task IDs have already been notified using n8n's static data store so reps don't get the same reminder twice per day. The code checks each task ID against a stored set, passes only new ones through, then updates the stored set. Paste the code from the pro tip section below into the JavaScript editor.

  1. 1Click '+' after the Zoho CRM node and search 'Code'
  2. 2Select 'Run Once for All Items'
  3. 3Paste the deduplication script into the JavaScript editor
  4. 4Click 'Execute Node' to test — on first run, all tasks pass through
What you should see: Output items contain only tasks that haven't been notified yet in the current day. On a clean run you'll see all tasks; on a second run within the same day, the output should be empty if no new tasks were added.
Common mistake — n8n's static data persists across executions but resets if you redeploy the workflow or update the workflow definition. Add a daily cleanup step (or reset the stored set at midnight) to prevent stale IDs from blocking legitimate next-day reminders.

This Code node runs deduplication using n8n's built-in static data store and also flags overdue tasks with a warning emoji. Paste it into the Code node set to 'Run Once for All Items', placed immediately after the Zoho CRM fetch node.

JavaScript — Code Node// Deduplication + overdue flag for Zoho CRM follow-up reminders
▸ Show code
// Deduplication + overdue flag for Zoho CRM follow-up reminders
// Paste into Code node > Run Once for All Items
const staticData = $getWorkflowStaticData('global');

... expand to see full code

// Deduplication + overdue flag for Zoho CRM follow-up reminders
// Paste into Code node > Run Once for All Items

const staticData = $getWorkflowStaticData('global');

// Initialize the notified set and reset it daily
const today = new Date().toISOString().split('T')[0];
if (staticData.lastRunDate !== today) {
  staticData.notifiedTaskIds = [];
  staticData.lastRunDate = today;
}

const notifiedIds = new Set(staticData.notifiedTaskIds || []);
const outputItems = [];

for (const item of $input.all()) {
  const task = item.json;
  const taskId = task.id;

  // Skip already-notified tasks
  if (notifiedIds.has(taskId)) {
    continue;
  }

  // Flag overdue tasks
  const dueDate = new Date(task.Due_Date);
  const todayDate = new Date(today);
  const isOverdue = dueDate < todayDate;

  outputItems.push({
    json: {
      ...task,
      isOverdue,
      overdueLabel: isOverdue ? ' ⚠️ Overdue' : '',
      taskId,
    }
  });

  notifiedIds.add(taskId);
}

// Persist updated set back to static data
staticData.notifiedTaskIds = [...notifiedIds];

return outputItems;
6

Canvas > + > Zoho CRM > Resource: User > Operation: Get

Look up the Zoho user's email

The task Owner field in Zoho returns an object with an ID and name, but Slack needs an email address to find the right user. Add another Zoho CRM node configured to get the User record by the owner ID extracted from each task. Set Resource to 'User', Operation to 'Get', and pass in the Owner.id from the previous node using an expression.

  1. 1Add a new Zoho CRM node after the Code node
  2. 2Set Resource to 'User'
  3. 3Set Operation to 'Get'
  4. 4Set User ID field to expression: {{ $json.Owner.id }}
  5. 5Click 'Execute Node' to confirm the user record returns an Email field
What you should see: The node output shows a user object containing Email, Full_Name, and Profile fields for the task owner.
7

Canvas > + > Slack > Resource: User > Operation: Get By Email

Look up the Slack user by email

Add a Slack node configured to look up a Slack user by their email address. This maps the Zoho CRM owner email to a Slack user ID, which is required to send a DM. Set Resource to 'User', Operation to 'Get By Email', and pass the email from the previous step. The output will include the user's Slack ID in the id field.

  1. 1Add a Slack node and connect your Slack credentials
  2. 2Set Resource to 'User'
  3. 3Set Operation to 'Get By Email'
  4. 4Set Email to expression: {{ $json.Email }}
  5. 5Click 'Execute Node' — confirm the output shows a Slack user id field
What you should see: The node output shows a Slack user object with fields including id (starts with 'U'), name, and tz.
Common mistake — If a rep's Zoho CRM email doesn't match their Slack workspace email, this lookup returns a 'users_not_found' error. Run a one-time audit comparing Zoho owner emails to Slack member emails before going to production.
8

Canvas > + > Set Node

Format the reminder message

Add a Set node to assemble the Slack message text before sending. Build a clear, actionable message that includes the task subject, the contact or deal name it's linked to, the due date, and a direct link to the Zoho CRM record. Use Slack's mrkdwn format for bold and links. This node outputs a single 'message' field that the Slack send node will consume.

  1. 1Add a Set node after the Slack user lookup
  2. 2Add a field named 'message' with type String
  3. 3Set the value to an expression combining task fields — e.g.: *Follow-up Due:* {{ $('Zoho CRM').item.json.Subject }}\n*Contact:* {{ $('Zoho CRM').item.json.Who_Id.name }}\n*Due:* {{ $('Zoho CRM').item.json.Due_Date }}\n<https://crm.zoho.com/crm/org{your_org_id}/tab/Activities/{{ $('Zoho CRM').item.json.id }}|Open in Zoho CRM>
  4. 4Add a field named 'slack_user_id' set to {{ $('Slack').item.json.id }}
  5. 5Click 'Execute Node' and verify the message field looks correct
What you should see: The Set node output shows a 'message' field with formatted text and a 'slack_user_id' field starting with 'U'.
Common mistake — Zoho CRM record URLs include your org ID, which is a number visible in your Zoho CRM browser URL. Hard-code it in the link expression — it doesn't change.
9

Canvas > + > Slack > Resource: Message > Operation: Send

Send the Slack DM to the rep

Add a final Slack node configured to send a message. Set Resource to 'Message', Operation to 'Send'. Set Channel to the slack_user_id field from the Set node — sending to a user ID creates a direct message automatically, no channel needed. Set Text to the message field. Enable 'As User' if you want the message to appear from your bot rather than the default n8n app.

  1. 1Add a Slack node and use the same credentials from step 7
  2. 2Set Resource to 'Message'
  3. 3Set Operation to 'Send'
  4. 4Set Channel to expression: {{ $json.slack_user_id }}
  5. 5Set Text to expression: {{ $json.message }}
  6. 6Click 'Execute Node' — check your Slack DM inbox for the test message
What you should see: You receive a Slack DM from your n8n Slack app with the formatted follow-up reminder. The message shows the task name, contact, due date, and a working Zoho link.
10

Node Settings > Continue on Fail | Workflow > Add Error Trigger

Add error handling

Click the three-dot menu on the Zoho CRM fetch node and select 'Settings'. Enable 'Continue on Fail' so a single bad task record doesn't stop the entire batch. Do the same for both Slack nodes. Add an Error Trigger node as a separate branch at the workflow level — connect it to a Slack node that posts failures to a #automation-errors channel so your team knows when a reminder silently failed.

  1. 1Right-click each Zoho CRM and Slack node and select 'Settings'
  2. 2Enable 'Continue on Fail' on each node
  3. 3Click the '+' outside the main flow to add an Error Trigger node
  4. 4Connect it to a Slack node targeting your #automation-errors channel
  5. 5Set the error message to include {{ $json.error.message }} and the workflow name
What you should see: The canvas shows two separate flows: the main reminder chain and a separate error-handling branch starting from the Error Trigger node.
11

Canvas > Activate toggle (top right) | Workflow > Executions

Activate and verify

Click the toggle in the top-right of the canvas to activate the workflow. Wait for the next scheduled run or click 'Execute Workflow' manually to trigger it immediately. Open the Executions tab to confirm the run shows green for all nodes. Check a rep's Slack DMs to confirm they received the message with the correct task details and a working link.

  1. 1Click the gray toggle in the top-right corner — it should turn green and show 'Active'
  2. 2Click 'Execute Workflow' to trigger a manual test run
  3. 3Open the 'Executions' tab and click the most recent run
  4. 4Click through each node to confirm green status and check the output data
  5. 5Verify the Slack DM arrived in the correct rep's inbox
What you should see: The Executions tab shows a completed run with all nodes green. The assigned rep has a Slack DM with the correct task and a clickable Zoho CRM link.
Common mistake — Activating the workflow on a Monday morning when there are 50+ overdue tasks will fire 50 Slack DMs at once. Run a test on a quiet day first, or add a limit node to cap the first production run to 5 records.

Scaling Beyond 100+ due tasks per run+ Records

If your volume exceeds 100+ due tasks per run records, apply these adjustments.

1

Add a Limit node for the first week

On your first production runs, cap the output of the Zoho CRM fetch node using an n8n Limit node set to 20 records. This prevents a backlog of 100+ overdue tasks from flooding every rep's Slack inbox on day one. Remove the limit after a week once reps are caught up.

2

Watch Zoho API rate limits

Zoho CRM allows 5,000 API calls per day on most plans and 200 calls per minute. Each workflow run uses roughly 3 API calls per task (fetch, user lookup, status check). At 100 tasks, that's 300 calls per run — fine for 2 daily runs, but tight if you add more triggers. Monitor your API usage in Zoho's Developer Console.

3

Batch Slack sends with a Wait node

If you have 50+ tasks in a single run, add an n8n Wait node set to 500ms between each Slack send. Slack's rate limit is 1 message per second per channel — sending DMs too fast in bulk can trigger a 429 error that silently drops messages. The Wait node keeps you under the limit.

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

VerdictWhy n8n for this workflow

Use n8n for this if your team self-hosts or wants to avoid per-task pricing. Every Zoho CRM task check and every Slack DM is an operation — on Make or Zapier those add up fast at volume. n8n's flat pricing (or free self-hosted tier) means you can run this twice a day against 50 tasks and pay nothing extra. The second reason to pick n8n here is the Code node: deduplication across runs and overdue flagging require stateful logic that you can't do cleanly in a no-code platform. The one scenario where you'd skip n8n: if your team has zero technical comfort and needs this running in 20 minutes without touching a terminal. Use Zapier for that.

Cost

The math is straightforward. Each workflow run touches roughly 3 nodes per task: the Zoho fetch (one call for all tasks), the user lookup (one call per task), and the Slack send (one call per task). For 30 tasks twice a day, that's about 1,860 node executions per month. On n8n cloud, the Starter plan ($20/month) includes 2,500 executions — you're fine. Self-hosted n8n is $0 beyond server costs, typically $5-10/month on a small VPS. On Zapier, 30 tasks twice daily = 1,800 Zap runs/month, which costs $49/month on the Professional plan. That's a $40/month difference for the same workflow.

Tradeoffs

Make handles scheduled polling for Zoho CRM more visually than n8n — the scenario builder makes the fetch-then-notify chain easier to understand for non-technical reviewers. Zapier has a native Zoho CRM integration that sets up faster, but it can't deduplicate across runs without a Zapier Storage step (an add-on). Power Automate has deep Microsoft 365 integration but its Zoho CRM connector is community-built and unreliable — avoid it here. Pipedream's Zoho CRM component is well-maintained and would work, but its free tier has execution limits that bite at twice-daily schedules with 30+ tasks. n8n wins for this specific workflow because stateful deduplication in a Code node plus flat pricing is the right combination for a batch notification job.

Three things you'll hit after setup. First: Zoho CRM's OAuth token expires after 60 minutes by default, but n8n handles the refresh automatically only if you granted offline_access scope during credential setup. If you skipped that scope, the workflow fails silently every hour. Recreate the credential with offline_access. Second: Zoho returns the Due_Date as a string in YYYY-MM-DD format without timezone info — if your n8n server runs on UTC and your team is in US/Eastern, tasks due at midnight Eastern show up a day early in UTC. Normalize dates explicitly in the Code node. Third: Slack's im:write scope is required to DM users but is not included in the default n8n Slack app manifest — you have to add it manually in your Slack app settings at api.slack.com/apps before the DM send step will work.

Ideas for what to build next

  • Add a daily digest for managersExtend the workflow to also post a summary to a #sales-followups Slack channel at 8 AM showing all reps' due tasks for the day. Managers get visibility without needing to log into Zoho CRM.
  • Mark tasks complete from SlackAdd Slack Block Kit buttons to each reminder message — a 'Mark Complete' button triggers a second n8n workflow via webhook that updates the task Status to 'Completed' in Zoho CRM without the rep opening the browser.
  • Escalate tasks overdue by 48+ hoursAdd an IF node that checks the Due_Date age — tasks overdue by more than 2 days trigger a separate Slack message to the rep's manager in addition to the rep, flagging it as a stale follow-up.

Related guides

Was this guide helpful?
Slack + Zoho CRM overviewn8n profile →