Skip to content
OpenSmartRoute
Skillv1.0.0

fireflies-reference-architecture

Design meeting intelligence architecture with Fireflies.ai GraphQL API, webhooks, and CRM sync. Use when designing new integrations, planning transcript pipelines, or establishing architecture for mee

by jeremylongshore(0) 0 installs
Free
Sign in to install

Free account. Installing gives you the manifest plus copy-paste snippets.

See reviews

About

Imported from jeremylongshore/tons-of-skills-marketplace (skills/.curated/fireflies-reference-architecture/SKILL.md). Install upstream with npx skills add jeremylongshore/tons-of-skills-marketplace --skill fireflies-reference-architecture. Copyright stays with the author (MIT).

Fireflies.ai Reference Architecture

Overview

Production architecture for meeting intelligence using Fireflies.ai. Event-driven pipeline: meetings are recorded by the Fireflies bot, transcripts arrive via webhook, then are processed for action items, analytics, and CRM sync.

Prerequisites

  • A documented consent, access, retention, and downstream-sharing policy for each meeting source.
  • Scoped identities separating webhook ingress, transcript processing, storage, and CRM consumers.
  • A policy owner, synthetic fixtures, redacted telemetry, and an emergency disable/rollback path.

Instructions

  1. Verify event signatures at ingress and place opaque IDs on a durable, idempotent queue.
  2. Retrieve and process transcript data only within the authorized worker; apply field allowlists before any downstream sync.
  3. Enforce retention and access checks at storage and retrieval, and emit aggregate/redacted operational metrics.
  4. Test with fictional meetings, promote through a canary, and stop processing if consent, access, or destination validation fails.

Examples

Route a synthetic transcript-ready event through the queue using an opaque ID. The worker writes only approved action items to a staging CRM, rejects a repeated event as a duplicate, and records no transcript text in logs or metrics.

Architecture

┌──────────────────────────────────────────────────────┐
│              Meeting Sources                          │
│  Zoom  │  Google Meet  │  MS Teams  │  Upload API    │
└──────────┬───────────────────────────────┬───────────┘
           │ Bot auto-joins                │ uploadAudio
           ▼                               ▼
┌──────────────────────────────────────────────────────┐
│              Fireflies.ai Platform                    │
│  Transcription → Speaker ID → AI Summary → Actions   │
└───────────────────────┬──────────────────────────────┘
                        │ Webhook: "Transcription completed"
                        │ Payload: { meetingId, eventType }
                        ▼
┌──────────────────────────────────────────────────────┐
│              Your Webhook Receiver                    │
│  1. Verify x-hub-signature (HMAC-SHA256)             │
│  2. ACK 200 immediately                              │
│  3. Queue for async processing                       │
└───────────────────────┬──────────────────────────────┘
                        │
           ┌────────────┼────────────┐
           ▼            ▼            ▼
   ┌──────────────┐ ┌────────┐ ┌──────────────┐
   │ Transcript   │ │ Action │ │ Analytics    │
   │ Storage      │ │ Items  │ │ Engine       │
   │ (DB/Search)  │ │ (CRM)  │ │ (Dashboards) │
   └──────────────┘ └────────┘ └──────────────┘

Core Components

1. GraphQL Client Layer

// lib/fireflies.ts
const FIREFLIES_API = "https://api.fireflies.ai/graphql";

export async function firefliesQuery(query: string, variables?: any) {
  const res = await fetch(FIREFLIES_API, {
    method: "POST",
    headers: {
      "Content-Type": "application/json",
      Authorization: `Bearer ${process.env.FIREFLIES_API_KEY}`,
    },
    body: JSON.stringify({ query, variables }),
  });
  const json = await res.json();
  if (json.errors) throw new Error(json.errors[0].message);
  return json.data;
}

2. Webhook Processor

// services/webhook-processor.ts
import crypto from "crypto";

interface TranscriptEvent {
  meetingId: string;
  eventType: string;
  clientReferenceId?: string;
}

