Skip to content
Notifications
Clear all

Step-by-step: How I built a meeting summary pipeline into our CRM using Fireflies API

23 Posts
23 Users
0 Reactions
50 Views
(@hannahw)
Reputable Member
Joined: 3 months ago
Posts: 234
Topic starter   [#26313]

We were drowning in meeting notes scattered across Slack and email. Our sales team needed key details (next steps, pain points) directly in HubSpot, fast. Fireflies' API turned out to be the perfect glue.

Here's my basic pipeline flow:
* **Trigger:** Fireflies webhook sends "transcript ready" to a Zapier webhook.
* **Processing:** A simple Python script (on a free Render instance) parses the Fireflies JSON. It extracts:
* Meeting summary & action items
* Custom topics I flagged (e.g., "budget", "competitor")
* Key quotes from our solution discussion
* **Push:** Script formats the data and uses the HubSpot API to create/update a contact record and log a note on the associated deal.

Biggest cost saver? We only call the Fireflies API for *sales calls*, not internal meetings. I set this using their workflow rules. This keeps our processing costs near zero.

The setup took a weekend. Now our reps save 15+ minutes per call on manual entry and have way better context. Total added cost for this "automation layer" is about $10/month for the Zapier step.

Biggest tip: Use Fireflies' `topics` and `tasks` objects in the API responseβ€”they're gold for CRM fields. Skip the full transcript unless you really need it.



   
Quote
(@amandap)
Estimable Member
Joined: 3 months ago
Posts: 173
 

This is exactly what I need to set up. Quick question, how do you handle the webhook from Zapier to your Python script? Is it just a basic POST endpoint you set up on Render?



   
ReplyQuote
(@finnj)
Reputable Member
Joined: 3 months ago
Posts: 269
 

That $10/month for Zapier is the tell. You've basically built a vendor-locked Rube Goldberg machine. Fireflies API -> Zapier -> Render -> HubSpot, and you're on the hook for four services just to move text around.

The free tier of n8n, or even a simple Flask app with a cron job, could replace the whole "Zapier+Render" middle layer for exactly zero dollars. You're already running a script, why pay a toll to trigger it?

Interesting that you only process sales calls to save cost. Isn't the real problem that Fireflies charges per meeting? Maybe the glue shouldn't be so expensive in the first place 😉


FOSS advocate


   
ReplyQuote
(@datadog_dave)
Honorable Member
Joined: 4 months ago
Posts: 494
 

The n8n suggestion is a good one, it's a solid free alternative for this kinda pipeline. I'm a sucker for the simplicity of a managed webhook catcher though, especially for a sales team process where someone needs to own the "it broke" pager.

You're right that >Fireflies charges per meeting< is the real cost driver. That's why I'm actually testing Deepgram's API for transcription on internal calls now, feeding it into the same script. It gets pricey fast if you're not selective.

The $10 Zapier tier is basically our team's "don't make Dave build another cron server" tax.


Dashboards or it didn't happen.


   
ReplyQuote
(@cloud_cost_hawk_new)
Reputable Member
Joined: 5 months ago
Posts: 333
 

The "cost saver" you found is just a workaround for the real issue. Fireflies, like most of these AI services, charges per API call to extract the value you just paid them to create. It's a double dip.

You've admitted the real cost driver is the per-meeting fee. So you built a system to filter calls. But that's just adding complexity to manage their pricing model. The actual cost isn't the $10 for Zapier, it's the ongoing Fireflies bill that will scale directly with your sales activity. Wait until marketing wants to analyze all *their* calls.

A truly cheap pipeline would start with a cheaper transcription source for internal calls, not a filter. You're already on a free Render instance for the script, so you're halfway there.


-- cost first


   
ReplyQuote
(@cost_observer_42)
Honorable Member
Joined: 4 months ago
Posts: 407
 

So the "Dave tax" is a $120/year line item, but the real math is on your Deepgram test. Are you logging those API calls separately in your billing data? Because now you've got two transcription cost centers to reconcile.

You're swapping one variable cost for another. Unless you're segmenting usage and cost by department already, marketing will just bloat the Deepgram bill instead of the Fireflies one. The tool isn't the cost, the lack of a hard allocation policy is.

Selective usage is just manual cost control. It doesn't scale.


cost_observer_42


   
ReplyQuote
(@bob88)
Reputable Member
Joined: 3 months ago
Posts: 241
 

Your filter for >only sales calls< is a smart first step, but it's a tactical fix, not a strategic one. I've seen this pattern before. That $10 Zapier cost is noise. The real operational cost you've introduced is the cognitive load of maintaining this multi-service chain when the transcription source inevitably changes.

You're happy with Fireflies now, but what happens when marketing wants their call summaries in a different system, or finance needs a separate audit trail? You'll duplicate this pipeline, doubling the points of failure. You've built a pipeline *for* Fireflies and HubSpot, not a pipeline *for meeting data*.

Consider abstracting the transcription source from day one. Make your Python script accept a standardized JSON payload from *any* provider (Fireflies, Deepgram, AssemblyAI). The script does the CRM formatting and push. Let a separate, simple service (n8n, a single Lambda, even a different Zap) handle the provider-specific webhook and normalization. That way, swapping a transcription vendor becomes a one-hour config change, not a weekend rebuild. You're already doing the hard part with the parsing logic. Don't hardcode the source.


Migrate once, test twice.


   
ReplyQuote
(@davids)
Honorable Member
Joined: 3 months ago
Posts: 568
 

You've absolutely nailed the long-term maintenance risk. The "pipeline for Fireflies and HubSpot" versus "pipeline for meeting data" distinction is crucial.

I'll share a concrete outcome of not abstracting early: we later needed to bring in Gong data for a different team, and we had to create a parallel "Zapier to Script B" flow because the original script was so coupled to Fireflies' JSON structure. It was a week of redundant work.

Your suggestion about a separate service for provider-specific normalization is spot on. The ideal state is a single script that expects, say, a common "meeting_metadata" and "transcript_chunks" format. The trigger layer (Zapier, n8n, Lambda) becomes a cheap, replaceable adapter. That shifts the cognitive load from "rewriting the core logic" to just "writing a new webhook parser," which is far more sustainable.

The resistance I often see is that it feels like over-engineering for a simple, working solution. How do you decide when to invest in that abstraction from the start, versus only building it when you add a second source?


Stay curious, stay critical.


   
ReplyQuote
(@emma78)
Reputable Member
Joined: 3 months ago
Posts: 221
 

Yes, it's just a basic POST endpoint. You set it up on Render by creating a web service, then point your Zapier webhook to that URL.

I'm just starting to learn about webhooks myself. When you say "handle," do you mean the security part? Like, verifying it's actually Zapier sending the data? That's the next thing I need to figure out for mine.



   
ReplyQuote
(@data_pipeline_tinker)
Honorable Member
Joined: 5 months ago
Posts: 364
 

That's a clever use of their workflow rules to gate the API calls. A lot of people miss that you can use Fireflies itself as the first filter, which is simpler than writing conditional logic in your script later. The `topics` and `tasks` objects are indeed the right starting point for CRM mapping.

One practical addition I'd suggest is to log the meeting duration from the payload into a custom HubSpot property early on. We found it became a useful leading indicator for deal health - longer discovery calls often correlated with specific deal stages. You can extract it from the `duration` field in the Fireflies response with almost no extra code.

What's your fallback plan for when the free Render instance goes to sleep? I've had webhooks get dropped during idle periods, which required adding a dead-letter queue via a simple Google Sheet as a catch-all before we moved to a more reliable setup.


Extract, transform, trust


   
ReplyQuote
(@chrisd)
Honorable Member
Joined: 3 months ago
Posts: 453
 

Great to see someone else tackling this exact pain point! Your tip about using the `topics` and `tasks` objects directly is spot-on. They're pre-structured data, which saves so much time over trying to parse a summary block.

One minor but impactful addition: I'd also pull the `sentiment` field, if Fireflies provides it for your plan. It's a single score you can push to a custom property in HubSpot with almost no extra work, and it gives a quick, objective temperature check on the call that reps sometimes miss in their own notes. That, plus the `duration` field another poster mentioned, gives you two leading indicators for almost zero extra code.

Smart move filtering at the source with their workflow rules. Saves those free-tier Render cycles for when you actually need them!


Prod is the only environment that matters.


   
ReplyQuote
(@cloud_infra_rookie)
Noble Member
Joined: 4 months ago
Posts: 552
 

Yeah, that's exactly what I meant. I've been reading that you should check a secret token in the webhook request header. Zapier lets you add a custom header with a value you set, and then your script can check for it before doing anything. It seems pretty simple to add.

Does anyone know if Render has a way to add environment variables for that secret? I'm still trying to figure out how to keep keys out of my code.



   
ReplyQuote
(@ashp99)
Honorable Member
Joined: 3 months ago
Posts: 377
 

Yes, Render does have environment variables! You can set them right in the dashboard under your web service's settings. It's called "Environment Variables," and you just add your key/value pairs there.

That's where I stash my webhook secrets and API keys. Then in your Python script, you can just use `os.environ.get('YOUR_SECRET_TOKEN')`. It's much cleaner than hardcoding.


data over opinions


   
ReplyQuote
(@integration_ian_2)
Honorable Member
Joined: 4 months ago
Posts: 525
 

Spot on about using the workflow rules for filtering - that's the kind of smart gatekeeping that makes a free-tier setup sustainable. Your point about the `topics` and `tasks` objects is the key that unlocks a clean integration; trying to parse the free-form summary for structured data is a rabbit hole.

One nuance I ran into with the `tasks` object: sometimes multiple action items get concatenated into a single string. I added a tiny bit of logic to split on common delimiters like "and" or commas before mapping each to a separate HubSpot note. It made the output much cleaner for the reps.

That $10 Zapier cost is a great trade-off. It's the reliable router that lets your Python script do the heavy lifting without worrying about retries or timeouts.


api first


   
ReplyQuote
(@auditor_abby)
Reputable Member
Joined: 6 months ago
Posts: 363
 

Exactly. The point about vendor lock-in is the critical one. I've reviewed three separate incidents where a team's critical workflow broke because a vendor's API changed or they switched to a different meeting platform, and their custom script was a single point of failure.

Building a >pipeline for meeting data< forces you to define an internal schema first. That's the compliance win. You create a single, versioned data contract - what *your* business needs from a meeting - and log everything against that. Then the provider-specific adapter is just a compliance-controlled input source. You can audit, switch, or add sources without touching the core logic that pushes data to your CRM.

It also means your logs are consistent. If Gong sends a "duration" in minutes and Fireflies sends it in seconds, that normalization happens at the adapter layer, not in twenty different scripts.


Where is your SOC 2?


   
ReplyQuote
Page 1 / 2