1 | |
2 |
|
3 | |
4 | * Get Document as Text |
5 | * Get a Google Doc's title and its body as plain text (paragraphs and table cells, in reading order). Reads the first tab unless `tab_id` (from List Tabs) names another one. |
6 | */ |
7 | export async function main( |
8 | auth: RT.Gdocs, |
9 | document_id: string, |
10 | tab_id: string | undefined |
11 | ) { |
12 | const url = new URL(`https://docs.googleapis.com/v1/documents/${document_id}`) |
13 | if (tab_id != null && tab_id !== "") |
14 | url.searchParams.append("includeTabsContent", "true") |
15 | const response = await fetch(url, { |
16 | headers: { |
17 | Authorization: `Bearer ${auth.token}`, |
18 | Accept: "application/json", |
19 | }, |
20 | }) |
21 | if (!response.ok) { |
22 | throw new Error(`${response.status} ${await response.text()}`) |
23 | } |
24 |
|
25 | const doc = await response.json() |
26 | let content = doc.body?.content |
27 | if (tab_id) { |
28 | const tab = findTab(doc.tabs ?? [], tab_id) |
29 | if (!tab) throw new Error(`No tab ${tab_id} in document ${document_id}`) |
30 | content = tab.documentTab?.body?.content |
31 | } |
32 | return { |
33 | document_id: doc.documentId, |
34 | title: doc.title, |
35 | text: toText(content ?? []), |
36 | } |
37 | } |
38 |
|
39 | function findTab(tabs: any[], id: string): any { |
40 | for (const t of tabs) { |
41 | if (t.tabProperties?.tabId === id) return t |
42 | const child = findTab(t.childTabs ?? [], id) |
43 | if (child) return child |
44 | } |
45 | } |
46 |
|
47 | function toText(content: any[]): string { |
48 | let text = "" |
49 | for (const el of content) { |
50 | for (const e of el.paragraph?.elements ?? []) |
51 | text += e.textRun?.content ?? "" |
52 | for (const row of el.table?.tableRows ?? []) |
53 | for (const cell of row.tableCells ?? []) |
54 | text += toText(cell.content ?? []) |
55 | if (el.tableOfContents) text += toText(el.tableOfContents.content ?? []) |
56 | } |
57 | return text |
58 | } |
59 |
|