Skip to content

Conversation

@luancazarine
Copy link
Collaborator

@luancazarine luancazarine commented Nov 20, 2025

Resolves #13377

Summary by CodeRabbit

  • New Features

    • Added Encharge actions: Add/Update Person, Archive Person, Remove Tags.
    • Added Encharge sources: New Person (instant), Updated Person (instant), Tag Removed (instant) with test event samples and a webhook base that manages activation/deactivation.
    • Encharge app: API wrapper with list/get/add/archive/remove/tag/hook operations, dynamic props for users/tags, parseObject utility and LIMIT constant.
  • Chores

    • Bumped package version to 0.1.0 and added platform dependency.

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

- Added actions for adding/updating a person, archiving a person, and removing tags.
- Introduced new sources for detecting new and updated persons, as well as when tags are removed.
- Updated prop definitions to include user ID and tags for better integration.
- Implemented utility functions for parsing objects and managing API requests.
- Bumped version to 0.1.0 and added dependencies for improved functionality.
@luancazarine luancazarine linked an issue Nov 20, 2025 that may be closed by this pull request
@vercel
Copy link

vercel bot commented Nov 20, 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 21, 2025 4:39pm
pipedream-docs-redirect-do-not-edit Ignored Ignored Nov 21, 2025 4:39pm

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Nov 20, 2025

Walkthrough

Adds a complete Encharge integration: API app wrapper, utilities, webhook lifecycle base, three instant webhook sources (new, updated, tag-removed) with test events, three actions (add/update, archive, remove-tags), constants, and package metadata updates.

Changes

Cohort / File(s) Change Summary
App core
components/encharge/encharge.app.mjs
Implements API abstraction (_apiUrl, _getHeaders, _makeRequest) and concrete methods: getPerson, listPeople, addOrUpdatePerson, archivePerson, removeTag, createHook, deleteHook; adds dynamic propDefinitions (userId, tags).
Actions
components/encharge/actions/add-or-update-person/add-or-update-person.mjs, components/encharge/actions/archive-person/archive-person.mjs, components/encharge/actions/remove-tags/remove-tags.mjs
Adds three actions: add-or-update-person (builds data, calls addOrUpdatePerson), archive-person (requires exactly one of userId/email, calls archivePerson), remove-tags (parses tags, calls removeTag); each exports summaries and returns API responses.
Sources base
components/encharge/sources/common/base.mjs
New shared source base with props (encharge, db, http), webhook lifecycle (activate → createHook + store id, deactivate → read id + deleteHook), _setWebhookId/_getWebhookId helpers, and run({ body }) to emit events.
Sources (instant)
components/encharge/sources/new-person-instant/new-person-instant.mjs, components/encharge/sources/updated-person-instant/updated-person-instant.mjs, components/encharge/sources/tag-removed-from-person-instant/tag-removed-from-person-instant.mjs
Three instant sources extending common base: new-person-instant (event "newUser"), updated-person-instant (event "updatedUser"), tag-removed-from-person-instant (dynamic event by tagId). Each provides generateMeta and getEvent overrides and includes sampleEmit.
Source test events
components/encharge/sources/new-person-instant/test-event.mjs, components/encharge/sources/updated-person-instant/test-event.mjs, components/encharge/sources/tag-removed-from-person-instant/test-event.mjs
Adds sample/test event payloads for each source (eventType, eventPayload, endUserData) to aid testing and sample emits.
Utilities & constants
components/encharge/common/utils.mjs, components/encharge/common/constants.mjs
Adds parseObject(obj) utility (error-tolerant JSON parsing for strings/arrays) and exports LIMIT = 100.
Package
components/encharge/package.json
Bumps version to 0.1.0 and adds dependency @pipedream/platform: ^3.1.1.

Sequence Diagram(s)

