Automating Meeting Transcripts and Summaries with n8n, ChatterBox & OpenAI



This content originally appeared on DEV Community and was authored by Alex Tsimbalistov

Introduction

Picture this: it’s Friday after a week filled with countless online meetings. The details blur, and writing meeting notes is the last thing you want to do. Imagine having a personal bot that joins your meetings, records everything, and emails you concise summaries and action items. In this tutorial, we’ll build exactly that using n8n, a powerful low-code automation tool, combined with ChatterBox’s meeting bot API and OpenAI’s summarization capabilities. This AI-driven workflow detects your upcoming meetings from Google Calendar, dispatches a bot to transcribe them, and then emails you a succinct summary right afterward—saving you valuable time and effort.

This step-by-step guide covers essential n8n nodes and concepts: setting up a Google Calendar trigger, custom logic for meeting details, HTTP requests to interact with ChatterBox, polling to retrieve transcripts, OpenAI for summarization, and finally, an Email node to deliver results. By the end, you’ll experience firsthand how n8n effectively integrates traditional automation with AI, creating your own powerful meeting assistant. Let’s get started!

What We’ll Build

End-to-end N8n Workflow

Before diving into configuration, here’s an overview of the workflow we’ll create:

  1. Google Calendar Trigger – Kicks off the workflow when a calendar event (meeting) is about to start.
  2. Identify Online Meeting Details – Checks if the event has an online meeting URL (Zoom, Meet, or Teams) and determines the platform.
  3. Extract Meeting Credentials – Using custom JavaScript to parse the meeting link for the necessary ID and passcode.
  4. Send Bot – Dispatches a bot to join the meeting via an HTTP Request node (ChatterBox API).
  5. Wait & Poll for Transcript – Monitors the meeting status (either by waiting a set time or polling) and then retrieves the full transcript once the meeting ends.
  6. Summarize with LLM – Feeds the transcript into an OpenAI node to generate a concise summary of the meeting.
  7. Email the Summary – Sends the summary to your email (or any recipients) using an Email node, so you have the notes in your inbox.

We’ll build the workflow in n8n using a clear, modular approach. The following sections break down each step in detail with configuration tips, code snippets, and placeholders for screenshots (so you can visualize or add your own later). Ready to turn your meetings into actionable summaries? Let’s set up our tools and credentials first.

Prerequisites

To follow along, you should have the following ready:

  • n8n: An instance of n8n (either self-hosted or n8n Cloud) where you can build and run your workflow. Familiarity with the n8n editor is assumed (intermediate level).

  • Google Calendar access: This will allow n8n to read calendar events. (In n8n, you’ll create Google credentials and authorize access to your Calendar).

  • Online meeting service account: Meetings scheduled in your Google Calendar that use Zoom, Google Meet, or Microsoft Teams. The calendar event should contain the meeting join link or details (commonly in the event location or description).

  • ChatterBox API Key: Sign up for the ChatterBox Meeting Bot API to get an API token. ChatterBox offers an all-in-one API to drop bots into Zoom/Meet/Teams calls and get transcripts
    (It has a free trial for short sessions – more than enough to test this workflow.)

  • OpenAI API Key: An API key for OpenAI to use the AI summarization. Make sure you have access to the model you plan to use and that n8n is configured with this credential (n8n has an OpenAI node where you can enter the API key).

  • Email service: Credentials for sending email from n8n. I used Resend but there are many other available options. We’ll use this to email the meeting summary out.

⚠ Make sure you comply with privacy laws and obtain consent from participants before recording or transcribing meetings.

With these in place, you’re all set to build the workflow. Now, let’s dive into each step.

Step 1: Google Calendar Trigger – Catch the Meeting Start

Our workflow begins with the Google Calendar Trigger node, which will automatically fire when a meeting is about to start. This ensures our automation kicks in right on time for the scheduled call.

  1. Add a Google Calendar Trigger node to your canvas. Authenticate it with your Google credentials (the same set that has Calendar access). Google Calendar Trigger Settings
  2. Configure the trigger:
  • Calendar ID: Select the calendar that contains your meetings (e.g., your primary calendar or a specific one for work meetings).
  • Trigger On: Choose “Event Started”. This event will cause the node to trigger at the moment an event begins (the start time on the calendar). We want the bot to join as soon as the meeting starts.
  • Poll Interval: You can set how often n8n checks for new events. For near-real-time, a short interval like every minute is fine.

