How to Use n8n with ._Template 76 Daily Sales Standup Slack
Your sales team is scattered across three time zones, and every morning the same ritual plays out: someone pings the group asking "what did everyone close yesterday?", a few reps answer, most don't, a
Your sales team is scattered across three time zones, and every morning the same ritual plays out: someone pings the group asking "what did everyone close yesterday?", a few reps answer, most don't, and by 9:15 the standup has decayed into a half-remembered Slack thread nobody scrolls back to. The pipeline numbers your VP quotes in the leadership meeting are stale by the time they're spoken. Template 76 — Daily Sales Standup Slack — exists to kill that ritual and replace it with a single automated message that posts the same structured update, sourced from your CRM, at the same time every day.
The problem: standups don't scale, but the data does
Manual sales standups fail for a predictable reason. They depend on humans remembering to report, formatting their update consistently, and doing it before the day's noise buries the ask. Multiply that by ten reps and five working days and you get a compliance rate that trends toward zero. Meanwhile, every number you actually want — deals closed, calls booked, revenue moved, deals slipping — already lives in your CRM. The gap isn't data. It's the manual translation layer between the CRM and the channel where your team already lives.
The cost of that gap compounds. Managers spend the first hour of the day assembling a picture that the system could assemble in two seconds. Reps context-switch out of selling to write a status. And leadership makes decisions on a lagging, self-reported snapshot instead of ground truth. What you want is a standup that runs whether or not anyone remembers it — one that reads directly from the source and posts a clean, identical format every morning.
The solution: a scheduled n8n workflow that turns CRM data into one Slack message
Template 76 is an n8n workflow that fires on a schedule, pulls the previous day's sales activity from your CRM, aggregates it into a leaderboard and a pipeline summary, and posts a formatted message to a dedicated Slack channel. No human touches it. The reps read it; the manager reads it; the standup becomes a five-minute conversation about the numbers instead of a scramble to produce them.
The architecture is deliberately simple, which is what makes it reliable: a Schedule Trigger node sets the cadence, a CRM node (HubSpot, Pipedrive, or Salesforce) pulls the raw records, a Code or Set node reshapes them into totals and per-rep breakdowns, and a Slack node delivers the result using Block Kit formatting. Everything runs on your own n8n instance, so your CRM credentials and pipeline data never leave infrastructure you control.
Step-by-step: building the workflow in n8n
Start with the Schedule Trigger node. Set it to a Cron expression like 0 8 * * 1-5 to fire at 08:00 Monday through Friday. Under the node's settings, set the timezone explicitly (for example America/New_York) — n8n honors the instance timezone by default, and a mismatch here is the number-one reason standups post an hour early or late.
Next, add your CRM node. For HubSpot, use the Search operation on the Deals resource with a filter on hs_lastmodifieddate greater than the start of yesterday, or filter closedate within the last 24 hours if you only want closed-won deals. For Pipedrive, use Get All Deals with a status=won filter and a date range. Authenticate with an OAuth2 or API-key credential stored in n8n's credential vault — never hardcode the token into an HTTP node. If your CRM node doesn't expose the exact filter you need, drop in an HTTP Request node and hit the CRM's REST API directly, passing an ISO-8601 date computed from {{ $now.minus({ days: 1 }).toISO() }}.
Now shape the data with a Code node. This is where the raw deal array becomes a standup. Iterate the items, group by owner, sum deal values, and count deals closed. A minimal version looks like this:
const byRep = {};
for (const item of $input.all()) {
const d = item.json;
const rep = d.owner_name || 'Unassigned';
byRep[rep] = byRep[rep] || { count: 0, value: 0 };
byRep[rep].count += 1;
byRep[rep].value += Number(d.amount) || 0;
}
return [{ json: { byRep, total: Object.values(byRep).reduce((a,b)=>a+b.value,0) } }];
Finally, add the Slack node. Use the Send Message operation, select your channel (a dedicated #sales-standup is cleaner than a busy general channel), and build the body with Block Kit. Reference the aggregated data with expressions like {{ $json.total }} and a mapped loop over byRep to render a leaderboard. Use a section block for the headline number, a divider, then a bulleted list of reps sorted by value. Set the Slack credential to a bot token with chat:write scope, and invite that bot to the channel before your first run or the post silently fails.
Test with the Execute Workflow button before you trust the schedule. Pin the Schedule Trigger's data, run the downstream nodes manually, and confirm the Slack message renders exactly as intended. Only then flip the workflow to Active.
The benefits: consistency, speed, and ground truth
The immediate win is that the standup happens every single day at the same minute, with the same structure, without anyone owning it. That consistency is what makes the numbers trustworthy — your team stops debating whether the data is current because it's always sourced fresh from the CRM at post time.
The second win is time. Managers reclaim the morning hour they spent assembling status. Reps stop writing updates and read one instead. And because the format is identical every day, your team develops pattern recognition — a slow Tuesday jumps out visually because it breaks the shape they've internalized. Over weeks, the channel becomes a scrollable history of daily performance you can screenshot into any board deck without preparation.
The third, quieter benefit is cultural. A public, automated leaderboard creates gentle accountability without a manager playing enforcer. Reps see where they stand relative to the team every morning, and that visibility does more for pipeline hygiene than any nagging reminder.
Common pitfalls and how to avoid them
Timezone drift. The most frequent failure. Set the timezone on the Schedule Trigger explicitly and compute your CRM date filters relative to that same zone using $now, not a hardcoded offset that breaks on daylight-saving transitions.
Silent Slack failures. If the bot isn't a member of the target channel, or the token lacks chat:write, the node can error without anyone noticing. Add an Error Trigger workflow that DMs an admin when any execution fails, so a broken standup surfaces immediately instead of quietly vanishing.
Empty-day edge cases. On a day with zero closed deals, an unguarded Code node can produce a malformed message or an empty Slack post. Add a conditional: if the aggregated count is zero, post a friendly "No deals closed yesterday — let's change that today" instead of a blank leaderboard.
API rate limits and pagination. CRMs cap page sizes. If your team closes more deals than one page returns, you'll under-count. Enable the CRM node's Return All option or handle pagination in an HTTP loop so the totals are complete.
Credential sprawl. Store CRM and Slack auth in n8n's credential manager, not inline. It keeps tokens out of exported workflow JSON and lets you rotate keys without editing nodes.
Get Template 76 — Daily Sales Standup Slack — on Gumroad, import the JSON into your n8n instance, connect your CRM and Slack credentials, and your first automated standup can post tomorrow morning.