sequenceDiagram
    participant User
    participant Source
    participant Base
    participant App
    participant Encharge
    participant DB

    User->>Source: Activate source
    Source->>Base: activate()
    Base->>App: createHook(endpoint, eventType)
    App->>Encharge: POST /hooks
    Encharge-->>App: { subscriptionId }
    Base->>DB: _setWebhookId(subscriptionId)

    Encharge->>Base: Webhook POST (body)
    Base->>Source: run({ body })
    Source->>Source: generateMeta(body)
    Source-->>User: emit(body + metadata)

    User->>Source: Deactivate source
    Source->>Base: deactivate()
    Base->>DB: _getWebhookId()
    Base->>App: deleteHook(subscriptionId)
    App->>Encharge: DELETE /hooks/{id}
Loading
sequenceDiagram
    participant Caller
    participant Action
    participant App
    participant Encharge

    Caller->>Action: Invoke action with props
    Action->>Action: Parse/validate inputs
    alt add-or-update-person
        Action->>App: addOrUpdatePerson({ data })
    else archive-person
        Action->>Action: require XOR(userId, email)
        Action->>App: archivePerson({ params })
    else remove-tags
        Action->>Action: parse tags → CSV
        Action->>App: removeTag({ data })
    end
    App->>Encharge: API request
    Encharge-->>App: response
    Action-->>Caller: return response + summary
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

  • Pay attention to:
    • API request construction and error handling in components/encharge/encharge.app.mjs (_makeRequest, headers, status handling).
    • Webhook lifecycle correctness and persistence in components/encharge/sources/common/base.mjs (activate/deactivate, DB key usage).
    • Input validation in components/encharge/actions/archive-person/archive-person.mjs (mutual exclusivity) and tag parsing in components/encharge/actions/remove-tags/remove-tags.mjs.
    • parseObject edge cases in components/encharge/common/utils.mjs.

Suggested labels

trigger / source

Suggested reviewers

  • michelle0927
  • GTFalcao

Pre-merge checks and finishing touches

❌ Failed checks (1 warning, 1 inconclusive)
Check name Status Explanation Resolution
Description check ⚠️ Warning Description only contains 'Resolves #13377' without explaining the implementation details or fulfilling the template's WHY section. Expand the description to include the WHY section from the template and briefly describe what was implemented.
Title check ❓ Inconclusive Title '13377 components encharge' references the issue but lacks specificity about the main changes being introduced. Use a more descriptive title like 'Add Encharge integration with sources and actions' to better summarize the changeset.
✅ Passed checks (3 passed)
Check name Status Explanation
Linked Issues check ✅ Passed PR successfully implements all required sources (new-person-instant, tag-removed-from-person-instant, updated-person-instant) and actions (archive-person, remove-tag, add-or-update-person) with proper APIs and validation logic.
Out of Scope Changes check ✅ Passed All changes directly support the Encharge integration requirements. Supporting files (utils, constants, app configuration) are necessary dependencies for the action and source implementations.
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 13377-components-encharge

Tip

📝 Customizable high-level summaries are now available in beta!

You can now customize how CodeRabbit generates the high-level summary in your pull requests — including its content, structure, tone, and formatting.

  • Provide your own instructions using the high_level_summary_instructions setting.
  • Format the summary however you like (bullet lists, tables, multi-section layouts, contributor stats, etc.).
  • Use high_level_summary_in_walkthrough to move the summary from the description to the walkthrough section.

Example instruction:

"Divide the high-level summary into five sections:

  1. 📝 Description — Summarize the main change in 50–60 words, explaining what was done.
  2. 📓 References — List relevant issues, discussions, documentation, or related PRs.
  3. 📦 Dependencies & Requirements — Mention any new/updated dependencies, environment variable changes, or configuration updates.
  4. 📊 Contributor Summary — Include a Markdown table showing contributions:
    | Contributor | Lines Added | Lines Removed | Files Changed |
  5. ✔️ Additional Notes — Add any extra reviewer context.
    Keep each section concise (under 200 words) and use bullet or numbered lists for clarity."

Note: This feature is currently in beta for Pro-tier users, and pricing will be announced later.


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: 7

📜 Review details