Test the trigger: You can manually create a test event in your Google Calendar (with a start time a few minutes from now and a dummy Zoom/Meet link in it) and activate the workflow. When the event time hits, this node should trigger and output the event data. The output includes details like the event summary (title), start time, end time, description, location, etc.
Calendar Trigger Node
The Google Calendar Trigger node gives us the payload for the meeting. Next, we need to determine if this event has an online meeting link and gather the info required for our bot.

Step 2: Identify Meeting Platform and Credentials

Not every calendar event is an online meeting – we only care about those with Zoom/Meet/Teams links. In this step, we’ll examine the event data to detect the meeting platform and extract the necessary credentials (like meeting ID and passcode). Data to look for: The event’s description or location often contains the meeting join info. For example, a Zoom invite might appear in the description with a URL, or a Google Meet link might be in the location field. We’ll parse these to figure out:

  • Which platform is it? (Zoom vs Google Meet vs Teams)
  • What is the meeting ID or code?
  • Is there a passcode or password? We’ll use a Function node (JavaScript) for this parsing logic. (Alternatively, one could use n8n’s AI capabilities here – imagine feeding the invite text into an AI Transform node to parse out the details – but let’s start with a custom JS approach for precision.) Add a Code node connected to the Calendar Trigger. In this node, we’ll write a script to inspect the event text and extract platform info:
const event = $input.item.json;

// Collect description + location text
let desc = (event.description || "") + " " + (event.location || "");

// Also collect conferenceData entryPoints URIs (if any)
if (event.conferenceData && Array.isArray(event.conferenceData.entryPoints)) {
  const uris = event.conferenceData.entryPoints
    .map(entry => entry.uri)
    .filter(Boolean); // remove undefined/null
  desc += " " + uris.join(" ");
}

// Combine everything into a single searchable text

let platform = null;
let meetingId = null;
let passcode = null;

