Skip to content
Notifications
Clear all

Step-by-step: Automating Otter transcript delivery to clients via email.

3 Posts
3 Users
0 Reactions
4 Views
(@auditlog)
Estimable Member
Joined: 3 months ago
Posts: 130
Topic starter   [#12696]

I've been using Otter.ai to transcribe client meetings for compliance purposes (SOX, HIPAA) and needed a reliable, automated way to get those transcripts to clients without manual intervention. The goal was a fully documented, repeatable process that leaves an audit trail. While Otter's built-in sharing is fine for ad-hoc use, I needed something that could batch process, apply consistent formatting, and log each delivery attempt.

My solution uses Otter's email summary feature as a trigger, a cloud function to reformat, and a secure delivery service. Here's my step-by-step breakdown.

**Core Architecture:**
1. **Trigger:** Otter.ai's "Email Summary" feature sends the transcript to a dedicated, monitored inbox (e.g., `transcripts@yourdomain.com`).
2. **Processing:** A serverless function (AWS Lambda, in my case) polls that inbox via IMAP, parses the email, and extracts the transcript.
3. **Reformatting:** The function cleans up the transcript, adds a standardized client-specific header/footer, and converts it to a PDF for non-repudiation.
4. **Delivery & Logging:** The PDF is sent via a transactional email service (SendGrid) with read receipts disabled for privacy. Every step is logged to a SIEM-friendly format.

**Critical Code Snippet (AWS Lambda - Python):**
This is the core of the parsing function after retrieving the raw email. It handles the Otter-specific HTML structure.

```python
import re
from bs4 import BeautifulSoup

def extract_otter_transcript(raw_html):
"""
Parses Otter.ai's email HTML to extract the clean transcript.
Returns speaker-separated text and meeting metadata.
"""
soup = BeautifulSoup(raw_html, 'html.parser')

# Otter embeds transcript in a specific div
transcript_div = soup.find('div', {'style': re.compile(r'font-family.*Arial')})

if not transcript_div:
return None, None

# Extract date/time from heading patterns
meeting_title = soup.find('h2').get_text() if soup.find('h2') else 'No Title'

# Clean up speaker lines
lines = []
for element in transcript_div.find_all(['p', 'div']):
text = element.get_text(strip=True)
if text and not re.match(r'^d{2}:d{2}$', text): # Ignore timestamps
lines.append(text)

transcript_text = 'n'.join(lines)
return meeting_title, transcript_text
```

**Key Considerations & Pitfalls:**

* **Audit Trail:** The Lambda function writes a structured JSON log for every run, capturing client ID, meeting ID, transcript hash, and delivery status. This is crucial for compliance.
```json
{
"event": "transcript_delivered",
"client_id": "client_123",
"otter_meeting_id": "otter_abc456",
"timestamp": "2023-10-26T15:30:00Z",
"delivery_method": "email",
"recipient_hash": "sha256_of_email"
}
```
* **Error Handling:** Build in retries for email fetching and a dead-letter queue for failed processing. Assume the Otter email format might change.
* **Security:** Store client email mappings and API keys in a secure secrets manager, not in the code. The PDFs should be password-protected if containing sensitive information (PHI/PII).
* **Cost:** The "Email Summary" feature requires a Pro plan. Monitor cloud function costs if volume is high.

I've found this system runs for months without touch, but the initial setup requires careful testing with various Otter email formats (different meeting lengths, speaker counts). The main alternative would be using Otter's API directly, but the email method provides a simple, queue-like buffer that's easier to debug and audit. Has anyone else built a similar pipeline, perhaps using Zapier/Make for a low-code approach, and how do you handle the audit log requirements?


Logs don't lie.


   
Quote
(@devops_contrarian_42)
Estimable Member
Joined: 4 months ago
Posts: 117
 

SOX and HIPAA, and you're polling an inbox with a Lambda? That's your audit trail? Hope you're encrypting that transcript at rest and logging every IMAP auth attempt. Otherwise your "compliance" is just a fancy PDF.

SendGrid's fine, but you're adding complexity where a simple, scheduled script on a locked-down VM would work. Now you've got Lambda timeouts, cloud function permissions, and another service bill to manage.


Keep it simple


   
ReplyQuote
(@julieh)
Estimable Member
Joined: 1 week ago
Posts: 52
 

Polling an inbox with IMAP for a SOX workflow makes my eye twitch. Where's the chain of custody before that email arrives? Otter's outbound email isn't exactly a signed, tamper-evident log.

You're creating a critical path that depends on Otter's email queue and your IMAP server's availability. If that transcript gets lost in a spam filter for two hours, your compliance timeline is already broken.


Caveat emptor.


   
ReplyQuote