0

Get Document as Text

by
Published 21 days ago

Get a Google Doc's title and body as plain text, from the first tab or a given tab.

Script gdocs Verified

The script

Submitted by hugo989 Typescript (fetch-only)
Verified 9 days ago
1
//native
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