Fetch meeting transcripts from Fireflies.ai, extract key points and action items, format them for Slack, and post automatically. Use when you need to share meeting summaries to Slack, process Fireflies transcripts, or set up automated meeting notes workflows. Handles deduplication to avoid posting the same meeting twice.
---
name: meeting-notes
description: Fetch meeting transcripts from Fireflies.ai, extract key points and action items, format them for Slack, and post automatically. Use when you need to share meeting summaries to Slack, process Fireflies transcripts, or set up automated meeting notes workflows. Handles deduplication to avoid posting the same meeting twice.
---
# Meeting Notes to Slack
Automate the workflow of fetching meeting transcripts from Fireflies.ai and posting formatted summaries to Slack.
## Overview
This skill provides a complete pipeline:
1. **Fetch** - Query Fireflies API for recent transcripts
2. **Extract** - Pull out key points, action items, and participants
3. **Format** - Create Slack-optimized markdown with sections and highlights
4. **Post** - Send to specified Slack channel
5. **Track** - Maintain state file to prevent duplicate posts
## Quick Start
```bash
# Fetch recent meetings and post to Slack
cd ~/clawd/skills/meeting-notes
./scripts/fetch-transcript.sh [days-back] [search-term]
./scripts/format-notes.sh <transcript-id>
./scripts/post-to-slack.sh <channel> <formatted-file>
```
## Scripts
### fetch-transcript.sh
Query Fireflies for recent transcripts and save unposted ones.
**Usage:**
```bash
./scripts/fetch-transcript.sh [days-back] [search-term]
```
**Arguments:**
- `days-back` (optional): Number of days to look back (default: 7)
- `search-term` (optional): Filter meetings by title or participant
**Output:**
- Saves transcripts to `state/transcripts/`
- Only fetches meetings not in `state/posted-meetings.json`
- Prints list of new meetings found
### format-notes.sh
Convert a raw transcript into Slack-formatted notes.
**Usage:**
```bash
./scripts/format-notes.sh <transcript-id>
```
**Arguments:**
- `transcript-id`: The Fireflies meeting ID
**Output:**
- Creates `state/formatted/<transcript-id>.md`
- Includes: title, date, participants, overview, action items, key topics
### post-to-slack.sh
Post formatted notes to Slack and track in state file.
**Usage:**
```bash
./scripts/post-to-slack.sh <channel> <formatted-file>
```
**Arguments:**
- `channel`: Slack channel name (e.g., `#team-sync`)
- `formatted-file`: Path to formatted markdown file
**Behavior:**
- Posts message to Slack via `message` tool
- Adds transcript ID to `state/posted-meetings.json`
- Prevents duplicate posts automatically
## State Files
### state/posted-meetings.json
Tracks which meetings have been posted to avoid duplicates.
**Format:**
```json
{
"posted": [
{
"id": "transcript-id-123",
"title": "Team Sync",
"posted_at": "2026-01-15T19:30:00Z",
"channel": "#team-sync"
}
]
}
```
### state/transcripts/
Raw transcript JSON files from Fireflies API, organized by ID.
### state/formatted/
Formatted markdown files ready for Slack posting.
## Configuration
### API Keys
The skill uses `~/clawd/secrets/fireflies.key` for authentication.
**Format:** Plain text file containing the API key
```
4576cfcf3273dc3f9b122d1acf3c8b51
```
For multiple accounts, see `~/clawd/secrets/fireflies.json` which contains account mappings.
### Slack Integration
Requires Slack channel plugin configured in Clawdbot. The `post-to-slack.sh` script uses the `message` tool internally.
## Common Workflows
### Daily Meeting Summary
Post yesterday's meetings:
```bash
./scripts/fetch-transcript.sh 1
for transcript in state/transcripts/*.json; do
id=$(basename "$transcript" .json)
./scripts/format-notes.sh "$id"
./scripts/post-to-slack.sh "#daily-sync" "state/formatted/${id}.md"
done
```
### Specific Meeting
Find and post a specific meeting:
```bash
./scripts/fetch-transcript.sh 30 "Product Review"
# Review the output, then format and post the desired meeting
./scripts/format-notes.sh <meeting-id>
./scripts/post-to-slack.sh "#product" "state/formatted/<meeting-id>.md"
```
### Automated Cron
Set up a cron job to automatically post daily:
```bash
# Post previous day's meetings every morning at 9am
cron add --schedule "0 9 * * *" --command "cd ~/clawd/skills/meeting-notes && ./scripts/fetch-transcript.sh 1 && for t in state/transcripts/*.json; do id=\$(basename \$t .json); ./scripts/format-notes.sh \$id; ./scripts/post-to-slack.sh '#daily-sync' state/formatted/\${id}.md; done"
```
## Error Handling
All scripts exit with status code 1 on error and print diagnostic messages to stderr.
**Common issues:**
- Missing API key: Check `~/clawd/secrets/fireflies.key` exists
- No new meetings: All recent meetings already posted
- Slack posting fails: Verify channel name and Clawdbot Slack integration
- Invalid transcript ID: Check ID exists in `state/transcripts/`
## Deduplication
The skill maintains deduplication at two levels:
1. **Fetch stage**: `fetch-transcript.sh` checks `posted-meetings.json` and skips already-posted meetings
2. **Post stage**: `post-to-slack.sh` verifies meeting isn't in state file before posting
This ensures meetings are never posted twice, even if the workflow is run multiple times.
don't have the plugin yet? install it then click "run inline in claude" again.