feat(skills): expose audio/video recording URLs in fireflies transcripts get (#308) (#309)

This commit is contained in:
Magnus Hedemark
2026-08-10 17:37:13 -04:00
committed by GitHub
parent 15b517906a
commit b87d18e15f
8 changed files with 30 additions and 5 deletions
+3 -2
View File
@@ -3,8 +3,8 @@
## Why Install This Skill
Turn Fireflies meetings into usable data without hand-copying notes. Search transcripts, inspect
summaries and action items, review analytics, and ask focused questions with AskFred from a single
dependency-free command line tool.
summaries and action items, review analytics, fetch audio and video recording links, and ask
focused questions with AskFred from a single dependency-free command line tool.
It also makes sensitive operations deliberate: every mutation requires an explicit confirmation,
and every mutation can be previewed locally before it is sent.
@@ -42,6 +42,7 @@ python3 scripts/fireflies meetings rename transcript-id --title "Q3 roadmap" --d
## Triggers
- Fireflies.ai transcripts, summaries, notes, contacts, channels, or analytics
- Meeting audio/video recording download links (`transcripts get` returns `video_url`/`audio_url`)
- AskFred questions about meeting content
- Remote audio upload to Fireflies
- Fireflies Webhooks V2 signature verification
+1 -1
View File
@@ -33,7 +33,7 @@ the target, scope, and rollback path; then route the change through the CLI's li
| Need | Command |
|---|---|
| Find transcript metadata | `scripts/fireflies transcripts list --keyword TEXT --limit 10 --json` |
| Read a meeting, summary, sentences, and analytics | `scripts/fireflies transcripts get ID --json` |
| Read a meeting, summary, sentences, analytics, and recording links | `scripts/fireflies transcripts get ID --json` |
| People, channels, groups, contacts, apps | `users`, `channels`, `groups`, `contacts`, `apps` |
| Meeting analytics or live meetings | `analytics --start DATE --end DATE`, `meetings active` |
| Ask a transcript question | `askfred create --question TEXT --transcript-id ID --confirm` |
+11
View File
@@ -56,6 +56,17 @@
"Notes AskFred mutations require AI credits and --confirm",
"Does not claim AskFred works without an API key"
]
},
{
"id": "recording-urls",
"prompt": "I have a transcript ID for a meeting I attended and I want to download the audio and video recordings of it. How does the skill give me those files?",
"expected_output": "The agent uses the fireflies transcripts get command with the transcript ID; the returned JSON includes video_url and audio_url fields, which are the download links for the meeting's video and audio recordings. It explains the query is a read-only GraphQL query requiring FIREFLIES_API_KEY and returns JSON.",
"assertions": [
"Uses the fireflies transcripts get command with a transcript ID",
"Identifies video_url and audio_url in the returned fields as the recording download links",
"Notes the query is read-only and requires FIREFLIES_API_KEY",
"Does not propose an upload or mutation for a read-only lookup"
]
}
]
}
+2
View File
@@ -41,6 +41,8 @@ follows (live schema wins):
- `createBite` names its argument `transcript_Id` (capital I) and `privacies` takes
`[BitePrivacy!]` (enum: `public`, `team`, `participants`).
- `shareMeeting` input gained `expiry_days` (7, 14, or 30).
- `transcript` selection gained `video_url` and `audio_url` (meeting recording download links),
verified by live introspection on 2026-08-10.
- `updateMeetingChannel` (changelog 2.15.0), `addToLiveMeeting`, `createLiveSoundbite`,
`createUploadUrl`/`confirmUpload`, `setUserRole`, and `askfred_thread` were added as ergonomic
commands after the audit found them documented but uncovered.
+1 -1
View File
@@ -10,7 +10,7 @@ subcommands: `--json`, `--api-key`, `--endpoint`, `--timeout`, `--dry-run`, `--q
|---|---|
| `query --document DOC [--variables JSON|--variables-file PATH]` | Generic read-only GraphQL |
| `mutation --document DOC ... --confirm` | Generic mutation |
| `transcripts list|get|delete` | Search, inspect, or delete meetings |
| `transcripts list|get|delete` | Search, inspect, or delete meetings; `get` also returns `video_url`/`audio_url` recording download links |
| `users`, `contacts`, `channels`, `groups`, `bites`, `apps` | Workspace/content reads; `users set-role --user-id ID --role admin|user` assigns roles |
| `analytics`, `meetings active`, `live-action-items` | Analytics and live data |
| `meetings rename|privacy|state|share|revoke-share|update-channel` | Meeting mutations; `share` accepts `--expiry-days` |
+10
View File
@@ -11,6 +11,16 @@ scripts/fireflies transcripts get transcript-id --json
The detailed query includes summary, speakers, sentences, and analytics.
## Fetch Recording Download URLs
Use this to grab the meeting's audio and video recordings. The response's `video_url` and
`audio_url` fields are the download links for the recording.
```bash
scripts/fireflies transcripts get transcript-id --json
# response includes "video_url" and "audio_url" — signed download links for the recording
```
## Extract Actions and Summary
Use this for a currently live meeting or for a completed transcript.
+1 -1
View File
@@ -16,7 +16,7 @@ EX_USAGE, EX_CONFIG, EX_TRANSPORT, EX_GRAPHQL, EX_CONFIRM = 2, 3, 4, 5, 6
DOCS = {
"transcripts_list": "query Transcripts($title: String, $keyword: String, $scope: String, $fromDate: DateTime, $toDate: DateTime, $limit: Int, $skip: Int, $hostEmail: String, $userId: String, $mine: Boolean, $organizers: [String!], $participants: [String!], $channelId: String, $organizerEmail: String, $participantEmail: String) { transcripts(title: $title, keyword: $keyword, scope: $scope, fromDate: $fromDate, toDate: $toDate, limit: $limit, skip: $skip, host_email: $hostEmail, user_id: $userId, mine: $mine, organizers: $organizers, participants: $participants, channel_id: $channelId, organizer_email: $organizerEmail, participant_email: $participantEmail) { id title date duration organizer_email participants transcript_url } }",
"transcript": "query Transcript($id: String!) { transcript(id: $id) { id title date duration organizer_email participants transcript_url summary { overview } speakers { id name } sentences { index text speaker_name start_time end_time } analytics { sentiments { negative_pct neutral_pct positive_pct } } } }",
"transcript": "query Transcript($id: String!) { transcript(id: $id) { id title date duration organizer_email participants transcript_url video_url audio_url summary { overview } speakers { id name } sentences { index text speaker_name start_time end_time } analytics { sentiments { negative_pct neutral_pct positive_pct } } } }",
"users": "query Users { users { user_id email name is_admin integrations } }",
"me": "query User { user { user_id email name is_admin integrations } }",
"user": "query User($id: String!) { user(id: $id) { user_id email name is_admin integrations } }",
+1
View File
@@ -79,6 +79,7 @@ class FirefliesTests(unittest.TestCase):
self.assertEqual(analytics["variables"],{"startTime":"2026-01-01","endTime":"2026-01-31"})
transcript=json.loads(self.run_cli("transcripts","get","transcript-id","--dry-run","--json").stdout)["payload"]
self.assertIn("negative_pct neutral_pct positive_pct",transcript["query"])
self.assertIn("video_url audio_url",transcript["query"])
audit=json.loads(self.run_cli("audit-events","--filter",'{"category":"MEETING_OPERATIONS"}',"--dry-run","--json").stdout)["payload"]
self.assertIn("events { id time action actor { user_id } resource { type id } }",audit["query"])
def test_transcripts_list_document_is_current(self):