Configuration used: CodeRabbit UI

Review profile: ASSERTIVE

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 6f9a2f5 and 2aa0c23.

⛔ Files ignored due to path filters (1)
  • pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml
📒 Files selected for processing (14)
  • components/encharge/actions/add-or-update-person/add-or-update-person.mjs (1 hunks)
  • components/encharge/actions/archive-person/archive-person.mjs (1 hunks)
  • components/encharge/actions/remove-tags/remove-tags.mjs (1 hunks)
  • components/encharge/common/constants.mjs (1 hunks)
  • components/encharge/common/utils.mjs (1 hunks)
  • components/encharge/encharge.app.mjs (1 hunks)
  • components/encharge/package.json (2 hunks)
  • components/encharge/sources/common/base.mjs (1 hunks)
  • components/encharge/sources/new-person-instant/new-person-instant.mjs (1 hunks)
  • components/encharge/sources/new-person-instant/test-event.mjs (1 hunks)
  • components/encharge/sources/tag-removed-from-person-instant/tag-removed-from-person-instant.mjs (1 hunks)
  • components/encharge/sources/tag-removed-from-person-instant/test-event.mjs (1 hunks)
  • components/encharge/sources/updated-person-instant/test-event.mjs (1 hunks)
  • components/encharge/sources/updated-person-instant/updated-person-instant.mjs (1 hunks)
🧰 Additional context used
🧠 Learnings (6)
📚 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/encharge/sources/updated-person-instant/updated-person-instant.mjs
  • components/encharge/sources/new-person-instant/new-person-instant.mjs
  • components/encharge/sources/tag-removed-from-person-instant/tag-removed-from-person-instant.mjs
📚 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/encharge/sources/updated-person-instant/test-event.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/encharge/encharge.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/encharge/encharge.app.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/encharge/package.json
📚 Learning: 2024-07-24T02:06:47.016Z
Learnt from: GTFalcao
Repo: PipedreamHQ/pipedream PR: 12697
File: components/salesforce_rest_api/sources/common-webhook-methods.mjs:1-71
Timestamp: 2024-07-24T02:06:47.016Z
Learning: The `common-webhook-methods.mjs` object is designed to be extended, similar to an abstract class, and intentionally does not implement certain methods like `generateWebhookMeta` and `getEventType` to enforce implementation in subclasses.

Applied to files:

  • components/encharge/sources/common/base.mjs
🧬 Code graph analysis (8)
components/encharge/common/constants.mjs (1)
components/encharge/encharge.app.mjs (1)
  • LIMIT (13-18)
components/encharge/common/utils.mjs (1)
components/plentyone/common/utils.mjs (1)
  • obj (1-24)
components/encharge/sources/updated-person-instant/updated-person-instant.mjs (1)
components/encharge/actions/add-or-update-person/add-or-update-person.mjs (1)
  • data (51-61)
components/encharge/actions/remove-tags/remove-tags.mjs (3)
components/encharge/actions/add-or-update-person/add-or-update-person.mjs (1)
  • response (63-66)
components/encharge/actions/archive-person/archive-person.mjs (1)
  • response (42-53)
components/encharge/common/utils.mjs (2)
  • parseObject (1-24)
  • parseObject (1-24)
components/encharge/sources/new-person-instant/new-person-instant.mjs (1)
components/encharge/actions/add-or-update-person/add-or-update-person.mjs (1)
  • data (51-61)
components/encharge/encharge.app.mjs (1)
components/encharge/common/constants.mjs (2)
  • LIMIT (1-1)
  • LIMIT (1-1)
components/encharge/actions/archive-person/archive-person.mjs (2)
components/encharge/actions/add-or-update-person/add-or-update-person.mjs (1)
  • response (63-66)
components/encharge/actions/remove-tags/remove-tags.mjs (1)
  • response (35-41)
components/encharge/actions/add-or-update-person/add-or-update-person.mjs (3)
components/encharge/common/utils.mjs (2)
  • parseObject (1-24)
  • parseObject (1-24)