export async function processWebhookEvent(event: TranscriptEvent) {
  // Fetch full transcript
  const { transcript } = await firefliesQuery(`
    query($id: String!) {
      transcript(id: $id) {
        id title date duration
        organizer_email
        speakers { id name }
        sentences {
          speaker_name text start_time end_time
          ai_filters { task question sentiment }
        }
        summary { overview action_items keywords topics_discussed }
        meeting_attendees { displayName email }
        analytics {
          sentiments { positive_pct negative_pct neutral_pct }
          speakers { name duration word_count questions words_per_minute }
        }
      }
    }
  `, { id: event.meetingId });

  // Process in parallel
  await Promise.all([
    storeTranscript(transcript),
    syncActionItems(transcript),
    updateAnalytics(transcript),
  ]);

  return transcript;
}

3. Transcript Storage

// services/transcript-store.ts
interface StoredMeeting {
  firefliesId: string;
  title: string;
  date: string;
  duration: number;
  speakers: string[];
  overview: string;
  actionItems: string[];
  keywords: string[];
  sentiment: { positive: number; negative: number; neutral: number };
}

async function storeTranscript(transcript: any): Promise<StoredMeeting> {
  const meeting: StoredMeeting = {
    firefliesId: transcript.id,
    title: transcript.title,
    date: transcript.date,
    duration: transcript.duration,
    speakers: transcript.speakers.map((s: any) => s.name),
    overview: transcript.summary?.overview || "",
    actionItems: transcript.summary?.action_items || [],
    keywords: transcript.summary?.keywords || [],
    sentiment: {
      positive: transcript.analytics?.sentiments?.positive_pct || 0,
      negative: transcript.analytics?.sentiments?.negative_pct || 0,
      neutral: transcript.analytics?.sentiments?.neutral_pct || 0,
    },
  };

  // Store in your database
  await db.meetings.upsert({ where: { firefliesId: meeting.firefliesId }, data: meeting });
  return meeting;
}

4. Action Item Sync

// services/action-items.ts
async function syncActionItems(transcript: any) {
  const items = transcript.summary?.action_items || [];
  if (items.length === 0) return;

  const attendees = transcript.meeting_attendees?.map((a: any) => a.email) || [];

  for (const item of items) {
    await taskManager.create({
      title: item.slice(0, 200),
      source: `Fireflies: ${transcript.title}`,
      meetingId: transcript.id,
      meetingDate: transcript.date,
      participants: attendees,
    });
  }

  console.log(`Synced ${items.length} action items from "${transcript.title}"`);
}

5. Meeting Analytics

// services/analytics.ts
async function buildWeeklyReport() {
  const since = new Date(Date.now() - 7 * 86400000).toISOString();

  const data = await firefliesQuery(`
    query($fromDate: DateTime) {
      transcripts(fromDate: $fromDate, limit: 100) {
        id title date duration
        participants
        summary { action_items keywords }
        analytics {
          speakers { name duration word_count }
          sentiments { positive_pct }
        }
      }
    }
  `, { fromDate: since });

  const meetings = data.transcripts;
  return {
    totalMeetings: meetings.length,
    totalHours: (meetings.reduce((s: number, m: any) => s + m.duration, 0) / 60).toFixed(1),
    actionItems: meetings.reduce((s: number, m: any) => s + (m.summary?.action_items?.length || 0), 0),
    topKeywords: aggregateKeywords(meetings).slice(0, 10),
    avgSentiment: avgSentiment(meetings),
  };
}

function aggregateKeywords(meetings: any[]): [string, number][] {
  const counts: Record<string, number> = {};
  for (const m of meetings) {
    for (const kw of m.summary?.keywords || []) {
      counts[kw] = (counts[kw] || 0) + 1;
    }
  }
  return Object.entries(counts).sort((a, b) => b[1] - a[1]);
}

6. Audio Upload Pipeline

// services/upload.ts
async function uploadRecording(fileUrl: string, title: string, attendees?: any[]) {
  return firefliesQuery(`
    mutation($input: AudioUploadInput) {
      uploadAudio(input: $input) {
        success
        title
        message
      }
    }
  `, {
    input: {
      url: fileUrl,
      title,
      attendees: attendees?.map(a => ({ displayName: a.name, email: a.email })),
      webhook: process.env.WEBHOOK_URL,
      client_reference_id: `upload-${Date.now()}`,
    },
  });
}

Project Layout

meeting-intelligence/
  src/
    lib/fireflies.ts          # GraphQL client
    services/
      webhook-processor.ts    # Event handler
      transcript-store.ts     # DB persistence
      action-items.ts         # CRM/task sync
      analytics.ts            # Aggregation
      upload.ts               # Audio upload
    api/
      webhooks/fireflies.ts   # Webhook endpoint
      health.ts               # Health check
    types/fireflies.ts        # TypeScript interfaces
  tests/
    fixtures/                 # Recorded API responses
    services/                 # Service unit tests

