import { listEndpoint, pageSpec, parseWithAccount } from '../lib/api.ts' import { transcriptToText, type TranscriptItem } from '../lib/transcript.ts' import { NOTE_ID_PATTERN } from '../lib/validate.ts' /** * Fetch a meeting transcript in cursor pages (`GET /v1/notes/{note_id}/transcript`, up to 100 * items per page) — works for transcripts too large for ./notes/get. By default fetches the whole * transcript and returns both the raw items and a readable text rendering. * * @param input.account - Account name (secret `granola-`). Required. @param input.secretName - Secret override. * @param input.noteId - `not_…` id (from ./notes/list). Required. * @param input.format - `'text'` (default: `[m:ss] Speaker: text`, same-speaker lines merged), `'items'` (raw), or `'both'`. * @param input.timestamps - Include `[m:ss]` offsets in text (default true). * @param input.limit - Max items (1-50000, default 50000 = whole transcript). @param input.paginate - Follow cursors (default true). * @param input.cursor - Continue from a previous `cursor`. * @returns `{ account, noteId, count, text?, items?, hasMore, cursor, pages }` * * @example * import transcript from 'kody:@charlesmatte/granola/notes/transcript' * * const t = await transcript({ account: 'work', noteId: 'not_1d3tmYTlCICgjy' }) */ export default async function getGranolaTranscript(input: unknown) { const p = parseWithAccount<{ noteId: string; format?: 'text' | 'items' | 'both'; timestamps?: boolean; limit?: number; cursor?: string; paginate?: boolean }>( input, { noteId: { type: 'string', required: true, pattern: NOTE_ID_PATTERN }, format: { type: 'enum', values: ['text', 'items', 'both'] }, timestamps: { type: 'boolean' }, ...pageSpec(50000), }, 'notes/transcript', ) const r = await listEndpoint(p.acct, { path: `/v1/notes/${p.noteId}/transcript`, itemsKey: 'transcript', limit: p.limit ?? 50000, maxPageSize: 100, cursor: p.cursor, paginate: p.paginate ?? true, }) const format = p.format ?? 'text' return { account: p.acct.account, noteId: p.noteId, count: r.count, ...(format !== 'items' ? { text: transcriptToText(r.items, { timestamps: p.timestamps }) } : {}), ...(format !== 'text' ? { items: r.items } : {}), hasMore: r.hasMore, cursor: r.cursor, pages: r.pages, } }