-
Notifications
You must be signed in to change notification settings - Fork 5.5k
Enhance Gmail component with thread message listing functionality #18984
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Enhance Gmail component with thread message listing functionality #18984
Conversation
- Added a new action to list messages within a specific thread. - Introduced `listThreads` and `getThread` methods to facilitate thread message retrieval. - Updated version to 1.4.0 to reflect the new features.
|
The latest updates on your projects. Learn more about Vercel for GitHub. 2 Skipped Deployments
|
WalkthroughAdds a new Gmail action that lists messages in a thread, introduces Changes
Sequence Diagram(s)sequenceDiagram
autonumber
actor User
participant Workflow
participant Action as list-thread-messages
participant GmailApp as gmail.app
participant GmailAPI as Gmail API
User->>Workflow: Trigger action with threadId
Workflow->>Action: run({ $ })
Action->>GmailApp: getThread({ threadId })
GmailApp->>GmailAPI: users.threads.get(threadId)
GmailAPI-->>GmailApp: thread object (includes messages[])
GmailApp-->>Action: thread (with messages)
Action->>Action: compute count & export summary
Action-->>Workflow: return messages[]
Workflow-->>User: messages list + summary
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~20 minutes
Suggested reviewers
Pre-merge checks and finishing touches❌ Failed checks (2 warnings)
✅ Passed checks (3 passed)
✨ Finishing touches
🧪 Generate unit tests (beta)
Comment |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 1
📜 Review details
Configuration used: CodeRabbit UI
Review profile: ASSERTIVE
Plan: Pro
📒 Files selected for processing (3)
components/gmail/actions/list-thread-messages/list-thread-messages.mjs(1 hunks)components/gmail/gmail.app.mjs(3 hunks)components/gmail/package.json(1 hunks)
🧰 Additional context used
🧠 Learnings (1)
📚 Learning: 2024-10-08T15:33:38.240Z
Learnt from: GTFalcao
Repo: PipedreamHQ/pipedream PR: 12731
File: components/hackerone/actions/get-members/get-members.mjs:3-28
Timestamp: 2024-10-08T15:33:38.240Z
Learning: When exporting a summary message in the `run` method of an action, ensure the message is correctly formatted. For example, in the `hackerone-get-members` action, the correct format is `Successfully retrieved ${response.data.length} members`.
Applied to files:
components/gmail/actions/list-thread-messages/list-thread-messages.mjs
🧬 Code graph analysis (1)
components/gmail/gmail.app.mjs (1)
components/gmail/actions/get-send-as-alias/get-send-as-alias.mjs (1)
constants(28-31)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (4)
- GitHub Check: Publish TypeScript components
- GitHub Check: pnpm publish
- GitHub Check: Verify TypeScript components
- GitHub Check: Lint Code Base
🔇 Additional comments (6)
components/gmail/package.json (1)
3-3: LGTM! Version bump is appropriate.The version bump from 1.3.5 to 1.4.0 correctly follows semantic versioning for the addition of new thread listing functionality.
components/gmail/gmail.app.mjs (2)
169-195: LGTM! Thread selection prop follows established patterns.The
threadIdpropDefinition correctly implements:
- Dynamic options with pagination support via
nextPageToken- Appropriate error handling (returns empty array on failure, consistent with
attachmentIdprop)- Thread listing via the new
listThreadsmethod
451-457: LGTM! Method follows established patterns.The
listThreadsmethod correctly follows the same pattern aslistMessagesandlistHistory, properly integrating with the Gmail API client.components/gmail/actions/list-thread-messages/list-thread-messages.mjs (3)
3-13: LGTM! Action metadata is well-defined.The metadata correctly describes a read-only, non-destructive action with appropriate documentation references.
14-22: LGTM! Props correctly reference the Gmail app and threadId propDefinition.
23-33: LGTM! Run method is well-implemented.The implementation correctly:
- Fetches the thread using the Gmail app's
getThreadmethod- Handles pluralization appropriately
- Exports a properly formatted summary message (consistent with codebase patterns)
- Returns the messages array as expected
Based on learnings.
- Bumped version numbers for various actions, including: - Add Label to Email (0.0.14 to 0.0.15) - Approve Workflow (0.0.11 to 0.0.12) - Archive Email (0.0.9 to 0.0.10) - Create Draft (0.1.9 to 0.1.10) - Create Label (0.0.3 to 0.0.4) - Delete Email (0.0.3 to 0.0.4) - Download Attachment (0.0.14 to 0.0.15) - Find Email (0.1.8 to 0.1.9) - Get Send As Alias (0.0.3 to 0.0.4) - List Labels (0.0.10 to 0.0.11) - List Send As Aliases (0.0.3 to 0.0.4) - Remove Label from Email (0.0.12 to 0.0.13) - Send Email (0.2.1 to 0.2.2) - Update Org Signature (0.0.13 to 0.0.14) - Update Primary Signature (0.0.13 to 0.0.14) - New Attachment Received (0.2.2 to 0.2.3) - New Email Matching Search (0.1.2 to 0.1.3) - New Email Received (0.3.2 to 0.3.3) - New Labeled Email (0.1.2 to 0.1.3) - New Sent Email (0.1.2 to 0.1.3)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 2
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (8)
components/gmail/actions/list-send-as-aliases/list-send-as-aliases.mjs (1)
22-22: Harden $summary when sendAs is undefinedAvoid “undefined send as aliases” in summaries by defaulting length to 0.
- $.export("$summary", `Successfully retrieved ${response.sendAs?.length} send as aliases`); + $.export("$summary", `Successfully retrieved ${response.sendAs?.length ?? 0} send as aliases`);components/gmail/actions/find-email/find-email.mjs (1)
69-121: Push transformed message, not the pre‑transform reference; consider a tiny header helperCurrently you push
messagebefore mutations, relying on object identity for changes to reflect. Push after transformation (or assign to anoutputvariable) for clarity, and add a small helper to DRY header lookups.- const messagesToEmit = []; - for await (let message of this.gmail.getAllMessages(messageIds)) { - messagesToEmit.push(message); + const messagesToEmit = []; + const getHeader = (msg, name) => + msg.payload?.headers?.find((h) => h.name?.toLowerCase() === name)?.value; + for await (let message of this.gmail.getAllMessages(messageIds)) { - const messageIdHeader = message.payload?.headers?.find( - (h) => h.name.toLowerCase() === "message-id", - ); - if (messageIdHeader) { - message.message_id = messageIdHeader.value.replace(/[<>]/g, ""); - } + const messageIdHeader = getHeader(message, "message-id"); + if (messageIdHeader) { + message.message_id = messageIdHeader.replace(/[<>]/g, ""); + } if (message.internalDate) { message.date = new Date(parseInt(message.internalDate)).toISOString(); } - const senderHeader = message.payload?.headers?.find( - (h) => h.name.toLowerCase() === "from", - ); - if (senderHeader) { - message.sender = senderHeader.value; - } + const senderHeader = getHeader(message, "from"); + if (senderHeader) message.sender = senderHeader; - const recipientHeader = message.payload?.headers?.find( - (h) => h.name.toLowerCase() === "to", - ); - if (recipientHeader) { - message.recipient = recipientHeader.value; - } + const recipientHeader = getHeader(message, "to"); + if (recipientHeader) message.recipient = recipientHeader; - const subjectHeader = message.payload?.headers?.find( - (h) => h.name.toLowerCase() === "subject", - ); - if (subjectHeader) { - message.subject = subjectHeader.value; - } + const subjectHeader = getHeader(message, "subject"); + if (subjectHeader) message.subject = subjectHeader; - if (this.metadataOnly) { - delete message.payload; - delete message.snippet; - } else { - const parsedMessage = utils.validateTextPayload(message, this.withTextPayload); - if (parsedMessage) { - message = parsedMessage; - } else { - if (message.payload?.body?.data && !Array.isArray(message.payload.parts)) { - message.payload.body.text = utils.decodeBase64Url(message.payload.body.data); - } - if (Array.isArray(message.payload?.parts)) { - utils.attachTextToParts(message.payload.parts); - } - } - } + let output = message; + if (this.metadataOnly) { + delete output.payload; + delete output.snippet; + } else { + const parsed = utils.validateTextPayload(output, this.withTextPayload); + if (parsed) { + output = parsed; + } else { + if (output.payload?.body?.data && !Array.isArray(output.payload.parts)) { + output.payload.body.text = utils.decodeBase64Url(output.payload.body.data); + } + if (Array.isArray(output.payload?.parts)) { + utils.attachTextToParts(output.payload.parts); + } + } + } + messagesToEmit.push(output); }components/gmail/actions/create-label/create-label.mjs (2)
60-74: Returnresponse.datainstead of the raw HTTP response.Stabilizes the public output and matches common Pipedream patterns.
- const response = await this.gmail._client().users.labels.create({ + const response = await this.gmail._client().users.labels.create({ userId: constants.USER_ID, requestBody: { name: this.name, messageListVisibility: this.messageListVisibility, labelListVisibility: this.labelListVisibility, color: { textColor: this.textColor, backgroundColor: this.backgroundColor, }, }, - }); - $.export("$summary", `Successfully created label: ${this.name}`); - return response; + }); + $.export("$summary", `Successfully created label: ${this.name}`); + return response.data;
23-36: Consider making label colors optional or validate hex format.Gmail allows creating labels without a color; requiring both may reduce usability. If kept required, validate hex strings (
^#(?:[0-9a-fA-F]{6})$) to avoid API errors.components/gmail/sources/new-attachment-received/new-attachment-received.mjs (2)
72-75: Use a delimiter in meta id to avoid ambiguous concatenation.- id: `${message.id}${attachment.partId}`, + id: `${message.id}-${attachment.partId}`,
88-93: Decode Gmail attachment data as base64url for reliability.
Gmail returns base64url; direct base64 can fail on '-'/'_'.- const buffer = Buffer.from(messageAttachment.data, "base64"); + const base64 = messageAttachment.data.replace(/-/g, "+").replace(/_/g, "/"); + const buffer = Buffer.from(base64, "base64");components/gmail/sources/new-labeled-email/new-labeled-email.mjs (1)
40-43: Fix stray quote in summary string.- summary: `A new message with ID: ${message.id} was labeled"`, + summary: `A new message with ID: ${message.id} was labeled`,components/gmail/sources/new-email-received/new-email-received.mjs (1)
671-679: Guard against NaN when computing startHistoryId (first webhook delivery before timer init).
If lastProcessedHistoryId is unset, Math.min(NaN, x) yields NaN. Default to receivedHistoryId.- let startHistoryId = Math.min( - parseInt(lastProcessedHistoryId), - parseInt(receivedHistoryId), - ); + const lph = parseInt(lastProcessedHistoryId); + const rh = parseInt(receivedHistoryId); + let startHistoryId = Number.isNaN(lph) ? rh : Math.min(lph, rh);
📜 Review details
Configuration used: CodeRabbit UI
Review profile: ASSERTIVE
Plan: Pro
📒 Files selected for processing (20)
components/gmail/actions/add-label-to-email/add-label-to-email.mjs(1 hunks)components/gmail/actions/approve-workflow/approve-workflow.mjs(1 hunks)components/gmail/actions/archive-email/archive-email.mjs(1 hunks)components/gmail/actions/create-draft/create-draft.mjs(1 hunks)components/gmail/actions/create-label/create-label.mjs(1 hunks)components/gmail/actions/delete-email/delete-email.mjs(1 hunks)components/gmail/actions/download-attachment/download-attachment.mjs(1 hunks)components/gmail/actions/find-email/find-email.mjs(1 hunks)components/gmail/actions/get-send-as-alias/get-send-as-alias.mjs(1 hunks)components/gmail/actions/list-labels/list-labels.mjs(1 hunks)components/gmail/actions/list-send-as-aliases/list-send-as-aliases.mjs(1 hunks)components/gmail/actions/remove-label-from-email/remove-label-from-email.mjs(1 hunks)components/gmail/actions/send-email/send-email.mjs(1 hunks)components/gmail/actions/update-org-signature/update-org-signature.mjs(1 hunks)components/gmail/actions/update-primary-signature/update-primary-signature.mjs(1 hunks)components/gmail/sources/new-attachment-received/new-attachment-received.mjs(1 hunks)components/gmail/sources/new-email-matching-search/new-email-matching-search.mjs(1 hunks)components/gmail/sources/new-email-received/new-email-received.mjs(1 hunks)components/gmail/sources/new-labeled-email/new-labeled-email.mjs(1 hunks)components/gmail/sources/new-sent-email/new-sent-email.mjs(1 hunks)
🧰 Additional context used
🧠 Learnings (2)
📚 Learning: 2025-10-20T01:01:02.970Z
Learnt from: js07
Repo: PipedreamHQ/pipedream PR: 18744
File: components/slack_v2/actions/send-large-message/send-large-message.mjs:49-64
Timestamp: 2025-10-20T01:01:02.970Z
Learning: In components/slack_v2/actions/send-large-message/send-large-message.mjs, the metadata_event_payload prop is typed as string, so the code only needs to handle string-to-JSON parsing and does not need to handle object inputs.
Applied to files:
components/gmail/actions/approve-workflow/approve-workflow.mjs
📚 Learning: 2024-10-30T15:24:39.294Z
Learnt from: jcortes
Repo: PipedreamHQ/pipedream PR: 14467
File: components/gainsight_px/actions/create-account/create-account.mjs:4-6
Timestamp: 2024-10-30T15:24:39.294Z
Learning: In `components/gainsight_px/actions/create-account/create-account.mjs`, the action name should be "Create Account" instead of "Create Memory".
Applied to files:
components/gmail/actions/create-label/create-label.mjs
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (4)
- GitHub Check: Publish TypeScript components
- GitHub Check: Verify TypeScript components
- GitHub Check: pnpm publish
- GitHub Check: Lint Code Base
🔇 Additional comments (19)
components/gmail/actions/add-label-to-email/add-label-to-email.mjs (1)
7-7: Version bump looks good.
version: "0.0.15"aligns with the coordinated Gmail action release—no further action needed.components/gmail/actions/list-labels/list-labels.mjs (1)
7-7: Version metadata update confirmed.Increment to
0.0.11keeps this action in sync with the Gmail package release set.components/gmail/actions/download-attachment/download-attachment.mjs (1)
10-10: Consistent version increment.Setting
version: "0.0.15"matches the coordinated Gmail action rollout.components/gmail/actions/list-send-as-aliases/list-send-as-aliases.mjs (1)
7-7: Version bump only — OKLooks good. Please confirm this action’s versioning aligns with the Gmail package 1.4.0 release and any changelog entries.
components/gmail/actions/create-draft/create-draft.mjs (1)
9-9: Approve create-draft action version bump to 0.1.10. All Gmail action versions and the component package.json (1.4.0) are consistent.components/gmail/actions/approve-workflow/approve-workflow.mjs (1)
7-7: Version bump only — LGTM.Patch bump from 0.0.11 → 0.0.12 with no logic change is appropriate and aligns with the broader Gmail package version bump.
components/gmail/actions/find-email/find-email.mjs (1)
8-8: Version bump LGTMPatch bump to 0.1.9 with no functional changes. Safe to ship.
components/gmail/actions/archive-email/archive-email.mjs (1)
8-8: Version bump approved
The gmail-archive-email action is correctly set to version 0.0.10, and components/gmail/package.json is at 1.4.0 with all other action metadata versions in place.components/gmail/actions/send-email/send-email.mjs (1)
9-9: Patch bump LGTMVersion updated to 0.2.2 with no functional changes. Semver-appropriate for a metadata-only update.
components/gmail/actions/get-send-as-alias/get-send-as-alias.mjs (1)
8-8: Approve version bump to 0.0.4. No behavioral changes detected.components/gmail/actions/remove-label-from-email/remove-label-from-email.mjs (1)
7-7: Approve version bump. remove-label-from-email action version correctly updated to 0.0.13; no further changes needed.components/gmail/actions/update-primary-signature/update-primary-signature.mjs (1)
7-7: Approve version bump to 0.0.14; independent Gmail actions use separate versions. Confirm if a unified Gmail release is intended before bumping other actions.components/gmail/actions/update-org-signature/update-org-signature.mjs (1)
11-11: LGTM — version bump only.No logic changes detected. Please confirm this action’s version is reflected in the Gmail package release (package.json, changelog/notes) alongside the new thread-listing features to keep the bundle consistent.
components/gmail/actions/delete-email/delete-email.mjs (1)
8-8: Inconsistent Gmail action metadata versions — verify alignmentcomponents/gmail/package.json is at version 1.4.0, but individual action metadata versions vary (delete-email 0.0.4, list-thread-messages 0.0.1, update-primary-signature 0.0.14, etc.); ensure all Gmail actions’
versionfields are aligned per your release policy.components/gmail/sources/new-attachment-received/new-attachment-received.mjs (1)
11-11: LGTM — version bump only.components/gmail/sources/new-labeled-email/new-labeled-email.mjs (1)
11-11: LGTM — version bump only.components/gmail/sources/new-email-received/new-email-received.mjs (1)
18-18: LGTM — version bump only.components/gmail/sources/new-sent-email/new-sent-email.mjs (1)
9-9: LGTM — version bump only.components/gmail/sources/new-email-matching-search/new-email-matching-search.mjs (1)
9-9: LGTM — version bump only.
| name: "Create Label", | ||
| description: "Create a new label in the connected account. [See the documentation](https://developers.google.com/workspace/gmail/api/reference/rest/v1/users.labels/create)", | ||
| version: "0.0.3", | ||
| version: "0.0.4", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🧹 Nitpick | 🔵 Trivial
🧩 Analysis chain
Patch version bump looks good.
No functional changes here; the metadata bump to 0.0.4 is appropriate.
To keep versions consistent across the Gmail package and actions, you can run:
🏁 Script executed:
#!/bin/bash
# Check component package version
jq -r '.version' components/gmail/package.json
# List Gmail actions and their versions
rg -nP --glob 'components/gmail/actions/**/**/*.mjs' -C0 '^\s*version:\s*"[0-9]+\.[0-9]+\.[0-9]+"\s*,?'
# Verify new action exists (from PR context)
fd -a 'list-thread-messages.mjs' components/gmail/actionsLength of output: 1468
Patch version bump is consistent across Gmail actions.
The metadata bump to 0.0.4 aligns with peer actions in components/gmail/actions.
Optional refactors:
- Return
response.datainstead of the full HTTP response for a more stable interface. - Make
textColor/backgroundColoroptional and validate hex codes.
🤖 Prompt for AI Agents
In components/gmail/actions/create-label/create-label.mjs around line 9, update
the action to (1) return response.data instead of the full HTTP response to
provide a stable interface, and (2) make textColor and backgroundColor optional
and validate any provided values as 3- or 6-character hex codes (with optional
leading '#'); if invalid, throw a clear validation error, and if absent omit
them from the request payload or use safe defaults. Ensure any related
types/exports and tests are adjusted to expect response.data.
| ...common, | ||
| key: "gmail-new-sent-email", | ||
| name: "New Sent Email", | ||
| description: "Emit new event for each new email sent. (Maximum of 100 events emited per execution)", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fix typo in description ("emited" → "emitted").
- description: "Emit new event for each new email sent. (Maximum of 100 events emited per execution)",
+ description: "Emit new event for each new email sent. (Maximum of 100 events emitted per execution)",📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| description: "Emit new event for each new email sent. (Maximum of 100 events emited per execution)", | |
| description: "Emit new event for each new email sent. (Maximum of 100 events emitted per execution)", |
🤖 Prompt for AI Agents
In components/gmail/sources/new-sent-email/new-sent-email.mjs around line 8, the
description string contains a typo ("emited"); update the description to use the
correct spelling "emitted" so it reads: 'Emit new event for each new email sent.
(Maximum of 100 events emitted per execution)'. Ensure only the word is
corrected and punctuation/spacing remain unchanged.
Resolves #18923
Summary by CodeRabbit
New Features
Chores