Automation
How to Auto-Send AI Zoom Meeting Summaries Straight to Slack
How to automatically send Zoom meeting summaries to Slack: the API, webhook and formatting steps behind a working AI summary-to-Slack pipeline.

There’s no single button for this. Sending Zoom’s AI Companion meeting summaries to Slack automatically means wiring together three separate pieces: Zoom generates the summary, a workflow tool listens for the meeting to end and pulls that summary through Zoom’s API, then that same tool posts it into Slack through a webhook or the chat.postMessage API call. Zoom and Slack don’t do this handoff for you out of the box.
The Zoom app listed in the Slack App Directory handles things like meeting reminders, “start meeting” shortcuts and join links inside Slack — it does not forward AI-generated summaries. Those summaries live behind Zoom’s own API and webhook system, gated by whether AI Companion is turned on for the account and the specific meeting. Getting a summary to land in Slack automatically means building that bridge yourself, and it’s a genuinely doable afternoon project with a tool like n8n, Zapier or Make.
What has to be true before you build anything
Three prerequisites, and skipping any one of them is why most people’s setup silently fails:
- AI Companion summaries must be enabled at the account or group level by a Zoom admin. Without this, meetings don’t generate a summary at all, and there’s nothing for your workflow to fetch — the automation will run and find an empty response every time.
- You need a Zoom Server-to-Server OAuth app registered in the Zoom App Marketplace (developer account, free). This gives you a client ID, client secret and account ID, which your workflow exchanges for an access token to call Zoom’s API and to receive webhook events.
- You need a way into Slack: either an Incoming Webhook URL scoped to one channel (fastest to set up, no bot needed) or a Slack app with a bot token carrying the
chat:writescope (more flexible — lets you post to multiple channels from one token).
The mechanism, step by step
The pattern is the same whether you build it in n8n, Zapier or Make — only the node names change.
- Subscribe to a Zoom webhook event. In your Zoom Marketplace app, add an event subscription for meeting completion / AI summary availability. Zoom sends a POST request to a URL you control the moment the relevant event fires.
- Handle Zoom’s CRC validation handshake. The first time you save a webhook endpoint URL in Zoom, Zoom sends a challenge payload containing a
plainToken. Your endpoint has to hash that token with your webhook’s secret token (HMAC-SHA256) and return it in the response, or Zoom will refuse to activate the subscription. This step trips up more builds than anything else in this whole pipeline — if your endpoint is a webhook node in n8n and it isn’t handling this handshake, the subscription just sits unverified and nothing ever fires. - Fetch the summary content via API. The webhook event tells you a meeting ended and gives you a meeting UUID — it typically doesn’t hand you the full summary text in the payload. Your workflow makes a follow-up authenticated call to Zoom’s API to retrieve the summary object: overview, key discussion points and next steps, each as separate fields.
- Add a short delay before fetching. AI Companion doesn’t generate the summary the instant the meeting ends — there’s processing time. Fetching immediately on the webhook trigger often returns nothing yet. A 1–2 minute wait step before the API call, or a simple retry-on-empty pattern, fixes this reliably.
- Format the summary for Slack, don’t dump raw text. Zoom’s summary object comes back as structured text (headers, bullet points). Posting it as one giant unformatted string reads badly in Slack. Map it into Slack Block Kit — a header block with the meeting title, a section block for the overview, and a bulleted list for key points and next steps.
- Post to Slack. Either a POST to your Incoming Webhook URL with a JSON payload, or a
chat.postMessagecall if you’re using a bot token and want to target different channels dynamically.
If you’re building this in n8n specifically, the webhook-and-CRC step is the same class of problem covered in N8n Webhook Not Triggering in Production Mode — the causes there (wrong URL environment, missing response format, workflow not active) apply directly to a Zoom webhook endpoint too.
Formatting limits that will bite you
Slack’s Block Kit has hard limits that matter once your summaries come from real hour-long meetings instead of test data: a single section block’s text is capped at 3,000 characters, while a full message (across all its blocks) can hold up to 40,000 characters total. A dense summary from a long meeting can hit the block-level cap even when it’s nowhere near the message-level one, so it’s the per-block limit that usually forces the truncation decision, not the total.
Two practical fixes: split a long summary across multiple section blocks (each under 3,000 characters) instead of one giant block, or trim the summary itself before formatting — for instance, posting only the “next steps” section to Slack and linking back to the full summary in Zoom’s web portal for anyone who wants the whole thing. If you’re also feeding the raw transcript into any AI step upstream (say, to generate your own summary instead of relying on AI Companion’s), the token-limit problem is the same shape as the one covered in Context Length Exceeded? How to Summarize a Long Transcript Without Breaking the Model — chunking or pre-trimming before the model call, not truncating blindly.
Routing to the right channel instead of one firehose
Posting every meeting summary into a single #meeting-notes channel works for a five-person team and becomes noise fast for anything bigger. The fix is a lookup step between “summary fetched” and “post to Slack”: a small table (a Google Sheet or a database row) that maps a Zoom meeting topic, host email or scheduled channel ID to a specific Slack channel ID, so your workflow picks the destination dynamically instead of hardcoding one webhook URL. This adds one lookup node to the pipeline and turns it from a broadcast into something closer to routed notifications — worth it once you’re running this for more than one team.
If you don’t want to build the webhook layer yourself
The no-code path (Zapier, Make) follows the same mechanism, not a shortcut around it: a trigger fires on a Zoom event related to the recording or meeting ending, an action step calls out to an AI model if you’re generating your own summary rather than pulling Zoom’s, and a final action posts to Slack. What changes is who hosts the webhook endpoint and handles the CRC handshake — the platform does it for you instead of you writing that logic in a webhook node — not whether the handshake and the delayed-fetch step are needed at all. They still are.
Common failure points to check first
If nothing shows up in Slack after setup, work down this list before assuming the whole architecture is wrong:
- Webhook subscription still shows unverified in the Zoom Marketplace — the CRC handshake failed. Check the endpoint returns the hashed token correctly, over HTTPS.
- API call for the summary returns empty — either AI Companion wasn’t enabled for that specific meeting (host-level toggle, separate from the account-level one), or the fetch happened before Zoom finished generating it.
- Slack rejects the post with
invalid_blocks— usually a section block over the 3,000-character limit, or a malformed Block Kit JSON structure. - Wrong Slack channel or nothing posts at all — for Incoming Webhooks, the URL is bound to one fixed channel at creation time; you can’t redirect it per-message without switching to a bot token and
chat.postMessage, which takes a channel ID as a parameter.
None of these are exotic — they’re the same handful of issues every Zoom-to-Slack build runs into, and checking them in order usually finds the break in under ten minutes.