Your Week 4 literature summary doc is sitting in Google Docs. Your LinkedIn network doesn't know what you found. In your current workflow, how does that summary become a post?
create_doc from Day 21 creates the document. For sharing findings, I'd open the doc, copy the first paragraph, open LinkedIn, paste it, write a caption, hit post. Five minutes per update, forty minutes a month.
doc_to_post chains GOOGLEDOCS_GET_DOCUMENT_BY_ID and LINKEDIN_CREATE_LINKED_IN_POST in two actions. The Docs response nests paragraphs inside body.content — each element with a paragraph key holds a list of elements, each with a textRun.content string. Extract the first paragraph and you have your post text:
body_content = result.get("body", {}).get("content", [])
first_para = ""
for item in body_content:
runs = item.get("paragraph", {}).get("elements", [])
text = "".join(r.get("textRun", {}).get("content", "") for r in runs).strip()
if text:
first_para = text
breakWhy is the text nested so deeply — body → content → paragraph → elements → textRun → content? Is there a simpler key?
The Docs API was designed for structured editing — each textRun can have independent formatting (bold, italic, link). That nesting is the price of rich text. For plain-text extraction, the loop above handles any document structure. There is no flat text key on the response — you navigate the tree.
So the paragraph nesting is basically HTML DOM but for JSON. I'd rather parse it than copy-paste it every Monday.
Exactly. Once extracted, LINKEDIN_CREATE_LINKED_IN_POST takes a single text field. Pass the first paragraph plus a research framing line:
post_text = first_para + " #research #openscience"
post_result = toolset.execute_action(
Action.LINKEDIN_CREATE_LINKED_IN_POST,
{"text": post_text}
)Literature summary → LinkedIn update in one function call. Every time I finish a review round, the network knows. That's the visibility I've been missing.
One caution: the first paragraph of a Docs file is often a title line or blank line. Preview the extracted text before wiring to production. Run doc_to_post with your own doc ID and check the LinkedIn post before sharing with a research audience.
# 1. Read the doc
doc = toolset.execute_action(
Action.GOOGLEDOCS_GET_DOCUMENT_BY_ID,
{"document_id": doc_id}
)
# 2. Extract first paragraph
body_content = doc.get("body", {}).get("content", [])
first_para = ""
for item in body_content:
runs = item.get("paragraph", {}).get("elements", [])
text = "".join(r.get("textRun", {}).get("content", "") for r in runs).strip()
if text:
first_para = text
break
# 3. Post to LinkedIn
toolset.execute_action(
Action.LINKEDIN_CREATE_LINKED_IN_POST,
{"text": first_para + " #research"}
)body.content is a list of structural elements. Paragraphs carry paragraph.elements, each with textRun.content. Skip items with no paragraph key (e.g. section breaks).
Your Week 4 literature summary doc is sitting in Google Docs. Your LinkedIn network doesn't know what you found. In your current workflow, how does that summary become a post?
create_doc from Day 21 creates the document. For sharing findings, I'd open the doc, copy the first paragraph, open LinkedIn, paste it, write a caption, hit post. Five minutes per update, forty minutes a month.
doc_to_post chains GOOGLEDOCS_GET_DOCUMENT_BY_ID and LINKEDIN_CREATE_LINKED_IN_POST in two actions. The Docs response nests paragraphs inside body.content — each element with a paragraph key holds a list of elements, each with a textRun.content string. Extract the first paragraph and you have your post text:
body_content = result.get("body", {}).get("content", [])
first_para = ""
for item in body_content:
runs = item.get("paragraph", {}).get("elements", [])
text = "".join(r.get("textRun", {}).get("content", "") for r in runs).strip()
if text:
first_para = text
breakWhy is the text nested so deeply — body → content → paragraph → elements → textRun → content? Is there a simpler key?
The Docs API was designed for structured editing — each textRun can have independent formatting (bold, italic, link). That nesting is the price of rich text. For plain-text extraction, the loop above handles any document structure. There is no flat text key on the response — you navigate the tree.
So the paragraph nesting is basically HTML DOM but for JSON. I'd rather parse it than copy-paste it every Monday.
Exactly. Once extracted, LINKEDIN_CREATE_LINKED_IN_POST takes a single text field. Pass the first paragraph plus a research framing line:
post_text = first_para + " #research #openscience"
post_result = toolset.execute_action(
Action.LINKEDIN_CREATE_LINKED_IN_POST,
{"text": post_text}
)Literature summary → LinkedIn update in one function call. Every time I finish a review round, the network knows. That's the visibility I've been missing.
One caution: the first paragraph of a Docs file is often a title line or blank line. Preview the extracted text before wiring to production. Run doc_to_post with your own doc ID and check the LinkedIn post before sharing with a research audience.
# 1. Read the doc
doc = toolset.execute_action(
Action.GOOGLEDOCS_GET_DOCUMENT_BY_ID,
{"document_id": doc_id}
)
# 2. Extract first paragraph
body_content = doc.get("body", {}).get("content", [])
first_para = ""
for item in body_content:
runs = item.get("paragraph", {}).get("elements", [])
text = "".join(r.get("textRun", {}).get("content", "") for r in runs).strip()
if text:
first_para = text
break
# 3. Post to LinkedIn
toolset.execute_action(
Action.LINKEDIN_CREATE_LINKED_IN_POST,
{"text": first_para + " #research"}
)body.content is a list of structural elements. Paragraphs carry paragraph.elements, each with textRun.content. Skip items with no paragraph key (e.g. section breaks).
Create a free account to get started. Paid plans unlock all tracks.