Skip to content

Conversation

@jcortes
Copy link
Collaborator

@jcortes jcortes commented Nov 24, 2025

WHY

Resolves #14949

Summary by CodeRabbit

  • New Features
    • Send individual messages with media attachment support
    • Send messages to groups of recipients
    • Retrieve contact lists from SendBlue
    • Receive inbound messages in real-time via webhooks
    • Poll for incoming messages with customizable filters, ordering, and limits

✏️ Tip: You can customize this high-level summary in your review settings.

@jcortes jcortes self-assigned this Nov 24, 2025
@vercel
Copy link

vercel bot commented Nov 24, 2025

The latest updates on your projects. Learn more about Vercel for GitHub.

2 Skipped Deployments
Project Deployment Preview Comments Updated (UTC)
pipedream-docs Ignored Ignored Nov 24, 2025 10:35pm
pipedream-docs-redirect-do-not-edit Ignored Ignored Nov 24, 2025 10:35pm

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Nov 24, 2025

Walkthrough

Adds a full Sendblue integration: three actions (send message, send group message, get contact list), two sources (webhook-based instant and polling), a fleshed-out app client with HTTP helpers and propDefinitions, and a package.json version/dependency update.

Changes

Cohort / File(s) Change Summary
Action Modules
components/sendblue/actions/send-message/send-message.mjs, components/sendblue/actions/send-group-message/send-group-message.mjs, components/sendblue/actions/get-contact-list/get-contact-list.mjs
Added three new actions. Send Message maps inputs to API fields and calls app.sendMessage. Send Group Message validates groupId or toNumbers, builds payload, and calls app.sendGroupMessage. Get Contact List calls app.getContactList and returns the response; all export metadata, props, annotations, and run handlers.
App Module
components/sendblue/sendblue.app.mjs
Replaced minimal app with a complete client: added propDefinitions, getUrl, getHeaders, _makeRequest, post, and API wrapper methods sendMessage, sendGroupMessage, getContactList, listMessages, addWebhook, deleteWebhook. Centralizes request construction and header/auth handling.
Source Modules
components/sendblue/sources/new-message-received-instant/new-message-received-instant.mjs, components/sendblue/sources/new-message-received/new-message-received.mjs
Added two sources. Instant source registers/unregisters webhooks in activate/deactivate and emits events for inbound messages. Polling source implements deploy/run hooks, persistent state (lastTimestamp, isFirstRun), processEvent to call app.listMessages, filter by timestamp, update state, and emit new messages.
Package Metadata
components/sendblue/package.json
Bumped version 0.0.40.1.0 and added dependencies with "@pipedream/platform": "^3.1.1".

Sequence Diagram(s)

sequenceDiagram
    participant User
    participant Action as Send Message Action
    participant App as sendblue.app
    participant API as Sendblue API

    User->>Action: invoke with props (toNumber, fromNumber, content, ...)
    Action->>Action: validate & map props → payload
    Action->>App: sendMessage({ data })
    App->>App: getHeaders() & getUrl(path)
    App->>API: POST /messages (with payload)
    API-->>App: response
    App-->>Action: return response
    Action->>User: return response and $summary
Loading
sequenceDiagram
    participant Sendblue as Sendblue (Webhook)
    participant Instant as Instant Source
    participant App as sendblue.app

    rect rgb(200,220,255)
    Note over Instant,App: Webhook lifecycle
    Instant->>App: activate() → addWebhook(endpoint)
    App->>Sendblue: POST /webhooks
    Sendblue-->>App: 201 Created
    end

    rect rgb(220,240,220)
    Note over Sendblue,Instant: Real-time inbound message
    Sendblue->>Instant: POST /webhook (message)
    Instant->>Instant: run(event) → generateMeta(message)
    Instant->>Instant: emit(event)
    end

    rect rgb(255,240,200)
    Note over Instant,App: Cleanup
    Instant->>App: deactivate() → deleteWebhook()
    App->>Sendblue: DELETE /webhooks/:id
    Sendblue-->>App: 204 No Content
    end