components/encharge/actions/archive-person/archive-person.mjs (1)
  • response (42-53)
components/encharge/actions/remove-tags/remove-tags.mjs (1)
  • response (35-41)
⏰ 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: Lint Code Base
  • GitHub Check: pnpm publish
🔇 Additional comments (15)
components/encharge/common/constants.mjs (1)

1-1: LGTM!

Clean constant definition for pagination limit.

components/encharge/package.json (2)

3-3: LGTM!

Appropriate version bump from 0.0.2 to 0.1.0 for new feature additions.


15-16: LGTM!

Correct addition of @pipedream/platform dependency needed for axios integration.

components/encharge/sources/new-person-instant/test-event.mjs (1)

1-23: LGTM!

Well-structured test event payload with representative data for the new person webhook.

components/encharge/sources/tag-removed-from-person-instant/test-event.mjs (1)

1-11: LGTM!

Appropriate minimal test event structure for tag removal webhook.

components/encharge/encharge.app.mjs (4)

1-2: LGTM!

Correct imports for axios and the LIMIT constant.


7-29: LGTM!

Well-structured userId propDefinition with pagination and proper label formatting.


53-69: LGTM!

Clean API request wrapper implementation with proper URL construction and header injection.


70-115: LGTM!

Comprehensive set of API methods covering person management, tagging, and webhook lifecycle operations.

components/encharge/actions/archive-person/archive-person.mjs (1)

1-36: LGTM!

Clean action metadata and prop definitions with appropriate annotations including destructiveHint: true.

components/encharge/common/utils.mjs (1)

1-24: LGTM!

Robust parseObject utility with proper error handling and fallback logic. The implementation is identical to the pattern used in other Pipedream components (e.g., plentyone), which is acceptable for component-scoped utilities.

components/encharge/sources/updated-person-instant/updated-person-instant.mjs (1)

1-30: LGTM!

The source structure is clean and follows the established instant-source pattern correctly. The event type, metadata generation, and destructuring are all consistent with sibling sources.

components/encharge/sources/common/base.mjs (1)

1-35: LGTM!

The webhook lifecycle management is implemented correctly. The base module properly abstracts common behavior while leaving getEvent() and generateMeta() for subclasses to implement—this follows the established abstract base pattern for Pipedream sources.

Based on learnings

components/encharge/sources/new-person-instant/new-person-instant.mjs (1)

1-30: LGTM!

The implementation correctly follows the instant-source pattern and is consistent with the sibling sources in this PR.

components/encharge/actions/add-or-update-person/add-or-update-person.mjs (1)

56-56: Remove undefined property reference.

Line 56 references this.phone, but there is no phone prop defined in the props section (lines 15-48). This will include phone: undefined in the API request payload, which may cause unexpected behavior or errors.

Remove the undefined property:

     const data = [
       {
         firstName: this.firstName,
         lastName: this.lastName,
         email: this.email,
-        phone: this.phone,
         id: this.userId,
-        additionalFields: this.additionalFields,
         ...parsedAdditionalFields,
       },
     ];
⛔ Skipped due to learnings
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.
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.

…utput formatting

- Updated the return statement in the tags processing to use a ternary operator for clarity.
- Removed unused additionalFields from the add-or-update-person action.
- Enhanced the summary message in the add-or-update-person action to conditionally include the email.
- Added validation in the archive-person action to ensure either user ID or email is provided.
- Modified the remove-tags action to handle tags as an array for consistent processing.
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: 1

♻️ Duplicate comments (1)
components/encharge/encharge.app.mjs (1)

48-50: Consider applying the readability improvement for tags parsing.

The tags parsing logic still uses the chained logical expression tags && tags.split(",") || [] which is less readable than a ternary operator. This was suggested in a previous review.

Apply this diff for improved readability:

-        return tags && tags.split(",") || [];
+        return tags ? tags.split(",") : [];
📜 Review details

Configuration used: CodeRabbit UI

