import { config } from 'dotenv'; import { resolve } from 'path'; config({ path: resolve(process.cwd(), '.env.local') }); import { exportGoogleDocPlain, exportGoogleDocHtml, upsertSeguimientoRows, patchSuperhumanIntegration, } from '../src/lib/superhuman-docs'; import { getValidAccessToken } from '../src/lib/google-drive'; const BPS = '8bec977a-6032-4759-aa7f-b5042081f450'; const FILE = '1uDnRPWf1Dqx5b9L3TuhfvutyZpSaifz7YFNrRy_eBhw'; const DOC = '7TGywaNiUY'; function parseDayLabel(raw: string): { dateIso: string; label: string } | null { const m = raw.trim().match(/^(\d{1,2})[\/.\-](\d{1,2})[\/.\-](\d{2,4})$/); if (!m) return null; let y = Number(m[3]); const mo = Number(m[2]); const d = Number(m[1]); if (y < 100) y += 2000; if (y < 2000 || y > 2100 || mo < 1 || mo > 12 || d < 1 || d > 31) return null; return { dateIso: `${y}-${String(mo).padStart(2, '0')}-${String(d).padStart(2, '0')}`, label: `${d}/${mo}/${String(y).slice(2)}`, }; } function splitNotesByDay(text: string) { const clean = text.replace(/^\uFEFF/, '').replace(/\r\n/g, '\n'); const dayRe = /^(?:#{1,4}\s*)?(\d{1,2})[\/.\-](\d{1,2})[\/.\-](\d{2,4})\s*$/; const lines = clean.split('\n'); const hits: { idx: number; label: string; dateIso: string }[] = []; for (let i = 0; i < lines.length; i++) { const m = lines[i].trim().match(dayRe); if (!m) continue; const parsed = parseDayLabel(`${m[1]}/${m[2]}/${m[3]}`); if (!parsed) continue; hits.push({ idx: i, ...parsed }); } if (!hits.length) return [] as { dateIso: string; label: string; body: string }[]; const sections: { dateIso: string; label: string; body: string }[] = []; for (let h = 0; h < hits.length; h++) { const start = hits[h].idx + 1; const end = h + 1 < hits.length ? hits[h + 1].idx : lines.length; const body = lines .slice(start, end) .join('\n') .replace(/^\n+/, '') .replace(/\n{3,}/g, '\n\n') .trim(); if (!body) continue; sections.push({ dateIso: hits[h].dateIso, label: hits[h].label, body }); } sections.sort((a, b) => b.dateIso.localeCompare(a.dateIso)); return sections; } async function exportViaDownload(fileId: string, mime: string) { const token = await getValidAccessToken(); const url = `https://www.googleapis.com/drive/v3/files/${encodeURIComponent(fileId)}/export?mimeType=${encodeURIComponent(mime)}`; const r = await fetch(url, { headers: { Authorization: `Bearer ${token}` }, }); if (!r.ok) throw new Error(`${mime} ${r.status}: ${(await r.text()).slice(0, 200)}`); return await r.text(); } async function main() { let plain = ''; try { plain = await exportGoogleDocPlain(FILE); console.log('plain via helper', plain.length); } catch (e) { console.log('plain helper fail', e instanceof Error ? e.message : e); } if (!plain) { try { plain = await exportViaDownload(FILE, 'text/plain'); console.log('plain via download', plain.length); } catch (e) { console.log('plain download fail', e instanceof Error ? e.message : e); } } try { const html = await exportGoogleDocHtml(FILE); console.log('html ok', html.length); } catch (e) { console.log('html fail', e instanceof Error ? e.message : e); } if (!plain) throw new Error('no plain export'); console.log('--- sample ---\n', plain.slice(0, 2000)); const secs = splitNotesByDay(plain); console.log('sections', secs.length, secs.slice(0, 8).map((s) => s.label)); const now = new Date().toISOString(); const rows = secs.slice(0, 120).map((sec) => { const firstLine = sec.body .split('\n') .map((l) => l.replace(/^[\s*•\-]+/, '').trim()) .find((l) => l.length > 8) || ''; return { tenant_id: BPS, source: 'superhuman' as const, entry_type: 'meeting' as const, external_id: `gdoc:${FILE}:${sec.dateIso}`, title: `Seguimiento · ${sec.label}`, summary: firstLine.slice(0, 220) || null, body_md: `
${sec.body
.replace(/&/g, '&')
.replace(//g, '>')}`,
browser_link: `https://docs.google.com/document/d/${FILE}/edit`,
metrics: {},
occurred_at: `${sec.dateIso}T12:00:00.000Z`,
synced_at: now,
updated_at: now,
};
});
const n = await upsertSeguimientoRows(rows);
await patchSuperhumanIntegration(BPS, {
status: 'connected',
external_account_id: DOC,
label: '01.BLUE PARROT SCHOOL',
last_sync_at: now,
error_message: null,
meta: {
doc_name: '01.BLUE PARROT SCHOOL',
gdoc_id: FILE,
gdoc_days: n,
synced_at: now,
},
});
console.log('upserted day notes', n);
}
main().catch((e) => {
console.error(e);
process.exit(1);
});