Skip to content
Expedify
5 min

Google Docs

When the output is prose that a person has to read, edit and send. The trick is not generating the document — it is leaving the right holes in it.

A sheet is for data somebody will scan. A document is for words somebody will change before they go out — a proposal, a brief, a summary, a contract draft. The difference matters, because a document that arrives finished is a document nobody trusts, and a document that arrives empty is a document nobody uses.

This node writes into Google Docs and shares what it wrote. Seven operations, and two ways of building a document that are worth knowing apart.

Seven operations

create_document

What it does
A new document, optionally with body text placed at the start.

replace_text

What it does
Find literal strings and swap them. The mail-merge operation.

append_text · insert_text

What it does
Add text at the end, or at a position you name. Indices are 1-based, where 1 is the start of the body.

read_document

What it does
Pull the text back out — for summarising, checking or feeding a model.

share_document

What it does
Give somebody access, with a role and an optional note.

list_documents

What it does
Find documents by a query.
Ten of fifteen. Which apply depends on the operation, as with every node in this module.

operation

What it holds
Docs operation to perform One of: read_document · create_document · append_text · insert_text · replace_text · list_documents · share_document Defaults to read_document.

title

What it holds
Title for create_document

initial_text

What it holds
Optional body to insert immediately after create_document

text

What it holds
Text payload for append_text/insert_text

replacements

What it holds
Object mapping search strings to replacement strings

match_case

What it holds
Case-sensitive matching for replace_text Defaults to true.

document_id

What it holds
Doc ID (or template variable) — required for everything except create_document and list_documents

email

What it holds
Recipient email for share_document

role

What it holds
Share role One of: reader · commenter · writer Defaults to reader.

notify

What it holds
Send notification email on share Defaults to true.

Two ways to build a document

Generate it. create_document with initial_text assembled from templates. Fast, and the whole document is defined in the workflow — which means changing the wording means editing a workflow, and nobody outside the team can do that.

Fill it in. Keep a real document with literal tokens in it — {{client_name}}, {{amount}} — and use replace_text to swap them. Slower to set up, and the wording lives in a document your colleagues can edit without touching anything technical.

The node's own guidance is to use unique tokens for templated documents, and the reason is in the next section. For anything a non-technical colleague owns — proposals, offer letters, statements of work — the second approach is the one that survives contact with the business.

A worked example

A deal changes. A draft proposal is written from the deal's own fields and handed to whoever owns it, with edit access and a note saying what still needs doing.

Create, then share

Two operations, joined by the document id the first one returns.

Scroll for all 3 steps →

Three things in that pair are deliberate. The document is shared as writer rather than reader, because the point is for a person to finish it. notify is on, so it appears in their inbox rather than in a folder they never open. And the body contains an explicit TODO where the scope should be.

Leave the holes visible. An automated draft that reads as complete gets sent as complete. A section that says, in plain words, that it has not been written yet is the cheapest safeguard there is — and it is why the message on the share says the same thing again.

The second node reaches back with {{googledocs_1.document_id}}. That id is the only handle on the document, and everything after creation — appending, replacing, sharing — needs it.

What breaks

replace_text matches literal strings, and match_case defaults to on. There is no pattern matching. Replacing Name replaces every occurrence of that exact word wherever it appears — inside “Company Name”, inside a sentence, in a heading. That is why the guidance is to use tokens nobody would type by accident: {{client_name}} appears nowhere in ordinary prose, and Name appears everywhere.

A token you forgot to replace ships as-is. Nothing checks that every placeholder was filled. If your replacements map is missing a key, the document goes out with {{amount}} in it, and the run is green. If the document matters, read it back with read_document and fail the workflow when it still contains a brace.

Insertion indices are positions in a document that is changing. insert_text at index 1 puts text at the very start, which is reliable. Any other number is a position in a document whose length depends on what you already wrote — and two inserts in a row mean the second index is not what you calculated before the first. Prefer append_text and build in order, or write the whole body once in initial_text.

Sharing is an outward-facing action with no undo in the workflow. notify on sends a real email to a real person. Test with your own address, not a colleague's, and remember that a document shared as writer can be changed by them in ways your next replace_text will not expect.

Try it

  1. Run create_document with a title and a couple of lines of initial_text. Note the document_id and the url that come back.
  2. Now make a document by hand containing {{client_name}} twice, and run replace_text against it. Then try the same with the bare word Name and see what else it catches.
  3. Chain it: create, then append_text, then share_document to your own address with role set to reader. Check what the email looks like.
  4. Deliberately omit one key from replacements and read the document. The unreplaced token is what your customer would have received.

Next: Web Scraper — reaching for a page nobody built an integration for, and the twenty-nine fields that exist because the open web does not cooperate.

Related lessons