Loading
sequenceDiagram
    participant Orchestrator
    participant Poll as Polling Source
    participant App as sendblue.app
    participant API as Sendblue API

    rect rgb(200,220,255)
    Note over Orchestrator,Poll: Deploy/init
    Orchestrator->>Poll: deploy()
    Poll->>Poll: processEvent(max) (initial fetch)
    Poll->>App: listMessages(params...)
    App->>API: GET /messages
    API-->>App: messages
    App-->>Poll: messages
    Poll->>Poll: set isFirstRun = false
    end

    rect rgb(220,240,220)
    Note over Orchestrator,Poll: Periodic polling
    Orchestrator->>Poll: run() [timer]
    alt first run
      Poll->>Poll: skip (first run handled at deploy)
    else subsequent
      Poll->>App: listMessages(params with filters)
      App->>API: GET /messages
      API-->>App: messages
      App-->>Poll: messages
      Poll->>Poll: filter by lastTimestamp, emit new items
      Poll->>Poll: update lastTimestamp
    end
    end
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

  • Review focus:
    • components/sendblue/sendblue.app.mjs — verify HTTP helper correctness, auth header construction, error handling, and parameter encoding.
    • components/sendblue/sources/new-message-received/new-message-received.mjs — verify timestamp logic, state persistence, and ordering when filtering/emitting messages.
    • components/sendblue/actions/send-group-message/send-group-message.mjs — validate input validation and payload mapping for toNumbers vs groupId.
    • Webhook lifecycle in new-message-received-instant.mjs — ensure correct registration/deletion and event filtering (presence of from_number).

Pre-merge checks and finishing touches

❌ Failed checks (1 warning, 1 inconclusive)
Check name Status Explanation Resolution
Description check ⚠️ Warning The pull request description is minimal, containing only 'Resolves #14949' without elaborating on the changes, implementation details, or purpose. Expand the description to explain what components were added, key changes made, and how they address the linked issue requirements.
Title check ❓ Inconclusive The title is vague and generic, using only '[Components] sendblue' without specifics about what is being added or changed. Consider using a more descriptive title like 'Add sendblue component with actions and sources' to clearly convey the main changes in the pull request.
✅ Passed checks (3 passed)
Check name Status Explanation
Linked Issues check ✅ Passed The pull request implements all required components: send-message action, get-contact-list action, send-group-message action, and new-message-received-instant source with webhook support as specified in issue #14949.
Out of Scope Changes check ✅ Passed All changes are within scope: the PR adds only Sendblue components (actions, sources, app module, and package.json updates) that directly address the requirements in issue #14949.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch sendblue-new-components

📜 Recent review details

Configuration used: CodeRabbit UI

Review profile: ASSERTIVE

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between eea3464 and 6bb470d.

⛔ Files ignored due to path filters (1)
  • pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml
📒 Files selected for processing (7)
  • components/sendblue/actions/get-contact-list/get-contact-list.mjs (1 hunks)
  • components/sendblue/actions/send-group-message/send-group-message.mjs (1 hunks)
  • components/sendblue/actions/send-message/send-message.mjs (1 hunks)
  • components/sendblue/package.json (2 hunks)
  • components/sendblue/sendblue.app.mjs (1 hunks)
  • components/sendblue/sources/new-message-received-instant/new-message-received-instant.mjs (1 hunks)
  • components/sendblue/sources/new-message-received/new-message-received.mjs (1 hunks)
🧰 Additional context used
🧠 Learnings (7)
📚 Learning: 2024-12-12T19:23:09.039Z
Learnt from: jcortes
Repo: PipedreamHQ/pipedream PR: 14935
File: components/sailpoint/package.json:15-18
Timestamp: 2024-12-12T19:23:09.039Z
Learning: When developing Pipedream components, do not add built-in Node.js modules like `fs` to `package.json` dependencies, as they are native modules provided by the Node.js runtime.

Applied to files:

  • components/sendblue/package.json
📚 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/sendblue/sendblue.app.mjs
  • components/sendblue/sources/new-message-received-instant/new-message-received-instant.mjs
  • components/sendblue/sources/new-message-received/new-message-received.mjs
  • components/sendblue/actions/send-message/send-message.mjs
  • components/sendblue/actions/send-group-message/send-group-message.mjs
📚 Learning: 2025-09-15T22:01:11.472Z
Learnt from: GTFalcao
Repo: PipedreamHQ/pipedream PR: 18362
File: components/leonardo_ai/actions/generate-image/generate-image.mjs:103-105
Timestamp: 2025-09-15T22:01:11.472Z
Learning: In Pipedream components, pipedream/platform's axios implementation automatically excludes undefined values from HTTP requests, so there's no need to manually check for truthiness before including properties in request payloads.

Applied to files:

  • components/sendblue/sendblue.app.mjs
📚 Learning: 2025-06-04T17:52:05.780Z
Learnt from: GTFalcao
Repo: PipedreamHQ/pipedream PR: 16954
File: components/salesloft/salesloft.app.mjs:14-23
Timestamp: 2025-06-04T17:52:05.780Z
Learning: In the Salesloft API integration (components/salesloft/salesloft.app.mjs), the _makeRequest method returns response.data which directly contains arrays for list endpoints like listPeople, listCadences, listUsers, and listAccounts. The propDefinitions correctly call .map() directly on these responses without needing to destructure a nested data property.

Applied to files:

  • components/sendblue/sendblue.app.mjs
📚 Learning: 2024-10-10T19:18:27.998Z
Learnt from: GTFalcao
Repo: PipedreamHQ/pipedream PR: 14265
File: components/the_magic_drip/sources/common.mjs:35-43
Timestamp: 2024-10-10T19:18:27.998Z
Learning: In `components/the_magic_drip/sources/common.mjs`, when processing items in `getAndProcessData`, `savedIds` is intentionally updated with IDs of both emitted and non-emitted items to avoid emitting retroactive events upon first deployment and ensure only new events are emitted as they occur.

Applied to files:

  • components/sendblue/sources/new-message-received/new-message-received.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/sendblue/actions/get-contact-list/get-contact-list.mjs
📚 Learning: 2024-07-04T18:11:59.822Z
Learnt from: GTFalcao
Repo: PipedreamHQ/pipedream PR: 12731
File: components/hackerone/actions/get-members/get-members.mjs:3-28
Timestamp: 2024-07-04T18:11:59.822Z
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/sendblue/actions/get-contact-list/get-contact-list.mjs
  • components/sendblue/actions/send-message/send-message.mjs
  • components/sendblue/actions/send-group-message/send-group-message.mjs
🧬 Code graph analysis (5)
components/sendblue/sendblue.app.mjs (1)
components/gmail/gmail.app.mjs (1)
  • axios (415-423)
components/sendblue/sources/new-message-received-instant/new-message-received-instant.mjs (1)
components/sendblue/sources/new-message-received/new-message-received.mjs (1)
  • meta (173-173)
components/sendblue/sources/new-message-received/new-message-received.mjs (1)
components/sendblue/sources/new-message-received-instant/new-message-received-instant.mjs (2)
  • message (58-58)
  • meta (61-61)
components/sendblue/actions/get-contact-list/get-contact-list.mjs (3)
components/sendblue/actions/send-group-message/send-group-message.mjs (1)
  • response (67-76)
components/sendblue/actions/send-message/send-message.mjs (1)
  • response (64-74)
components/sendblue/sources/new-message-received/new-message-received.mjs (1)
  • response (145-147)
components/sendblue/actions/send-group-message/send-group-message.mjs (3)
components/sendblue/actions/get-contact-list/get-contact-list.mjs (1)
  • response (18-20)
components/sendblue/actions/send-message/send-message.mjs (1)
  • response (64-74)
components/sendblue/sources/new-message-received/new-message-received.mjs (1)
  • response (145-147)
⏰ 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: pnpm publish
  • GitHub Check: Verify TypeScript components
  • GitHub Check: Publish TypeScript components
  • GitHub Check: Lint Code Base
🔇 Additional comments (2)
components/sendblue/package.json (1)

3-17: LGTM! Version bump and dependency addition are appropriate.

The version bump to 0.1.0 correctly reflects the addition of new actions and sources. The @pipedream/platform dependency is properly added to support the expanded integration capabilities.

components/sendblue/sendblue.app.mjs (1)

1-247: LGTM! Comprehensive app implementation with proper HTTP helpers and API methods.

The app module correctly implements:

  • axios integration from @pipedream/platform
  • Rich propDefinitions covering all needed inputs for actions and sources
  • Standardized HTTP helper methods (getUrl, getHeaders, _makeRequest)
  • Clean API method wrappers for messaging, contacts, and webhook management

The structure is consistent with Pipedream patterns and properly supports the actions and sources in this PR.


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 8

📜 Review details

Configuration used: CodeRabbit UI

Review profile: ASSERTIVE

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 6845b85 and eea3464.

⛔ Files ignored due to path filters (1)
  • pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml
📒 Files selected for processing (7)
  • components/sendblue/actions/get-contact-list/get-contact-list.mjs (1 hunks)
  • components/sendblue/actions/send-group-message/send-group-message.mjs (1 hunks)
  • components/sendblue/actions/send-message/send-message.mjs (1 hunks)
  • components/sendblue/package.json (2 hunks)
  • components/sendblue/sendblue.app.mjs (1 hunks)
  • components/sendblue/sources/new-message-received-instant/new-message-received-instant.mjs (1 hunks)
  • components/sendblue/sources/new-message-received/new-message-received.mjs (1 hunks)
🧰 Additional context used
🧠 Learnings (6)
📚 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/sendblue/actions/send-group-message/send-group-message.mjs
  • components/sendblue/sources/new-message-received/new-message-received.mjs
  • components/sendblue/sources/new-message-received-instant/new-message-received-instant.mjs
  • components/sendblue/actions/send-message/send-message.mjs
  • components/sendblue/sendblue.app.mjs
📚 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/sendblue/actions/send-group-message/send-group-message.mjs
  • components/sendblue/actions/send-message/send-message.mjs
📚 Learning: 2024-10-10T19:18:27.998Z
Learnt from: GTFalcao
Repo: PipedreamHQ/pipedream PR: 14265
File: components/the_magic_drip/sources/common.mjs:35-43
Timestamp: 2024-10-10T19:18:27.998Z
Learning: In `components/the_magic_drip/sources/common.mjs`, when processing items in `getAndProcessData`, `savedIds` is intentionally updated with IDs of both emitted and non-emitted items to avoid emitting retroactive events upon first deployment and ensure only new events are emitted as they occur.

Applied to files:

  • components/sendblue/sources/new-message-received/new-message-received.mjs
📚 Learning: 2024-12-12T19:23:09.039Z
Learnt from: jcortes
Repo: PipedreamHQ/pipedream PR: 14935
File: components/sailpoint/package.json:15-18
Timestamp: 2024-12-12T19:23:09.039Z
Learning: When developing Pipedream components, do not add built-in Node.js modules like `fs` to `package.json` dependencies, as they are native modules provided by the Node.js runtime.

Applied to files:

  • components/sendblue/package.json
📚 Learning: 2025-06-04T17:52:05.780Z
Learnt from: GTFalcao
Repo: PipedreamHQ/pipedream PR: 16954
File: components/salesloft/salesloft.app.mjs:14-23
Timestamp: 2025-06-04T17:52:05.780Z
Learning: In the Salesloft API integration (components/salesloft/salesloft.app.mjs), the _makeRequest method returns response.data which directly contains arrays for list endpoints like listPeople, listCadences, listUsers, and listAccounts. The propDefinitions correctly call .map() directly on these responses without needing to destructure a nested data property.

Applied to files:

  • components/sendblue/sendblue.app.mjs
📚 Learning: 2025-09-15T22:01:11.472Z
Learnt from: GTFalcao
Repo: PipedreamHQ/pipedream PR: 18362
File: components/leonardo_ai/actions/generate-image/generate-image.mjs:103-105
Timestamp: 2025-09-15T22:01:11.472Z
Learning: In Pipedream components, pipedream/platform's axios implementation automatically excludes undefined values from HTTP requests, so there's no need to manually check for truthiness before including properties in request payloads.