Review profile: ASSERTIVE

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 2aa0c23 and e8cc937.

📒 Files selected for processing (5)
  • components/encharge/actions/add-or-update-person/add-or-update-person.mjs (1 hunks)
  • components/encharge/actions/archive-person/archive-person.mjs (1 hunks)
  • components/encharge/actions/remove-tags/remove-tags.mjs (1 hunks)
  • components/encharge/encharge.app.mjs (1 hunks)
  • components/encharge/sources/tag-removed-from-person-instant/tag-removed-from-person-instant.mjs (1 hunks)
🧰 Additional context used
🧠 Learnings (5)
📚 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/encharge/actions/add-or-update-person/add-or-update-person.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/encharge/sources/tag-removed-from-person-instant/tag-removed-from-person-instant.mjs
📚 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/encharge/sources/tag-removed-from-person-instant/tag-removed-from-person-instant.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/encharge/encharge.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/encharge/encharge.app.mjs
🧬 Code graph analysis (4)
components/encharge/actions/add-or-update-person/add-or-update-person.mjs (2)
components/encharge/common/utils.mjs (2)
  • parseObject (1-24)
  • parseObject (1-24)
components/encharge/actions/archive-person/archive-person.mjs (1)
  • response (45-56)
components/encharge/actions/remove-tags/remove-tags.mjs (1)
components/encharge/common/utils.mjs (2)
  • parseObject (1-24)
  • parseObject (1-24)
components/encharge/actions/archive-person/archive-person.mjs (2)
components/encharge/actions/add-or-update-person/add-or-update-person.mjs (1)
  • response (62-65)
components/encharge/actions/remove-tags/remove-tags.mjs (1)
  • response (41-47)
components/encharge/encharge.app.mjs (1)
components/encharge/common/constants.mjs (2)
  • LIMIT (1-1)
  • LIMIT (1-1)
⏰ 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 (3)
components/encharge/sources/tag-removed-from-person-instant/tag-removed-from-person-instant.mjs (1)

25-35: LGTM! Destructuring pattern correctly fixed.

The destructuring pattern on line 27 now correctly extracts the id property from the object ({ id }), resolving the previous issue where id would have been bound to the entire object. The metadata generation logic properly uses the extracted id value.

components/encharge/actions/archive-person/archive-person.mjs (1)

38-43: LGTM! Validation logic correctly handles all cases.

The validation now properly checks for both edge cases:

  • Lines 38-40: Ensures at least one identifier (userId or email) is provided
  • Lines 41-43: Ensures they are mutually exclusive

This resolves the previous critical validation gap.

components/encharge/actions/remove-tags/remove-tags.mjs (1)

35-40: LGTM! Type safety correctly implemented.

The code now properly handles the output of parseObject by normalizing it to an array (lines 36-40), ensuring that array methods like .join() and .length will work correctly regardless of the input type. This resolves the previous type safety concern.

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: 1

📜 Review details

Configuration used: CodeRabbit UI

Review profile: ASSERTIVE

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between e8cc937 and c1c302a.

📒 Files selected for processing (1)
  • components/encharge/actions/add-or-update-person/add-or-update-person.mjs (1 hunks)
🧰 Additional context used
🧠 Learnings (2)
📚 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/encharge/actions/add-or-update-person/add-or-update-person.mjs
📚 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/encharge/actions/add-or-update-person/add-or-update-person.mjs
🧬 Code graph analysis (1)
components/encharge/actions/add-or-update-person/add-or-update-person.mjs (3)
components/encharge/common/utils.mjs (2)
  • parseObject (1-24)
  • parseObject (1-24)
components/encharge/actions/archive-person/archive-person.mjs (1)
  • response (45-56)
components/encharge/actions/remove-tags/remove-tags.mjs (1)
  • response (41-47)
⏰ 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: Publish TypeScript components
  • GitHub Check: Lint Code Base
  • GitHub Check: Verify TypeScript components
🔇 Additional comments (1)
components/encharge/actions/add-or-update-person/add-or-update-person.mjs (1)

