Skip to content
Notifications
Clear all

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

4 Posts
4 Users
0 Reactions
1 Views
(@cloud_ops_learner_99)
Estimable Member
Joined: 1 month ago
Posts: 137
Topic starter   [#5305]

Hi everyone, I'm still pretty new to automating things in the cloud, but I wanted to share a small project I got working. My team wanted meeting summaries from Fireflies.ai automatically added to our CRM (we use HubSpot). I was nervous about using the API, but I managed to piece it together.

Here's the core part, a Python Lambda function that gets triggered when Fireflies sends a webhook. It fetches the transcript summary and posts it to a HubSpot contact note.

```python
import os
import requests

def lambda_handler(event, context):
# Get meeting data from Fireflies webhook
fireflies_data = event['body']
meeting_id = fireflies_data['id']
summary = fireflies_data['summary']

# Get the associated contact email from the meeting
attendee_email = fireflies_data['participants'][0]['email']

# Fetch HubSpot contact ID using the email
hubspot_headers = {'Authorization': f'Bearer {os.environ["HUBSPOT_TOKEN"]}'}
contact_url = f'https://api.hubapi.com/crm/v3/objects/contacts/{attendee_email}?idProperty=email'
contact_resp = requests.get(contact_url, headers=hubspot_headers)
contact_id = contact_resp.json()['id']

# Create a note in HubSpot
note_url = 'https://api.hubapi.com/crm/v3/objects/notes'
note_payload = {
"properties": {
"hs_timestamp": fireflies_data['date'],
"hs_note_body": f"Meeting Summary from Fireflies:nn{summary}",
"hubspot_owner_id": contact_id
}
}
requests.post(note_url, json=note_payload, headers=hubspot_headers)

return {'statusCode': 200}
```

I used Terraform to deploy the Lambda and set up the API Gateway endpoint for the webhook, which was a good learning experience 😅. The main challenge was figuring out the HubSpot API formatting. Hope this helps someone else trying to connect these services!



   
Quote
(@lukej)
Eminent Member
Joined: 1 week ago
Posts: 27
 

Your Lambda approach works, but there's a significant unhandled failure mode with that HubSpot contact lookup. The `requests.get` call can fail silently or return a non-200 status, and your code will raise a KeyError trying to access `contact_resp.json()['id']` before you check the response.

You should add explicit error handling and logging. Without it, you'll have no visibility when a meeting with an unknown email hits the webhook, and the Lambda will fail without a clear trace. Consider structuring it like this:

```python
contact_resp = requests.get(contact_url, headers=hubspot_headers)
if contact_resp.status_code != 200:
# Log the error and the email that failed
print(f"Failed to find contact for {attendee_email}: {contact_resp.text}")
return
```

Also, you're only using the first participant's email. What happens if the meeting's primary contact isn't the first in the `participants` list? You might need logic to map the host or a specific attendee type.


Measure everything.


   
ReplyQuote
(@bookworm42)
Estimable Member
Joined: 1 week ago
Posts: 88
 

The silent failure point is critical, but using `print` in Lambda for logging is a bad habit. CloudWatch won't catch those reliably unless you structure them as proper log events. Use the `logging` module or the context object.

Your second point about participant order is spot on. The Fireflies webhook payload has a `host_email` field. That's almost always the correct one to use for CRM mapping, not the first attendee. Relying on list order is fragile.



   
ReplyQuote
(@jordanh)
Estimable Member
Joined: 1 week ago
Posts: 85
 

Ah yes, the classic "print is a bad habit" lecture, which is absolutely correct. But let's be honest, half the Lambda functions running in production right now are still using print statements, because CloudWatch *does* still ingest them, you just lose structured context. The real crime is using no logging at all.

The `host_email` field, however, is the much more interesting assumption. It presumes the CRM system of record cares about the meeting *host*. What if I'm in sales and I need to log notes against the *prospect* who attended, not my colleague who clicked the calendar link? Relying on any single field is just trading one fragility for another. The real logic needs to be domain-specific: are you summarizing for the organizer, the account owner, or the external participant? The API gives you a list; you have to apply your own rules.


🤷


   
ReplyQuote