Applied to files:

  • components/sendblue/sendblue.app.mjs
🧬 Code graph analysis (6)
components/sendblue/actions/send-group-message/send-group-message.mjs (3)
components/sendblue/actions/get-contact-list/get-contact-list.mjs (1)
  • response (18-20)
components/sendblue/actions/send-message/send-message.mjs (1)
  • response (64-74)
components/sendblue/sources/new-message-received/new-message-received.mjs (1)
  • response (145-147)
components/sendblue/sources/new-message-received/new-message-received.mjs (5)
components/zep/actions/get-threads/get-threads.mjs (1)
  • max (39-39)
components/sendblue/actions/get-contact-list/get-contact-list.mjs (1)
  • response (18-20)
components/sendblue/actions/send-group-message/send-group-message.mjs (1)
  • response (68-77)
components/sendblue/actions/send-message/send-message.mjs (1)
  • response (64-74)
components/sendblue/sources/new-message-received-instant/new-message-received-instant.mjs (2)
  • message (61-61)
  • meta (64-64)
components/sendblue/sources/new-message-received-instant/new-message-received-instant.mjs (1)
components/sendblue/sources/new-message-received/new-message-received.mjs (1)
  • meta (173-173)
components/sendblue/actions/send-message/send-message.mjs (3)
components/sendblue/actions/get-contact-list/get-contact-list.mjs (1)
  • response (18-20)
components/sendblue/actions/send-group-message/send-group-message.mjs (1)
  • response (68-77)
components/sendblue/sources/new-message-received/new-message-received.mjs (1)
  • response (145-147)
components/sendblue/actions/get-contact-list/get-contact-list.mjs (3)
components/sendblue/actions/send-group-message/send-group-message.mjs (1)
  • response (68-77)
components/sendblue/actions/send-message/send-message.mjs (1)
  • response (64-74)
components/sendblue/sources/new-message-received/new-message-received.mjs (1)
  • response (145-147)
components/sendblue/sendblue.app.mjs (1)
components/gmail/gmail.app.mjs (1)
  • axios (415-423)
⏰ 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: pnpm publish
  • GitHub Check: Verify TypeScript components
  • GitHub Check: Publish TypeScript components
  • GitHub Check: Lint Code Base
🔇 Additional comments (2)
components/sendblue/package.json (1)

3-17: Package metadata update looks consistent with new Sendblue features

Version bump and the addition of a dependency block are appropriate for the new actions/sources and shared app helpers introduced in this PR. No issues from this diff alone.

components/sendblue/sendblue.app.mjs (1)

203-256: Confirmation: response handling is correct, but API response structure cannot be verified without live testing

I verified the code against Pipedream patterns. The axios from @pipedream/platform follows standard axios behavior: _makeRequest returns the full response object (with .data, .headers, etc.), and the polling source correctly accesses response.data.

This pattern is standard throughout the codebase—confirmed in cisco_webex.app.mjs and esignatures_io.app.mjs, which both follow the same approach.

However, the review's underlying validation concern—confirming that the Sendblue /api/v2/messages endpoint actually returns { data: [...] } format—is valid but cannot be definitively confirmed without calling the live API. The polling source code assumes response.data is an array of message objects with properties like date_updated, date_sent, and from_number, which aligns with typical API response structures.

The implementation is consistent with established Pipedream conventions and should work correctly if the API returns messages in the expected format.

Copy link
Collaborator

@luancazarine luancazarine left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi @jcortes, LGTM! Ready for QA!

@vunguyenhung
Copy link
Collaborator

For Integration QA:

@vunguyenhung
Copy link
Collaborator

Hi everyone, all test cases are passed! Ready for release!

Test reports

@jcortes jcortes merged commit 59e0393 into master Nov 26, 2025
10 checks passed
@jcortes jcortes deleted the sendblue-new-components branch November 26, 2025 15:07
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.

[Components] sendblue

4 participants