49-72: LGTM! The run method implementation is correct.

The implementation properly:

  • Parses additionalFields with appropriate fallback
  • Constructs the data payload correctly
  • Uses the userId to determine add vs. update in the summary
  • Handles the optional email in the summary message (previously flagged issue is now resolved)

Comment on lines +17 to +40
userId: {
propDefinition: [
app,
"userId",
],
optional: true,
},
firstName: {
type: "string",
label: "First Name",
description: "The first name of the person.",
optional: true,
},
lastName: {
type: "string",
label: "Last Name",
description: "The last name of the person.",
optional: true,
},
email: {
type: "string",
label: "Email",
description: "The email of the person.",
optional: true,
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

Verify that all props should be optional.

The PR objectives specify "Required props: person info (e.g., name, email, identifiers)," but all props in this action are marked optional. This creates a scenario where a user could invoke the action without providing any meaningful data:

  • For add operations (no userId), typically at least email or another identifier should be required to create a person.
  • For update operations, userId itself would typically be required to identify which person to update.

🏁 Script executed:

#!/bin/bash
# Description: Check the Encharge API app wrapper to understand parameter requirements for addOrUpdatePerson

# Search for the addOrUpdatePerson method implementation
rg -nP -A 10 'addOrUpdatePerson' components/encharge/encharge.app.mjs

Length of output: 296


🏁 Script executed:

#!/bin/bash
# Find other person-related actions in Encharge to compare prop configurations
fd -t f 'person' components/encharge/actions/ | head -10

Length of output: 135


🏁 Script executed:

#!/bin/bash
# Check run method and any validation logic for context
rg -nP -A 25 'run\(' components/encharge/actions/add-or-update-person/add-or-update-person.mjs

Length of output: 644


🏁 Script executed:

#!/bin/bash
# Look for any API documentation references or comments in Encharge files
rg -nP -B 2 -A 2 'required|Required|REQUIRED' components/encharge/ | head -30

Length of output: 0


[/run_scripts]

[/web_search]


🏁 Script executed:

#!/bin/bash
# Check archive-person action to see how it handles userId
cat components/encharge/actions/archive-person/archive-person.mjs

Length of output: 1626


🌐 Web query:

Encharge API people endpoint POST required fields documentation

💡 Result:

Short answer — use the Ingest API POST to https://ingest.encharge.io/v1/

Required for a person create/update:

  • Header: X-Encharge-Token (your write key). [1]
  • Header: Content-Type: application/json. [1]
  • JSON body:
    • name — event name (use "identify" when creating/updating people). [1]
    • user — object that must include either email OR userId to uniquely identify the person. Other keys inside user (e.g., properties, tags, ip) are optional and become person fields. [1][2]

Notes:

  • Date/time fields must be ISO 8601. [1][3]

Sources: Encharge Ingest API docs and People/Fields docs. [1][2][3]

References
[1] Encharge Ingest API (POST /v1) documentation.
[2] Encharge API documentation overview.
[3] Encharge person fields / date format guidance.


Add validation to enforce that either email or userId is provided.

The Encharge API requires either email or userId to identify the person being added or updated. While props are marked optional, the run method must validate that at least one identifier is provided—similar to how archive-person.mjs validates: "You must provide either a user ID or an email."

Add this check at the start of the run method:

async run({ $ }) {
  if (!this.userId && !this.email) {
    throw new Error("You must provide either a user ID or an email.");
  }
  // ... rest of method
}

Without this, the action can be invoked without any way to identify which person to update.

🤖 Prompt for AI Agents
In components/encharge/actions/add-or-update-person/add-or-update-person.mjs
around lines 17 to 40, the props mark both email and userId as optional but
there is no runtime validation ensuring at least one identifier is provided; add
a validation at the start of the run method that checks if both this.userId and
this.email are falsy and, if so, throws an Error with the message "You must
provide either a user ID or an email." to prevent calls that lack any way to
identify the person.

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] encharge

2 participants