Error Handling

Issue Cause Solution
Missing transcript meetingId invalid Log and skip, alert on repeated failures
Empty summary Meeting too short Check duration > 1 min before processing
Duplicate webhook Network retry Use meetingId as idempotency key
Rate limit on batch Many transcripts at once Queue with PQueue (1 req/sec)

Output

  • Event-driven architecture with webhook-triggered processing
  • Transcript storage with search-ready schema
  • Action item extraction and CRM sync pipeline
  • Meeting analytics aggregation engine

Resources

Next Steps

For multi-environment deployment, see fireflies-multi-env-setup.

Use it

Copy one of these into your project. Installing also returns the manifest and these snippets.

yaml
targets:
  - https://api.opensmartroute.ai/api/v1/registry/jeremylongshore-tons-of-skills-marketplace-fireflies-ref-2e0089/manifest   # or paste the manifest below

Manifest

An Open Capability Manifest: the router reads it to know what this does, what it costs and when to pick it.

jeremylongshore-tons-of-skills-marketplace-fireflies-ref-2e0089.ocm.jsonjson
{
  "ocm": "1",
  "id": "jeremylongshore-tons-of-skills-marketplace-fireflies-ref-2e0089",
  "kind": "skill",
  "name": "fireflies-reference-architecture",
  "description": "Design meeting intelligence architecture with Fireflies.ai GraphQL API, webhooks, and CRM sync. Use when designing new integrations, planning transcript pipelines, or establishing architecture for meeting analytics platforms. Trigger with phrases like \"fireflies architecture\", \"fireflies design\", \"fireflies project structure\", \"meeting intelligence pipeline\".",
  "publisher": "jeremylongshore",
  "version": "1.0.0",
  "capabilities": {
    "domains": [
      "coding"
    ],
    "tags": [
      "skill-md",
      "saas",
      "fireflies",
      "architecture",
      "skills-sh"
    ],
    "languages": [
      "en"
    ]
  },
  "quality_prior": 0.6,
  "examples": [
    "Design meeting intelligence architecture with Fireflies.ai GraphQL API, webhooks, and CRM sync. Use when designing new integrations, planning transcript pipelines, or establishing architecture for meeting analytics platforms. Trigger with phrases like \"fireflies architecture\", \"fireflies design\", \"fireflies project structure\", \"meeting intelligence pipeline\"."
  ],
  "primary": false,
  "metadata": {
    "source": {
      "provider": "skills.sh",
      "repository": "https://github.com/jeremylongshore/tons-of-skills-marketplace",
      "path": "skills/.curated/fireflies-reference-architecture/SKILL.md",
      "ref": "HEAD",
      "url": "https://github.com/jeremylongshore/tons-of-skills-marketplace/blob/HEAD/skills/.curated/fireflies-reference-architecture/SKILL.md",
      "key": "jeremylongshore/tons-of-skills-marketplace/skills/.curated/fireflies-reference-architecture/SKILL.md"
    },
    "compatibility": "Designed for Claude Code",
    "allowed_tools": [
      "Read,",
      "Grep"
    ],
    "license": "MIT"
  },
  "instructions": "# Fireflies.ai Reference Architecture\n\n## Overview\n\nProduction architecture for meeting intelligence using Fireflies.ai. Event-driven pipeline: meetings are recorded by the Fireflies bot, transcripts arrive via webhook, then are processed for action items, analytics, and CRM sync.\n\n## Prerequisites\n\n- A documented consent, access, retention, and downstream-sharing policy for each meeting source.\n- Scoped identities separating webhook ingress, transcript processing, storage, and CRM consumers.\n- A policy owner, synthetic fixtures, redacted telemetry, and an emergency disable/rollback path.\n\n## ",
  "cost": {
    "context_tokens": 2393
  }
}

Fetch it by URL: GET /api/v1/registry/jeremylongshore-tons-of-skills-marketplace-fireflies-ref-2e0089/manifest?version=1.0.0

Reviews

Star ratings from people who tried it. One review per account; edit yours any time.

No reviews yet. Install it, try it, and be the first to rate it.