// Detect Zoom
if (desc.match(/zoom\.us\/j\//i)) {
  platform = "zoom";
  const idMatch = desc.match(/\/j\/(\d+)/);
  if (idMatch) meetingId = idMatch[1];
  const pwdMatch = desc.match(/pwd=([\w]+)/);
  if (pwdMatch) passcode = pwdMatch[1];
}
// Detect Google Meet
else if (desc.match(/meet\.google\.com\/[a-zA-Z0-9-]+/i)) {
  platform = "googlemeet";
  const meetMatch = desc.match(/meet\.google\.com\/([A-Za-z0-9-]+)/);
  if (meetMatch) meetingId = meetMatch[1];
  // Google Meet usually doesn't require a passcode
}
// Detect Microsoft Teams
else if (desc.match(/teams\.microsoft\.com\/.*meeting/i)) {
  platform = "teams";
  const confIdMatch = desc.match(/Conference ID:\s*(\d+)/i);
  if (confIdMatch) {
    meetingId = confIdMatch[1];
  } else {
    const urlIdMatch = desc.match(/meeting_(\w+)/);
    if (urlIdMatch) meetingId = urlIdMatch[1];
  }
  const passMatch = desc.match(/Passcode:\s*([\w]+)/i);
  if (passMatch) passcode = passMatch[1];
}

// Add extracted info to the event
event.platform = platform;
event.meetingId = meetingId;
event.meetingPassword = passcode;

return event;

In the above code, we search the combined description/location/conference data text for clues:

  • Zoom: Looking for “zoom.us/j/” and capturing the numeric meeting ID and any pwd= parameter in the URL.
  • Google Meet: Matching “meet.google.com/” and grabbing the meeting code (which often looks like abc-defg-hjk).
  • Microsoft Teams: Matching “teams.microsoft.com” and then trying to extract either a Conference ID (if present in the invite) or some meeting identifier from the URL. (Teams invites are a bit complex; they often include a numeric conference ID for dial-in, and a long URL with a meeting GUID.

After this Function node, we should have an output item with fields: platform (one of “zoom”, “googlemeet”, “teams”), meetingId, meetingPassword (if any).

Step 3: Dispatch the ChatterBox Bot to the Meeting

Now for the exciting part: sending our transcription bot into the call! We will call the ChatterBox API to spin up a bot that joins the specified meeting and starts transcribing. ChatterBox supports Zoom, Google Meet, and Teams via a unified API endpoint. Add an HTTP Request node (n8n’s generic HTTP client) to trigger the bot deployment:

  1. Method & URL: Set the method to POST and the URL to https://bot.chatter-box.io/join. This is the ChatterBox “join meeting” endpoint.
  2. Headers: Include the authorization header with your API key. For example, set Authorization: Bearer YOUR_API_KEY (replace YOUR_API_KEY with the ChatterBox token from prerequisites). Also set Content-Type: application/json.
  3. Body: Select “JSON” as the body type. Here we’ll provide the meeting details we extracted:
  • platform: Use an expression to insert the platform from the previous Function node (e.g., {{$json["platform"]}} if the Function node is immediately before).
  • meetingId: Insert the meetingId from previous step.
  • meetingPassword: Insert the passcode if available (for Zoom or Teams; Google Meet usually none). If our earlier extraction yielded passcode, use it; otherwise this field can be left empty or omitted.
  • botName: Specify a name for your bot. Your HTTP node might look like this: Send Bot Node Settings In n8n’s UI, you’ll actually use the expression editor to insert those values from the Function node output. Execute the node (or run the workflow up to this point) to test it out. If everything is configured correctly, you should get a response from ChatterBox. The response will be a JSON containing a sessionId for the bot session. For example:
{
  "sessionId": "04634659-xxxx-xxxx-xxxx-xxxxxxxxx456"
}

n8n will output this as JSON. We will need this sessionId to fetch the transcript later.

At this stage, the bot is on its way to the meeting, joining as a participant. ChatterBox can send transcript events to a webhook URL as the meeting progresses, which is great for real-time processing but requires us to set up a receiving endpoint. To keep things simpler, we’ll go with a polling approach – basically, wait until the meeting is done, then ask ChatterBox for the full transcript.

Step 4: Retrieve the Transcript

Once the bot is in the meeting, we need to eventually retrieve the transcript. ChatterBox provides a convenient GET endpoint to fetch all call information, including the complete transcript, once available. Here’s how we’ll handle it:
Wait for meeting to end: We don’t want to pull the transcript too early. For simplicity, we will implement a loop with periodic checks: e.g., every 5 minutes, call the transcript endpoint to see if the meeting has ended. We know the meeting ended when the API returns "status": "finished".
Polling
Next, add another HTTP Request node after the Wait, to call the ChatterBox session endpoint:

  1. Method & URL: GET https://bot.chatter-box.io/session/{{ $json.sessionId }}. Here, we’re using the sessionId output from the previous HTTP node (the join call). Insert it via expression in the URL path.
  2. Headers: Same Authorization Bearer token as before.
  3. No body needed (it’s a GET).
  4. Execute the node (or let it run in the workflow). The response should include all the details of that session. Poll the Meeting Status Node Setttings According to ChatterBox docs, the response JSON will look like this:
{
  "recordingLink": "https://... (if recording available)",
  "startTimestamp": "2025-06-22T14:00:00Z",
  "endTimestamp": "2025-06-22T15:00:00Z",
  "status": "finished",
  "transcript": [
    {
      "timeStart": 12345,
      "timeEnd": 12350,
      "speaker": "Alice Smith",
      "text": "Hello everyone, thank you for joining..."
    },
    {
      "timeStart": 12351,
      "timeEnd": 12355,
      "speaker": "Bob Johnson",
      "text": "Hi Alice, no problem. I wanted to discuss..."
    }
    // ...and so on for the entire meeting
  ]
}

The key part is the transcript array – a list of utterances with speaker names and text. Now we have the raw material needed for summarization!

Processing the transcript data: The HTTP node will output the transcript array likely as part of the JSON. To prepare it for the AI summarizer, you might want to combine all the transcript texts into one large text block. This can be done with another small Code node:

const items = $json.transcript;
const fullText = items.map(line => line.speaker + ": " + line.text).join(" ");
return { json: { fullText } };

This would produce a single item containing fullText – a concatenation of all dialogue. You could also include formatting like newline between speakers, but for a summary it might not matter. The goal is to have one string that contains the entire meeting conversation to feed into the OpenAI node. (If the transcript is extremely long, keep in mind OpenAI API token limits – GPT can handle a lot, but you might consider summarizing in chunks or using a more efficient prompt if needed. For typical meetings, it’s fine.) Now, on to the AI magic!

Step 5: Summarize the Meeting with OpenAI

With the meeting transcript collected, we can finally ask AI to summarize it. n8n provides an OpenAI node (under AI integrations) which makes it easy to interact with models like GPT-4.1. We’ll use that to generate a nice summary of the call.
OpenAI Summarization Node
Add an OpenAI node (or specifically the “OpenAI (ChatGPT)” node if available):

  • Resource: Choose the appropriate resource. You’ll need to select Text.
  • Operation: Message a Model.
  • Model: Select the model from your OpenAI credentials. For example, “GPT-4.1-MINI”.
  • Prompt: This is where we instruct the AI how to summarize. We want a concise summary focusing on important points. You can craft the prompt as needed, for example: "Summarize the following meeting transcript. Focus on key decisions, discussion points, and action items. Provide a clear and concise summary in a few paragraphs.\n\nTranscript:\n{{$json["fullText"]}}" (Here we inject the fullText from the previous node, which contains the entire transcript text.) Adjust the wording to your liking. The better you guide the AI, the more useful the summary. For instance, you might ask for a bulleted list of action items if that’s important, or a paragraph per topic discussed.

Execute the OpenAI node. The output should be the AI’s response – i.e., the meeting summary text. Inspect it to see if it captured the essence of the meeting. At this point, we have what we came for – the meeting’s summary. The final step is to deliver it to your inbox (or wherever it needs to go), so you have it for reference or to share with colleagues.

Step 6: Email the Summary

The last piece of our workflow is sending out the summary via email. For this, you can use n8n’s Email node (which lets you configure SMTP details) or the Gmail node if you want to send through your Google account. For illustration, let’s use the generic Email node (SMTP):
Send Email Node
Add an Email Send node (or if using Gmail, add Gmail node and choose “Send Email” operation).

  • Credentials: If using Email node, either select pre-configured SMTP credentials or fill in details (e.g., SMTP host, port, user, password, etc.).
  • From: Set the sender name/email.
  • To: Set the recipient email address. You might send it to yourself, or to all meeting attendees. For simplicity, put your own email (you could also dynamically use the event attendees list from the trigger output if you want to cc everyone – that’s an advanced touch).
  • Subject: Craft a subject line. Using expressions, we can include the meeting title or date. For example: {{$('Google Calendar Trigger').item.json.summary}}
  • Body: This will be the content of the email. We insert the summary text from the OpenAI node. For example: {{ $json.message.content }}.

Execute the node (or the whole workflow) to test the email. You should receive an email with the subject and the summary in the body. 🎉 Now you’ve got the meeting notes delivered without lifting a finger!

Conclusion

In this tutorial, we’ve built a complete AI-driven meeting assistant using n8n. With a combination of automation nodes and a bit of custom code, we orchestrated a workflow that:

  • Detects when your online meetings start via Google Calendar,
  • Parses the meeting details to figure out how to join,
  • Launches a ChatterBox bot into the call to record everything (leveraging an API that works across Zoom, Teams, and Google Meet),
  • Waits for the meeting to finish and collects the full transcript,
  • Feeds the transcript to OpenAI to generate a concise summary,
  • And finally emails that summary to you (or your team), so you never miss the important points.

This showcase highlights the power and flexibility of n8n. We seamlessly combined a scheduling trigger, web APIs, conditional logic, and AI services all in one flow. By doing so, we’ve automated what used to be a manual, tedious task – freeing you up to focus on more important work (or simply attend fewer meetings!).

Where to go from here? You can extend this workflow in many ways:

  • Use the transcript for additional analytics: for example, run sentiment analysis on the conversation, or automatically create tasks in a project management tool for each action item mentioned (with the help of AI to detect action items).
  • Integrate with Slack or Teams: post the summary in a channel for all participants to see, not just via email.
  • Add error handling and edge cases: maybe alert if the bot fails to join, or if no transcript was generated.
  • Experiment with the AI prompts: tailor the summary style to your needs, or have the AI generate follow-up questions, meeting minutes format, etc.

By building this, you’ve dipped your toes into the world of agentic AI in automation – where a meeting bot works on your behalf within a workflow. This is a powerful pattern that shows how automation platforms like n8n can coordinate complex tasks between services and intelligent agents. We automated not just data movement, but an entire process involving an AI attending a meeting for you and another AI summarizing content for you. Pretty cool, right? I hope you found this tutorial engaging and useful. Now you can attend (or miss!) meetings with peace of mind, knowing your n8n workflow has got your back with the notes. Happy automating and let the bots handle the boring stuff! 🚀


This content originally appeared on DEV Community and was authored by Alex Tsimbalistov