import { T as TranscriptionChunk, A as ActionItemsFilterOptions, a as AggregatedActionItemsResult, b as ActionItemsMarkdownOptions, M as MeetingInsightsOptions, c as MeetingInsights, d as TranscriptsListParams, S as SearchTranscriptOptions, e as SearchMatch, F as FirefliesClient, W as WebhookPayload, P as ParseOptions, V as VerifyOptions } from './types-D2XsCR5R.js'; export { f as AIApp, g as AIAppsAPI, h as AIAppsListParams, i as ActionItemGrouping, j as ActionItemPreset, k as ActionItemStyle, l as ActiveMeeting, m as ActiveMeetingsParams, n as AddBotParams, o as AggregatedActionItem, p as AudioAPI, B as Bite, q as BiteCaption, r as BiteCreatedFrom, s as BiteSource, t as BiteUser, u as BitesAPI, v as BitesListParams, w as BulkExportParams, x as BulkExportResult, C as CreateBiteParams, D as DayOfWeekStats, y as DayStats, E as ExportActionItemsParams, z as ExportFormat, G as ExportedFile, H as FirefliesConfig, I as MeetingPrivacy, J as MeetingState, K as MeetingsAPI, L as ParticipantStats, R as RateLimitConfig, N as RateLimitState, O as RealtimeAPI, Q as RealtimeConfig, U as RealtimeEvents, X as RealtimeStream, Y as RetryConfig, Z as SearchParams, _ as SearchResults, $ as SpeakerInsightStats, a0 as ThrottleConfig, a1 as TimeGroupStats, a2 as TranscriptGetParams, a3 as TranscriptsAPI, a4 as TranscriptsInsightsParams, a5 as TranscriptsMutationsAPI, a6 as TranscriptsQueryScope, a7 as UploadAudioAttendee, a8 as UploadAudioParams, a9 as UserGroup, aa as UserGroupMember, ab as UserProfile, ac as UserRole, ad as UsersAPI, ae as UsersMutationsAPI, af as WebhookEventType } from './types-D2XsCR5R.js'; import { T as Transcript, a as ActionItemOptions, b as ActionItem, A as ActionItemsResult } from './action-items-CC9yUxHY.js'; export { c as AIAppOutput, d as AIFilter, e as AppsPreview, C as Channel, f as ChannelMember, M as MeetingAnalytics, g as MeetingAttendance, h as MeetingAttendee, i as MeetingInfo, j as Sentence, k as Sentiments, S as Speaker, l as Summary, m as SummarySection, n as SummaryStatus, U as User, o as extractActionItems } from './action-items-CC9yUxHY.js'; import { a as NormalizationOptions, N as NormalizedMeeting } from './speaker-analytics-Dr46LKyP.js'; export { b as NormalizedAnalytics, c as NormalizedAttendee, d as NormalizedChannel, e as NormalizedParticipant, f as NormalizedSentence, g as NormalizedSpeaker, h as NormalizedSummary, S as SpeakerAnalytics, i as SpeakerAnalyticsOptions, j as SpeakerStats, k as analyzeSpeakers } from './speaker-analytics-Dr46LKyP.js'; /** * Base error class for all Fireflies API errors. * All errors include a code for programmatic handling. */ declare class FirefliesError extends Error { readonly code: string; readonly status?: number; constructor(message: string, options?: { status?: number; cause?: unknown; }); } /** * Thrown when the API key is invalid or missing. */ declare class AuthenticationError extends FirefliesError { readonly code = "AUTHENTICATION_ERROR"; constructor(message?: string); } /** * Thrown when rate limits are exceeded. * Check retryAfter for suggested wait time in milliseconds. */ declare class RateLimitError extends FirefliesError { readonly code = "RATE_LIMIT_ERROR"; /** Suggested wait time in milliseconds before retrying. */ readonly retryAfter?: number; constructor(message?: string, retryAfter?: number); } /** * Thrown when a requested resource is not found. */ declare class NotFoundError extends FirefliesError { readonly code = "NOT_FOUND"; constructor(message?: string); } /** * Thrown when request validation fails. */ declare class ValidationError extends FirefliesError { readonly code = "VALIDATION_ERROR"; constructor(message: string); } /** * Thrown when the GraphQL API returns errors. */ declare class GraphQLError extends FirefliesError { readonly code = "GRAPHQL_ERROR"; readonly errors: GraphQLErrorDetail[]; constructor(message: string, errors: GraphQLErrorDetail[]); } /** * Detail from a GraphQL error response. */ interface GraphQLErrorDetail { message: string; path?: string[]; extensions?: Record; } /** * Thrown when a request times out. */ declare class TimeoutError extends FirefliesError { readonly code = "TIMEOUT_ERROR"; constructor(message?: string); } /** * Thrown when a network error occurs. */ declare class NetworkError extends FirefliesError { readonly code = "NETWORK_ERROR"; constructor(message: string, cause?: unknown); } /** * Base error for realtime operations. */ declare class RealtimeError extends FirefliesError { readonly code: string; constructor(message: string, options?: { cause?: unknown; }); } /** * Thrown when realtime connection fails. */ declare class ConnectionError extends RealtimeError { readonly code = "CONNECTION_ERROR"; constructor(message?: string, options?: { cause?: unknown; }); } /** * Thrown when stream is accessed after close. */ declare class StreamClosedError extends RealtimeError { readonly code = "STREAM_CLOSED"; constructor(message?: string); } /** * Thrown when webhook signature verification fails. */ declare class WebhookVerificationError extends FirefliesError { readonly code = "WEBHOOK_VERIFICATION_FAILED"; constructor(message: string); } /** * Thrown when webhook payload parsing fails. */ declare class WebhookParseError extends FirefliesError { readonly code = "WEBHOOK_PARSE_FAILED"; constructor(message: string); } /** * Thrown when no chunks received for configured timeout. * Consumer should check if meeting is still active and decide whether to reconnect. */ declare class ChunkTimeoutError extends RealtimeError { readonly code = "CHUNK_TIMEOUT"; readonly timeoutMs: number; constructor(timeoutMs: number); } /** * A speaker turn containing one or more consecutive chunks from the same speaker. */ interface SpeakerTurn { /** Name of the speaker */ speaker: string; /** Combined text from all chunks in this turn */ text: string; /** Start time of the first chunk in seconds */ startTime: number; /** End time of the last chunk in seconds */ endTime: number; /** Original chunks that make up this turn */ chunks: TranscriptionChunk[]; } /** * The accumulated transcript state. */ interface AccumulatedTranscript { /** Speaker turns in chronological order */ turns: SpeakerTurn[]; /** Unique speaker names in order of first appearance */ speakers: string[]; /** Total word count across all turns */ wordCount: number; /** Duration in seconds from first chunk start to last chunk end */ duration: number; /** Total number of final chunks accumulated */ chunkCount: number; } /** * Accumulates streaming transcription chunks into a coherent transcript. * * Chunks from the same speaker are merged into turns. Statistics like word count * and duration are computed on demand. * * @example * ```typescript * const accumulator = new TranscriptAccumulator(); * * for await (const chunk of client.realtime.stream(meetingId)) { * accumulator.add(chunk); * const transcript = accumulator.getTranscript(); * console.log(`${transcript.speakers.length} speakers, ${transcript.wordCount} words`); * } * * const final = accumulator.getTranscript(); * ``` */ declare class TranscriptAccumulator { private turns; private currentTurn; private seenChunkIds; /** * Add a chunk to the accumulator. * * Only final chunks are accumulated; non-final chunks are ignored. * Duplicate chunk IDs are also ignored. * * @param chunk - The transcription chunk to add */ add(chunk: TranscriptionChunk): void; /** * Get the current accumulated transcript state. * * Statistics are computed on demand to ensure accuracy. * * @returns The accumulated transcript with turns, speakers, and statistics */ getTranscript(): AccumulatedTranscript; /** * Clear all accumulated data. * * Useful for resetting the accumulator between sessions. */ clear(): void; private getUniqueSpeakers; private computeWordCount; private computeDuration; } /** * Filter action items by criteria. * * Filters can be combined with AND logic - items must match all specified criteria. * * @param items - Action items to filter * @param options - Filter criteria * @returns Filtered items preserving original type and order * * @example * ```typescript * // Filter to Alice's items with due dates * const filtered = filterActionItems(items, { * assignees: ['Alice'], * datedOnly: true, * }); * ``` */ declare function filterActionItems(items: T[], options: ActionItemsFilterOptions): T[]; /** * Aggregate action items from multiple transcripts. * * Extracts action items from each transcript and attaches source metadata * (transcript ID, title, date) to each item. * * @param transcripts - Transcripts to extract action items from * @param extractionOptions - Options for action item extraction * @param filterOptions - Options to filter extracted items * @returns Aggregated result with items and statistics * * @example * ```typescript * const result = aggregateActionItems(transcripts); * console.log(`${result.totalItems} items from ${result.transcriptsProcessed} meetings`); * ``` */ declare function aggregateActionItems(transcripts: Transcript[], extractionOptions?: ActionItemOptions, filterOptions?: ActionItemsFilterOptions): AggregatedActionItemsResult; /** * Format action items as Markdown. * * Supports multiple styles (checkbox, bullet, numbered), grouping options, * inline metadata, and presets for popular tools. * * @param result - Action items result (single or aggregated) * @param options - Formatting options * @returns Formatted markdown string * * @example * ```typescript * const markdown = formatActionItemsMarkdown(result, { * style: 'checkbox', * groupBy: 'assignee', * includeSummary: true, * preset: 'notion', * }); * ``` */ declare function formatActionItemsMarkdown(result: ActionItemsResult | AggregatedActionItemsResult, options?: ActionItemsMarkdownOptions): string; /** * Options for batch processing. */ interface BatchOptions { /** * Number of concurrent operations. * Currently only sequential (1) is supported. * @default 1 */ concurrency?: number; /** * Delay in milliseconds between operations. * @default 100 */ delayMs?: number; /** * Whether to automatically handle rate limit errors. * When true, waits for retryAfter and retries. * @default true */ handleRateLimit?: boolean; /** * Maximum number of rate limit retries per item. * @default 3 */ maxRateLimitRetries?: number; } /** * Result of a batch operation on a single item. */ type BatchResult = { item: T; result: R; error?: never; } | { item: T; result?: never; error: Error; }; /** * Process items in batch with rate limiting and error handling. * * Yields results as they complete, allowing streaming processing. * On rate limit errors, automatically waits and retries if handleRateLimit is true. * * @param items - Items to process (sync or async iterable) * @param processor - Function to process each item * @param options - Batch processing options * @returns AsyncIterable yielding results (success or error) for each item * * @example * ```typescript * import { batch, FirefliesClient } from 'fireflies-api'; * * const client = new FirefliesClient({ apiKey: 'your-api-key' }); * const ids = ['id1', 'id2', 'id3']; * * for await (const result of batch(ids, id => client.transcripts.get(id))) { * if (result.error) { * console.error(`Failed to fetch ${result.item}: ${result.error.message}`); * } else { * console.log(`Got ${result.result.title}`); * } * } * ``` */ declare function batch(items: Iterable | AsyncIterable, processor: (item: T) => Promise, options?: BatchOptions): AsyncIterable>; /** * Process all items in batch and collect results. * * Unlike the streaming `batch()`, this waits for all items to complete * and returns results as an array. * * @param items - Array of items to process * @param processor - Function to process each item * @param options - Batch processing options plus continueOnError * @returns Array of successful results. When continueOnError is false, results * match input order. When true, failed items are omitted (array may be shorter). * @throws First error encountered if continueOnError is false (default) * * @example * ```typescript * import { batchAll, FirefliesClient } from 'fireflies-api'; * * const client = new FirefliesClient({ apiKey: 'your-api-key' }); * const ids = ['id1', 'id2', 'id3']; * * // Throws on first error * const transcripts = await batchAll(ids, id => client.transcripts.get(id)); * * // Continues on error, collects successful results * const results = await batchAll( * ids, * id => client.transcripts.get(id), * { continueOnError: true } * ); * ``` */ declare function batchAll(items: T[], processor: (item: T) => Promise, options?: BatchOptions & { continueOnError?: boolean; }): Promise; /** * Statistics about meetings for a digest period. */ interface DigestStats { /** Total number of meetings */ totalMeetings: number; /** Total duration in minutes */ totalMinutes: number; /** Average meeting duration in minutes */ averageDuration: number; /** Day with most meetings (e.g., "monday") */ busiestDay: string; /** Meeting count by day of week */ meetingsByDay: Record; } /** * A highlight extracted from a meeting summary. */ interface DigestHighlight { /** ID of the source transcript */ meetingId: string; /** Title of the meeting */ meetingTitle: string; /** Date of the meeting (ISO 8601) */ meetingDate: string; /** Key points extracted from the summary */ keyPoints: string[]; /** Decisions made in the meeting */ decisions: string[]; } /** * Participant statistics across the digest period. */ interface DigestParticipant { /** Normalized email address */ email: string; /** Display name (if available) */ name: string; /** Number of meetings attended */ meetingCount: number; /** Total time in meetings (minutes) */ totalMinutes: number; } /** * Action item with source meeting context. */ interface DigestActionItem extends ActionItem { /** ID of the source transcript */ transcriptId: string; /** Title of the source meeting */ transcriptTitle: string; /** Date of the source meeting (ISO 8601) */ transcriptDate: string; } /** * Participant info with email and resolved name. */ interface DigestParticipantInfo { /** Email address */ email: string; /** Display name (from meeting_attendees or extracted from email) */ name: string; } /** * Action items grouped by meeting with meeting context. */ interface DigestMeetingWithActionItems { /** Transcript ID */ id: string; /** Meeting title */ title: string; /** Meeting date (ISO 8601) */ date: string; /** Duration in minutes */ duration: number; /** List of participants with name and email */ participants: DigestParticipantInfo[]; /** Action items from this meeting */ items: DigestActionItem[]; } /** * Aggregated action items organized for digest display. */ interface DigestActionItems { /** Total count of action items */ total: number; /** Action items grouped by assignee */ byAssignee: Record; /** Action items grouped by meeting */ byMeeting: DigestMeetingWithActionItems[]; /** Action items without an assignee */ unassigned: DigestActionItem[]; /** Action items with due dates */ withDueDates: DigestActionItem[]; } /** * Summary of a single meeting for digest listing. */ interface DigestMeeting { /** Transcript ID */ id: string; /** Meeting title */ title: string; /** Meeting date (ISO 8601) */ date: string; /** Duration in minutes */ duration: number; /** Number of participants */ participants: number; } /** * Options for building a digest from transcripts. */ interface DigestBuildOptions { /** Include action items section (default: true) */ includeActionItems?: boolean; /** Include highlights section (default: true) */ includeHighlights?: boolean; /** Include statistics section (default: true) */ includeStats?: boolean; /** Include sentiment analysis (default: false) */ includeSentiment?: boolean; /** Group meetings by category (default: 'none') */ groupBy?: 'day' | 'category' | 'participant' | 'none'; } /** * Options for rendering a digest to output. */ interface RenderOptions { /** * Template to use for rendering. * Can be a built-in name ('default', 'compact', 'executive') * or a path to a custom .md template file. */ template?: 'default' | 'compact' | 'executive' | string; } /** * Weekly digest aggregating meeting insights. */ interface WeeklyDigest { /** Date range covered by the digest */ period: { /** Start date (ISO 8601 date string) */ from: string; /** End date (ISO 8601 date string) */ to: string; }; /** Total number of meetings */ totalMeetings: number; /** Total duration across all meetings (minutes) */ totalDuration: number; /** Meeting statistics */ stats: DigestStats; /** Aggregated action items */ actionItems: DigestActionItems; /** Highlights from meetings */ highlights: DigestHighlight[]; /** Participant statistics */ participants: DigestParticipant[]; /** List of meetings in the period */ meetings: DigestMeeting[]; /** Overall sentiment (if enabled) */ sentiment?: { /** Average sentiment score (0-100) */ overall: number; /** Trend compared to previous period */ trend: 'improving' | 'stable' | 'declining'; }; } /** * Calculate meeting statistics from transcripts. Pure function. * * @param transcripts - Array of transcripts to analyze * @returns Statistics including totals, averages, and by-day breakdown * * @example * ```typescript * const stats = calculateStats(transcripts); * console.log(`Busiest day: ${stats.busiestDay}`); * ``` */ declare function calculateStats(transcripts: Transcript[]): DigestStats; /** * Extract highlights from transcripts. Pure function. * * Parses summary.overview to extract key points and decisions from each meeting. * * @param transcripts - Array of transcripts to extract highlights from * @returns Array of highlights with key points and decisions * * @example * ```typescript * const highlights = extractHighlights(transcripts); * for (const h of highlights) { * console.log(`${h.meetingTitle}: ${h.keyPoints.length} key points`); * } * ``` */ declare function extractHighlights(transcripts: Transcript[]): DigestHighlight[]; /** * Aggregate participants from transcripts. Pure function. * * Deduplicates by normalized email, counts meetings and total time per participant. * Looks up participant names from meeting_attendees data. * * @param transcripts - Array of transcripts to aggregate * @returns Array of participant stats sorted by meeting count descending * * @example * ```typescript * const participants = aggregateParticipants(transcripts); * console.log(`Top participant: ${participants[0]?.email}`); * ``` */ declare function aggregateParticipants(transcripts: Transcript[]): DigestParticipant[]; /** * Aggregate action items from transcripts for digest display. Pure function. * * Reuses existing extractActionItems() and groups by assignee, with * separate collections for unassigned and items with due dates. * * @param transcripts - Array of transcripts to aggregate * @returns Aggregated action items organized for digest * * @example * ```typescript * const actionItems = aggregateActionItemsForDigest(transcripts); * console.log(`${actionItems.total} total items`); * console.log(`Unassigned: ${actionItems.unassigned.length}`); * ``` */ declare function aggregateActionItemsForDigest(transcripts: Transcript[]): DigestActionItems; /** * Build a digest from transcripts. Pure function - no API calls. * * Combines all aggregation helpers to produce a complete weekly digest. * * @param transcripts - Array of transcripts to aggregate * @param options - Build options for filtering sections * @returns Weekly digest with stats, action items, highlights, and participants * * @example * ```typescript * const transcripts = await client.transcripts.list({ period: 'last-week' }); * const digest = buildDigest(transcripts, { * includeActionItems: true, * includeHighlights: true, * }); * console.log(`${digest.totalMeetings} meetings`); * ``` */ declare function buildDigest(transcripts: Transcript[], options?: DigestBuildOptions): WeeklyDigest; /** * Render a digest using a template. Pure function. * * @param digest - Digest to render * @param options - Template options (built-in name, file path, or inline template) * @returns Rendered string (markdown) * * @example * ```typescript * const output = renderDigest(digest); // Default * const output = renderDigest(digest, { template: 'compact' }); // Built-in * const output = renderDigest(digest, { template: './es.md' }); // Custom file * const output = renderDigest(digest, { template: '# Custom\n{{totalMeetings}} meetings' }); // Inline * ``` */ declare function renderDigest(digest: WeeklyDigest, options?: RenderOptions): string; /** * Render a digest as HTML. Pure function. * * @param digest - Digest to render * @returns HTML string * * @example * ```typescript * const html = renderDigestHtml(digest); * ``` */ declare function renderDigestHtml(digest: WeeklyDigest): string; /** * Render a template with mustache-like syntax. Pure function. * * Supports: * - Variable substitution: `{{var}}`, `{{a.b.c}}` * - Loops: `{{#items}}...{{/items}}` * - Conditionals: `{{#truthy}}...{{/truthy}}` * - Filters: `{{value | duration}}` * * @param template - Template string with placeholders * @param data - Data object for substitution * @returns Rendered string * * @example * ```typescript * const result = renderTemplate('Hello {{name}}!', { name: 'World' }); * // => 'Hello World!' * ``` */ declare function renderTemplate(template: string, data: Record): string; /** * Extract domain from email address. * * @param email - Email address * @returns Lowercase domain, or empty string if invalid * * @example * ```typescript * extractDomain('user@company.com'); // 'company.com' * extractDomain('User@EXAMPLE.ORG'); // 'example.org' * extractDomain('invalid'); // '' * ``` */ declare function extractDomain(email: string): string; /** * Check if any participant has an email outside the given domain. * * @param participants - List of participant email addresses * @param internalDomain - The internal/company domain to check against * @returns True if at least one participant has a different domain * * @example * ```typescript * hasExternalParticipants(['a@company.com', 'b@external.com'], 'company.com'); // true * hasExternalParticipants(['a@company.com', 'b@company.com'], 'company.com'); // false * ``` */ declare function hasExternalParticipants(participants: string[], internalDomain: string): boolean; /** * Export format types supported by bulk export. */ type ExportFormat = 'markdown' | 'json' | 'txt' | 'csv'; /** * Options for transcriptToText(). */ interface TextExportOptions { /** Include timestamps for each speaker turn. Default: false */ includeTimestamps?: boolean; /** Include meeting metadata header (title, date, participants). Default: true */ includeMetadata?: boolean; } /** * Options for transcriptToCsv(). */ interface CsvExportOptions { /** Include CSV header row. Default: true */ includeHeader?: boolean; /** Field delimiter. Default: ',' */ delimiter?: string; } /** * A file ready for export. */ interface ExportFile { /** Filename with extension */ filename: string; /** File content as string */ content: string; } /** * Convert a transcript to plain text format. * * @param transcript - The transcript to convert * @param options - Formatting options * @returns Plain text string with speaker labels * * @example * ```typescript * import { transcriptToText } from 'fireflies-api'; * * const text = transcriptToText(transcript); * await writeFile('meeting.txt', text); * ``` */ declare function transcriptToText(transcript: Transcript, options?: TextExportOptions): string; /** * Convert a transcript to CSV format with one row per sentence. * * @param transcript - The transcript to convert * @param options - CSV formatting options * @returns CSV string with headers and properly escaped values * * @example * ```typescript * import { transcriptToCsv } from 'fireflies-api'; * * const csv = transcriptToCsv(transcript); * await writeFile('meeting.csv', csv); * ``` */ declare function transcriptToCsv(transcript: Transcript, options?: CsvExportOptions): string; /** * Sanitize a string for use as a filename. * * @param title - The title to sanitize * @returns A filesystem-safe filename * * @example * ```typescript * sanitizeFilename('Weekly Team Standup!') // 'weekly-team-standup' * ``` */ declare function sanitizeFilename(title: string): string; /** * Generate an export filename from a transcript. * * @param transcript - The transcript to generate a filename for * @param extension - File extension (without dot) * @returns Filename in format: YYYY-MM-DD-title.ext * * @example * ```typescript * generateExportFilename(transcript, 'md') * // '2024-01-15-weekly-standup.md' * ``` */ declare function generateExportFilename(transcript: Transcript, extension: string): string; /** * Export a transcript to the specified format. * * @param transcript - The transcript to export * @param format - Target format (markdown, json, txt, csv) * @returns Formatted string content * * @example * ```typescript * const content = await exportTranscript(transcript, 'markdown'); * await writeFile('meeting.md', content); * ``` */ declare function exportTranscript(transcript: Transcript, format: ExportFormat): Promise; /** * Create a zip archive from exported files. * Pure function - returns Buffer, no I/O. * * @param files - Array of files to add to the archive * @returns Promise resolving to zip Buffer * * @example * ```typescript * const files = [ * { filename: 'meeting1.md', content: '# Meeting 1' }, * { filename: 'meeting2.md', content: '# Meeting 2' }, * ]; * const zipBuffer = await createZipArchive(files); * await writeFile('exports.zip', zipBuffer); * ``` */ declare function createZipArchive(files: ExportFile[]): Promise; /** * A question asked by an external participant. */ interface ExternalQuestion { /** The question text */ text: string; /** Name of the speaker who asked the question */ speakerName: string; /** Email of the speaker (if available from attendees) */ speakerEmail?: string; /** Index of the sentence in the transcript */ sentenceIndex: number; /** Start time as decimal seconds string */ startTime: string; /** End time as decimal seconds string */ endTime: string; } /** * Result of finding external participant questions. */ interface ExternalQuestionsResult { /** List of external participants identified */ externalParticipants: Array<{ name: string; email?: string; }>; /** Questions asked by external participants */ questions: ExternalQuestion[]; /** Total count of questions */ totalQuestions: number; } /** * Find questions asked by external participants in a transcript. * * This function analyzes a transcript to identify questions from participants * whose email domains don't match the specified internal domains. * * @param transcript - The transcript to analyze * @param internalDomains - Internal domain(s) to identify internal participants. * Can be a single domain string (e.g., '@mycompany.com' or 'mycompany.com') * or an array of domains. * @returns Object containing external participants, their questions, and count * * @example * ```typescript * const transcript = await client.transcripts.get('id'); * const result = findExternalParticipantQuestions(transcript, '@mycompany.com'); * * console.log(`Found ${result.totalQuestions} questions from external participants`); * for (const q of result.questions) { * console.log(`${q.speakerName}: ${q.text}`); * } * ``` */ declare function findExternalParticipantQuestions(transcript: Transcript, internalDomains: string | string[]): ExternalQuestionsResult; /** * Options for transcriptToMarkdown(). */ interface MarkdownExportOptions { /** Include meeting metadata header (title, date, participants, duration). Default: true */ includeMetadata?: boolean; /** Include AI-generated summary sections. Default: true */ includeSummary?: boolean; /** Include action items section. Default: true */ includeActionItems?: boolean; /** Format for action items: checkbox or plain list. Default: 'checkbox' */ actionItemFormat?: 'checkbox' | 'list'; /** Include timestamps for each sentence. Default: false */ includeTimestamps?: boolean; /** How to format speaker names. Default: 'bold' */ speakerFormat?: 'bold' | 'plain'; /** Group consecutive sentences by same speaker. Default: true */ groupBySpeaker?: boolean; /** Write output to file path (Node.js only). If set, also returns the string. */ outputPath?: string; } /** * Options for chunksToMarkdown(). */ interface ChunksExportOptions { /** Meeting title (chunks don't include metadata). Default: 'Live Transcript' */ title?: string; /** Include timestamps for each chunk. Default: false */ includeTimestamps?: boolean; /** How to format speaker names. Default: 'bold' */ speakerFormat?: 'bold' | 'plain'; /** Group consecutive chunks by same speaker. Default: true */ groupBySpeaker?: boolean; /** Write output to file path (Node.js only). If set, also returns the string. */ outputPath?: string; } /** * Convert a completed Fireflies transcript to well-formatted Markdown. * * @param transcript - The transcript to convert * @param options - Formatting options * @returns Markdown string representation of the transcript * * @example * ```typescript * import { FirefliesClient, transcriptToMarkdown } from 'fireflies-api'; * * const client = new FirefliesClient({ apiKey: 'your-api-key' }); * const transcript = await client.transcripts.get('transcript-id'); * * // Basic usage * const markdown = await transcriptToMarkdown(transcript); * * // With options * const markdown = await transcriptToMarkdown(transcript, { * includeTimestamps: true, * actionItemFormat: 'list', * }); * * // Write to file * const markdown = await transcriptToMarkdown(transcript, { * outputPath: './meeting-notes.md', * }); * ``` */ declare function transcriptToMarkdown(transcript: Transcript, options?: MarkdownExportOptions): Promise; /** * Convert realtime transcription chunks to well-formatted Markdown. * * @param chunks - Array of transcription chunks from realtime stream * @param options - Formatting options * @returns Markdown string representation of the chunks * * @example * ```typescript * import { FirefliesClient, chunksToMarkdown } from 'fireflies-api'; * * const client = new FirefliesClient({ apiKey: 'your-api-key' }); * * // Accumulate chunks from realtime stream * const chunks: TranscriptionChunk[] = []; * for await (const chunk of client.realtime.stream(meetingId)) { * chunks.push(chunk); * } * * // Convert to markdown * const markdown = await chunksToMarkdown(chunks); * * // With options * const markdown = await chunksToMarkdown(chunks, { * title: 'Team Standup', * includeTimestamps: true, * }); * ``` */ declare function chunksToMarkdown(chunks: TranscriptionChunk[], options?: ChunksExportOptions): Promise; /** * Analyze multiple transcripts to compute aggregate meeting statistics. * * Pure function - no API calls, fully testable. Computes duration totals, * day of week distribution, participant counts, speaker talk times, and * time-based groupings. * * @param transcripts - Array of transcripts to analyze * @param options - Analysis options for filtering and grouping * @returns Aggregate meeting insights * * @example * ```typescript * import { FirefliesClient, analyzeMeetings } from 'fireflies-api'; * * const client = new FirefliesClient({ apiKey: 'your-api-key' }); * * // Fetch transcripts * const transcripts: Transcript[] = []; * for await (const t of client.transcripts.listAll({ mine: true })) { * transcripts.push(t); * } * * // Analyze * const insights = analyzeMeetings(transcripts, { * groupBy: 'week', * topSpeakersCount: 5, * }); * * console.log(`${insights.totalMeetings} meetings, ${insights.totalDurationMinutes} minutes total`); * console.log(`Average: ${insights.averageDurationMinutes} minutes`); * ``` */ declare function analyzeMeetings(transcripts: Transcript[], options?: MeetingInsightsOptions): MeetingInsights; /** * Options for fetching transcripts from multiple users. */ interface MultiUserOptions { /** * Whether to deduplicate transcripts by ID across accounts. * Useful when multiple users have access to the same transcripts. * @default true */ deduplicate?: boolean; /** * Filter parameters to apply to each account's transcript listing. * Pagination (skip/limit) is handled automatically. */ filter?: Omit; /** * Delay in milliseconds between yielded transcripts. * Helps throttle processing and reduce memory pressure. * Note: API rate limiting is handled by the underlying client. * @default 100 */ delayMs?: number; } /** * A transcript with source tracking information. */ interface MultiUserTranscript { /** The transcript object */ transcript: Transcript; /** API key used to fetch this transcript (for attribution) */ sourceApiKey: string; /** Index of the API key in the input array */ sourceIndex: number; } /** * Fetch transcripts from multiple Fireflies accounts with deduplication. * * This function creates a client for each API key and iterates through * all transcripts, optionally deduplicating across accounts. * * @param apiKeys - Array of Fireflies API keys * @param options - Configuration options * @returns AsyncIterable yielding transcripts with source tracking * * @example * ```typescript * import { getMeetingsForMultipleUsers } from 'fireflies-api'; * * const apiKeys = [ * process.env.FIREFLIES_API_KEY_USER1!, * process.env.FIREFLIES_API_KEY_USER2!, * ]; * * for await (const { transcript, sourceIndex } of getMeetingsForMultipleUsers(apiKeys)) { * console.log(`[User ${sourceIndex}] ${transcript.title}`); * } * * // With filtering * for await (const item of getMeetingsForMultipleUsers(apiKeys, { * filter: { fromDate: '2024-01-01' }, * deduplicate: true, * })) { * console.log(item.transcript.title); * } * ``` */ declare function getMeetingsForMultipleUsers(apiKeys: string[], options?: MultiUserOptions): AsyncIterable; /** * Options for batch normalization, extending NormalizationOptions. */ interface BatchNormalizationOptions extends NormalizationOptions { /** * Delay between items in ms. * Since normalization is a pure function, this is typically 0. * @default 0 */ delayMs?: number; } /** * Normalize a Fireflies transcript to a provider-agnostic format. * * This function converts Fireflies-specific transcript data to a normalized schema * that can be used across multiple meeting intelligence providers. * * @param transcript - The Fireflies transcript to normalize * @param options - Normalization options * @returns A normalized meeting object * * @example * ```typescript * import { FirefliesClient, normalizeTranscript } from 'fireflies-api'; * * const client = new FirefliesClient({ apiKey: 'your-api-key' }); * const transcript = await client.transcripts.get({ id: 'transcript-id' }); * * const normalized = normalizeTranscript(transcript, { * timeUnit: 'milliseconds', * includeRawData: true, * }); * * console.log(normalized.id); // "fireflies:transcript-id" * console.log(normalized.duration); // in seconds * ``` */ declare function normalizeTranscript(transcript: Transcript, options?: NormalizationOptions): NormalizedMeeting; /** * Create a pre-configured normalizer function. * * Useful when normalizing multiple transcripts with the same options. * * @param options - Normalization options to apply to all transcripts * @returns A function that normalizes transcripts with the configured options * * @example * ```typescript * import { createNormalizer } from 'fireflies-api'; * * const normalizer = createNormalizer({ * timeUnit: 'milliseconds', * includeRawData: false, * }); * * // Reuse with same config * const norm1 = normalizer(transcript1); * const norm2 = normalizer(transcript2); * ``` */ declare function createNormalizer(options?: NormalizationOptions): (transcript: Transcript) => NormalizedMeeting; /** * Normalize multiple transcripts with streaming and error handling. * * Yields a BatchResult for each transcript, capturing any errors * without stopping iteration. * * @param transcripts - Array or async iterable of transcripts to normalize * @param options - Batch normalization options * @returns AsyncIterable yielding BatchResult for each transcript * * @example * ```typescript * import { normalizeTranscripts } from 'fireflies-api'; * * for await (const result of normalizeTranscripts(transcripts)) { * if (result.error) { * console.error(`Failed: ${result.item.id}`, result.error); * } else { * console.log(result.result.id); // "fireflies:..." * } * } * ``` */ declare function normalizeTranscripts(transcripts: Transcript[] | AsyncIterable, options?: BatchNormalizationOptions): AsyncIterable>; /** * Normalize multiple transcripts and collect all results. * * Unlike the streaming `normalizeTranscripts()`, this waits for all items * to complete and returns results as an array. * * @param transcripts - Array or async iterable of transcripts to normalize * @param options - Batch normalization options * @returns Array of BatchResult for each transcript * * @example * ```typescript * import { normalizeTranscriptsAll } from 'fireflies-api'; * * const results = await normalizeTranscriptsAll(transcripts, { * timeUnit: 'milliseconds', * includeRawData: false, * }); * * const successful = results.filter(r => !r.error).map(r => r.result); * const failed = results.filter(r => r.error); * ``` */ declare function normalizeTranscriptsAll(transcripts: Transcript[] | AsyncIterable, options?: BatchNormalizationOptions): Promise[]>; /** * Options for parallel pagination. */ interface ParallelPaginationOptions { /** Pages to fetch concurrently. @default 3 */ concurrency?: number; /** Items per page. @default 50 */ pageSize?: number; /** Delay between fetch starts (ms). @default 100 */ delayMs?: number; } /** * Create an async iterable that paginates through results with concurrent page fetching. * * Fetches multiple pages in parallel while maintaining item order. * Stops when a partial page (< pageSize items) is received. * * @param fetcher - Function that fetches a page of results * @param options - Pagination options * @returns Async iterable yielding items one at a time * * @example * ```typescript * const items = paginateParallel( * (skip, limit) => client.transcripts.list({ skip, limit }), * { concurrency: 3, pageSize: 50 } * ); * * for await (const item of items) { * console.log(item.title); * } * ``` */ declare function paginateParallel(fetcher: (skip: number, limit: number) => Promise, options?: ParallelPaginationOptions): AsyncIterable; /** * Create an async iterable that automatically paginates through results. * * @param fetcher - Function that fetches a page of results * @param pageSize - Number of items per page * @returns Async iterable yielding items one at a time * * @example * ```typescript * const items = paginate( * (skip, limit) => client.transcripts.list({ skip, limit }), * 50 * ); * * for await (const item of items) { * console.log(item.title); * } * ``` */ declare function paginate(fetcher: (skip: number, limit: number) => Promise, pageSize?: number): AsyncIterable; /** * Collect all items from an async iterable into an array. * * @param iterable - Async iterable to collect * @returns Array of all items */ declare function collectAll(iterable: AsyncIterable): Promise; /** * Search helper functions for searching transcript content. */ /** * Search a single transcript for matching sentences. * * This is a pure function with no API calls, making it fully testable. * It searches the transcript's sentences for text matching the query, * optionally filtering by speaker, questions, or tasks. * * @param transcript - The transcript to search * @param options - Search options including query, filters, and context settings * @returns Array of matches with context * * @example * ```typescript * import { searchTranscript } from 'fireflies-api'; * * const matches = searchTranscript(transcript, { * query: 'budget', * speakers: ['Alice'], * filterQuestions: true, * contextLines: 2, * }); * * for (const match of matches) { * console.log(`${match.sentence.speakerName}: ${match.sentence.text}`); * } * ``` */ declare function searchTranscript(transcript: Transcript, options: SearchTranscriptOptions): SearchMatch[]; /** * A transcript with a guaranteed video URL. */ interface TranscriptWithVideo { /** The full transcript object */ transcript: Transcript; /** URL to download video (expires after 24h) */ videoUrl: string; } /** * Iterate through transcripts that have video recordings. * * This function filters transcripts to only yield those with video_url set. * Video recordings require Business plan or higher. * * @param client - FirefliesClient instance * @param options - Optional filter parameters (pagination is handled automatically) * @returns AsyncIterable yielding transcripts with their video URLs * * @example * ```typescript * import { FirefliesClient, getMeetingVideos } from 'fireflies-api'; * * const client = new FirefliesClient({ apiKey: 'your-api-key' }); * * for await (const { transcript, videoUrl } of getMeetingVideos(client)) { * console.log(`${transcript.title}: ${videoUrl}`); * } * * // With filters * for await (const item of getMeetingVideos(client, { * fromDate: '2024-01-01', * mine: true, * })) { * console.log(item.videoUrl); * } * ``` */ declare function getMeetingVideos(client: FirefliesClient, options?: Omit): AsyncIterable; /** * Check if a transcript has a video recording. * * @param transcript - Transcript to check * @returns true if the transcript has a video URL */ declare function hasVideo(transcript: Transcript): transcript is Transcript & { video_url: string; }; /** * Deduplicates items by a key. * Uses a sliding window to avoid unbounded memory growth. */ declare class Deduplicator { private seen; private queue; private maxSize; constructor(maxSize?: number); /** * Check if item is a duplicate and mark as seen. * @param key - Unique key to check * @returns true if duplicate, false if new */ isDuplicate(key: string): boolean; /** * Clear all tracked keys. */ clear(): void; /** * Get current number of tracked keys. */ get size(): number; } /** * Type guard to check if a payload is a valid WebhookPayload. * * @param payload - The payload to validate * @returns true if the payload matches the WebhookPayload structure * * @example * ```typescript * if (isValidWebhookPayload(req.body)) { * // req.body is now typed as WebhookPayload * console.log(req.body.meetingId); * } * ``` */ declare function isValidWebhookPayload(payload: unknown): payload is WebhookPayload; /** * Parse and validate a Fireflies webhook payload. * * Optionally verifies the webhook signature if signature and secret are provided. * * @param payload - The webhook payload to parse * @param options - Optional verification options * @returns The validated WebhookPayload * @throws {WebhookVerificationError} If signature verification fails * @throws {WebhookParseError} If payload structure is invalid * * @example * ```typescript * // Parse without verification * const event = parseWebhookPayload(req.body); * console.log(event.meetingId); * * // Parse with verification * const event = parseWebhookPayload(req.body, { * signature: req.headers['x-hub-signature'], * secret: process.env.WEBHOOK_SECRET, * }); * ``` */ declare function parseWebhookPayload(payload: unknown, options?: ParseOptions): WebhookPayload; /** * Verify the authenticity of a Fireflies webhook using HMAC SHA-256. * * Uses timing-safe comparison to prevent timing attacks. * * @param options - Verification options * @returns true if the signature is valid, false otherwise * * @example * ```typescript * const isValid = verifyWebhookSignature({ * payload: req.body, * signature: req.headers['x-hub-signature'], * secret: process.env.WEBHOOK_SECRET, * }); * * if (!isValid) { * return res.status(401).send('Invalid signature'); * } * ``` */ declare function verifyWebhookSignature(options: VerifyOptions): boolean; export { type AccumulatedTranscript, ActionItem, ActionItemOptions, ActionItemsFilterOptions, ActionItemsMarkdownOptions, ActionItemsResult, AggregatedActionItemsResult, AuthenticationError, type BatchNormalizationOptions, type BatchOptions, type BatchResult, ChunkTimeoutError, type ChunksExportOptions, ConnectionError, type CsvExportOptions, Deduplicator, type DigestActionItem, type DigestActionItems, type DigestBuildOptions, type DigestHighlight, type DigestMeeting, type DigestMeetingWithActionItems, type DigestParticipant, type DigestParticipantInfo, type DigestStats, type ExportFile, type ExternalQuestion, type ExternalQuestionsResult, FirefliesClient, FirefliesError, GraphQLError, type GraphQLErrorDetail, type MarkdownExportOptions, MeetingInsights, MeetingInsightsOptions, type MultiUserOptions, type MultiUserTranscript, NetworkError, NormalizationOptions, NormalizedMeeting, NotFoundError, type ParallelPaginationOptions, ParseOptions, RateLimitError, RealtimeError, type RenderOptions, SearchMatch, SearchTranscriptOptions, type SpeakerTurn, StreamClosedError, type TextExportOptions, TimeoutError, Transcript, TranscriptAccumulator, type TranscriptWithVideo, TranscriptionChunk, TranscriptsListParams, ValidationError, VerifyOptions, WebhookParseError, WebhookPayload, WebhookVerificationError, type WeeklyDigest, aggregateActionItems, aggregateActionItemsForDigest, aggregateParticipants, analyzeMeetings, batch, batchAll, buildDigest, calculateStats, chunksToMarkdown, collectAll, createNormalizer, createZipArchive, exportTranscript, extractDomain, extractHighlights, filterActionItems, findExternalParticipantQuestions, formatActionItemsMarkdown, generateExportFilename, getMeetingVideos, getMeetingsForMultipleUsers, hasExternalParticipants, hasVideo, isValidWebhookPayload, normalizeTranscript, normalizeTranscripts, normalizeTranscriptsAll, paginate, paginateParallel, parseWebhookPayload, renderDigest, renderDigestHtml, renderTemplate, sanitizeFilename, searchTranscript, transcriptToCsv, transcriptToMarkdown, transcriptToText, verifyWebhookSignature };