Skip to content

feat: add Gmail node - #564

Open
cemregonenc wants to merge 1 commit into
kafein-technology:devfrom
cemregonenc:feat/gmail-node
Open

feat: add Gmail node#564
cemregonenc wants to merge 1 commit into
kafein-technology:devfrom
cemregonenc:feat/gmail-node

Conversation

@cemregonenc

@cemregonenc cemregonenc commented Aug 10, 2026

Copy link
Copy Markdown

Summary

  • add the Gmail node with sixteen operations across messages, drafts and labels
  • connect a Google account from the credential card, rather than by pasting a token obtained elsewhere
  • flatten a message into a plain record, and read the text out of one that carries only HTML
  • take the message to act on from the node before, and act on every message that came in where the operation allows it

Depends on #547

The dynamic select field and the array support in the display option fields come from that PR, so this one should be reviewed and merged after it.

Connecting an account

Gmail does not accept a password, so a credential holds a refresh token instead. The authorisation runs here: the credential card carries a Connect button, Google asks which account to use and what it may do, and the tokens come back encrypted into the credential. The Client Secret belongs to the installation and is never shown to anyone connecting an account.

The installation needs GOOGLE_CLIENT_ID and GOOGLE_CLIENT_SECRET set, from a project in the Google Cloud console.

google_oauth.py holds the flow and the token refresh, and recognises the scopes Drive, Sheets and Calendar will need alongside Gmail's, so a later Google node can use the same path.

Notes on the design

The output is flattened. Gmail returns a message as a tree of MIME parts with the body encoded — faithful to what was sent, and of little use to the node downstream. A message comes out as sender, subject, date, body and labels. The full response is still available with Simplify turned off.

HTML is read for its text. A marketing message often carries no plain part at all, and its HTML runs to thousands of lines of layout and tracking. Passing that on buries the few sentences that matter and, where an agent is reading, fills its context with markup. The markup itself is kept in body_html.

Identifiers are not typed by hand. Which Message takes the message from the node before, and can also find one by search. Copying an identifier from one run into the next is no way to build a workflow.

Operations act on everything that came in. Marking one message read is something a person would do in Gmail itself; a workflow earns its place by doing the same to everything a search turned up. Replying is the exception — a reply goes to one message, not to five.

Permanent deletion is left out. Gmail puts it behind full account access rather than the narrower modify scope, and asking every account for the run of the mailbox to serve one operation is out of proportion. Move to Trash reaches the same end, with thirty days to change your mind.

Security

  • addresses are validated before Gmail is asked to, so a typo names the field it was in rather than coming back as a refusal with the whole header quoted
  • Read Only refuses every operation that would change the mailbox, before a connection is opened
  • the refresh token is encrypted with the same key as every other credential and is never returned to the client
  • scopes are fixed to what the node needs, rather than written out by whoever creates the credential

Validation

  • 17 node tests passed, alongside manual runs against a connected Gmail account
  • covered: reading with and without search terms, sending, replying within a conversation, drafts, labels, marking read, moving to and restoring from the bin, address validation, Read Only

Closes #552

- Add `GmailNode` with sixteen operations across messages, drafts and labels.
- Add `google_oauth.py` for the authorisation flow and token refresh, with the scopes Drive, Sheets and Calendar will need recognised alongside Gmail's.
- Add four endpoints to the credentials API so an account is connected from the credential card rather than by pasting a token obtained elsewhere.
- Flatten a message into a plain record. Gmail returns a tree of MIME parts with the body encoded, which is faithful to what was sent but of little use to the node downstream.
- Read the text out of a message carrying only HTML, since a marketing message runs to thousands of lines of markup and passing that on buries the few sentences that matter.
- Take the message to act on from the node before rather than from an identifier typed by hand, and act on every message that came in where the operation allows it.
- Validate addresses before Gmail is asked to, so a typo says which field it was in.
- Extend `displayOptions` evaluation in the textarea, number and JSON editor fields, which had not yet learnt to read a list of values.
- Leave permanent deletion out: Gmail puts it behind full account access rather than the narrower modify scope, and Move to Trash reaches the same end with thirty days to change your mind.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant