From fireflies-pack
Provides typed GraphQL client patterns for Fireflies.ai API in TypeScript and Python with error handling and convenience methods. Use for integrations and team standards.
npx claudepluginhub jeremylongshore/claude-code-plugins-plus-skills --plugin fireflies-packThis skill is limited to using the following tools:
Production-ready patterns for the Fireflies.ai GraphQL API. Fireflies has no official SDK -- all interaction is via HTTP POST to `https://api.fireflies.ai/graphql`. These patterns provide typed wrappers, error handling, caching, and multi-tenant support.
Configures Fireflies.ai GraphQL API Bearer token authentication, sets .env vars, installs optional Node/Python clients, and verifies connectivity with scripts.
Provides reusable Fathom REST API client patterns in Python and TypeScript for listing meetings, fetching transcripts, and summaries. Use for data pipelines or API wrappers.
Guides Next.js Cache Components and Partial Prerendering (PPR): 'use cache' directives, cacheLife(), cacheTag(), revalidateTag() for caching, invalidation, static/dynamic optimization. Auto-activates on cacheComponents: true.
Share bugs, ideas, or general feedback.
Production-ready patterns for the Fireflies.ai GraphQL API. Fireflies has no official SDK -- all interaction is via HTTP POST to https://api.fireflies.ai/graphql. These patterns provide typed wrappers, error handling, caching, and multi-tenant support.
FIREFLIES_API_KEY environment variable setgraphql-request for typed queries// lib/fireflies-client.ts
const FIREFLIES_API = "https://api.fireflies.ai/graphql";
interface FirefliesError {
message: string;
code?: string;
extensions?: { status: number; helpUrls?: string[] };
}
interface FirefliesResponse<T> {
data?: T;
errors?: FirefliesError[];
}
export class FirefliesClient {
private apiKey: string;
private baseUrl: string;
constructor(apiKey?: string) {
this.apiKey = apiKey || process.env.FIREFLIES_API_KEY!;
this.baseUrl = FIREFLIES_API;
if (!this.apiKey) throw new Error("FIREFLIES_API_KEY is required");
}
async query<T = any>(gql: string, variables?: Record<string, any>): Promise<T> {
const res = await fetch(this.baseUrl, {
method: "POST",
headers: {
"Content-Type": "application/json",
Authorization: `Bearer ${this.apiKey}`,
},
body: JSON.stringify({ query: gql, variables }),
});
const json: FirefliesResponse<T> = await res.json();
if (json.errors?.length) {
const err = json.errors[0];
const error = new Error(`Fireflies: ${err.message}`) as any;
error.code = err.code;
error.status = err.extensions?.status;
throw error;
}
return json.data!;
}
// Convenience methods for common queries
async getUser() {
return this.query<{ user: any }>(`{ user { name email user_id is_admin } }`);
}
async getTranscripts(limit = 20) {
return this.query<{ transcripts: any[] }>(`
query($limit: Int) {
transcripts(limit: $limit) {
id title date duration organizer_email participants
summary { overview action_items keywords }
}
}
`, { limit });
}
async getTranscript(id: string) {
return this.query<{ transcript: any }>(`
query($id: String!) {
transcript(id: $id) {
id title date duration
speakers { id name }
sentences { speaker_name text start_time end_time }
summary { overview action_items keywords short_summary }
analytics {
sentiments { positive_pct negative_pct neutral_pct }
speakers { name duration word_count questions }
}
}
}
`, { id });
}
}
// lib/fireflies.ts
let instance: FirefliesClient | null = null;
export function getFirefliesClient(): FirefliesClient {
if (!instance) {
instance = new FirefliesClient();
}
return instance;
}
const tenantClients = new Map<string, FirefliesClient>();
export function getClientForTenant(tenantId: string): FirefliesClient {
if (!tenantClients.has(tenantId)) {
const apiKey = getTenantApiKey(tenantId); // from your secret store
tenantClients.set(tenantId, new FirefliesClient(apiKey));
}
return tenantClients.get(tenantId)!;
}
import { z } from "zod";
const TranscriptSchema = z.object({
id: z.string(),
title: z.string(),
date: z.string(),
duration: z.number(),
speakers: z.array(z.object({ id: z.string(), name: z.string() })),
summary: z.object({
overview: z.string().nullable(),
action_items: z.array(z.string()).nullable(),
keywords: z.array(z.string()).nullable(),
}).nullable(),
});
type Transcript = z.infer<typeof TranscriptSchema>;
async function getValidatedTranscript(id: string): Promise<Transcript> {
const client = getFirefliesClient();
const { transcript } = await client.getTranscript(id);
return TranscriptSchema.parse(transcript);
}
import os
from typing import Any
import requests
class FirefliesClient:
API_URL = "https://api.fireflies.ai/graphql"
def __init__(self, api_key: str | None = None):
self.api_key = api_key or os.environ["FIREFLIES_API_KEY"]
def query(self, gql: str, variables: dict | None = None) -> dict[str, Any]:
resp = requests.post(
self.API_URL,
json={"query": gql, "variables": variables},
headers={
"Content-Type": "application/json",
"Authorization": f"Bearer {self.api_key}",
},
)
data = resp.json()
if "errors" in data:
raise Exception(f"Fireflies: {data['errors'][0]['message']}")
return data["data"]
def get_transcripts(self, limit: int = 20) -> list[dict]:
result = self.query("""
query($limit: Int) {
transcripts(limit: $limit) {
id title date duration organizer_email
summary { overview action_items keywords }
}
}
""", {"limit": limit})
return result["transcripts"]
def get_transcript(self, transcript_id: str) -> dict:
result = self.query("""
query($id: String!) {
transcript(id: $id) {
id title date duration
speakers { name }
sentences { speaker_name text start_time end_time }
summary { overview action_items keywords }
}
}
""", {"id": transcript_id})
return result["transcript"]
# Usage
client = FirefliesClient()
for t in client.get_transcripts(5):
print(f"{t['title']} - {t['duration']}min")
| Pattern | Use Case | Benefit |
|---|---|---|
| Typed client class | All API calls | Centralized auth and error handling |
| Singleton | Single-tenant apps | Reuse connection, consistent config |
| Factory | Multi-tenant SaaS | Isolated API keys per customer |
| Zod validation | API responses | Runtime type safety, catches schema drift |
Apply patterns in fireflies-core-workflow-a for real-world usage.