Skip to content

Conversation

@choeqq
Copy link
Contributor

@choeqq choeqq commented Oct 29, 2025

WHY

New Contact Added to Segment (ActiveCampaign)

Description

Adds a new polling source that emits events when contacts are added to an ActiveCampaign segment.

How it works

  • Polls segments periodically to detect new contact additions
  • Uses the /audiences API to list and fetch segment details (the V1 /segments API only returns legacy/hidden segments)
  • Tracks contact membership by storing contact IDs in the component database
  • First run behavior: Stores existing contacts without emitting events to avoid flooding with historical data
  • Subsequent runs: Compares current segment contacts with stored IDs and emits events only for newly added contacts

Key features

  • Dropdown selector for segments (fetches all user-created segments)
  • Supports dynamic segments (contacts automatically enter/exit based on criteria)
  • Emits full contact data with each event
  • Deduplicates events using unique ID format: {segmentId}-{contactId}-{timestamp}

Use case example

Monitor when contacts match specific criteria like "Status = Active" or "First Name contains 'kacper'" by creating a segment with those filters and watching for new additions.

Changes to activecampaign.app.mjs

  • Added listAudiences() method to fetch segments from /api/3/audiences
  • Added segment propDefinition for single segment selection
  • Added listSegmentOptions() to populate segment dropdown with user-created segments

Summary by CodeRabbit

  • New Features

    • Segment selection & watch: pick specific segments (or leave blank to watch all); segment choices load dynamically with pagination
    • New trigger — "New Contact Added to Segment": polls segments and emits events for newly added contacts (includes sample test event)
  • Chores

    • Version bumps and metadata updates across the ActiveCampaign component, sources, and actions

@adolfo-pd adolfo-pd added the User submitted Submitted by a user label Oct 29, 2025
@vercel
Copy link

vercel bot commented Oct 29, 2025

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

1 Skipped Deployment
Project Deployment Preview Comments Updated (UTC)
pipedream-docs-redirect-do-not-edit Ignored Ignored Oct 30, 2025 8:22am

@pipedream-component-development
Copy link
Collaborator

Thank you so much for submitting this! We've added it to our backlog to review, and our team has been notified.

@pipedream-component-development
Copy link
Collaborator

Thanks for submitting this PR! When we review PRs, we follow the Pipedream component guidelines. If you're not familiar, here's a quick checklist:

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Oct 29, 2025

Walkthrough

Adds segment selection props and option resolution to the ActiveCampaign app, three API helper methods (segments/audiences/options), a new polling source "New Contact Added to Segment" with per-segment state, pagination, and a test-event, plus many version bumps across package/actions/sources.

Changes

Cohort / File(s) Summary
App: segment props & methods
components/activecampaign/activecampaign.app.mjs
Added propDefinitions segments (string[]) and segment (string) using listSegmentOptions. Added methods: listSegments(args), listAudiences(args), listSegmentOptions(prevContext) (pagination-aware) and getContactFieldValues({ contactId, ...args }).
New source: contact added to segment
components/activecampaign/sources/new-contact-added-to-segment/new-contact-added-to-segment.mjs, components/activecampaign/sources/new-contact-added-to-segment/test-event.mjs
New polling source that paginates segment contacts, diffs against stored per-segment contact IDs, enriches contacts with custom field values, emits events for newly added contacts, persists latest IDs, and adds a test-event fixture.
Package version
components/activecampaign/package.json
Bumped package version from 0.4.5 to 0.4.6.
Action version bumps
components/activecampaign/actions/*/*
Multiple action modules had version increments under components/activecampaign/actions/ (metadata-only changes; no logic changes).
Source version bumps
components/activecampaign/sources/...
Many source modules under components/activecampaign/sources/ had exported version string updates (metadata-only).

Sequence Diagram(s)

sequenceDiagram
    participant Timer as Timer
    participant Source as New Contact<br/>Added to Segment
    participant API as ActiveCampaign API
    participant Store as Persistent Storage

    Timer->>Source: Trigger (interval)
    Source->>Source: Validate `segmentId`
    Source->>API: listAudiences(segmentId) (resolve segment name)
    API-->>Source: Segment info
    Source->>API: getSegmentContacts(segmentId) [paginated]
    API-->>Source: Contacts pages
    Source->>Store: _getStoredContactIds(segmentKey)
    Store-->>Source: storedIds

    alt First run (no storedIds)
        Source->>Store: _setStoredContactIds(currentIds)
    else Subsequent runs
        Source->>Source: Compute newIds = currentIds - storedIds
        loop for each newId
            Source->>API: getContactFieldValues(contactId)
            API-->>Source: field values
            Source->>Timer: Emit event (contact + metadata + addedAt)
        end
        Source->>Store: _setStoredContactIds(currentIds)
    end
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~30 minutes

  • Review focus:
    • new source: pagination of segment contacts, diff logic, first-run behavior, error handling when fetching field values, and persistent key naming.
    • app methods: pagination/context handling in listSegmentOptions and mapping of audience/segment fields to option objects.
    • verify version bumps are metadata-only.

Poem

🐰
I hop through segments, nose to the air,
Polling for newcomers with attentive care.
I stash old IDs in a cozy little lair,
When new friends arrive I shout and declare.
A carrot of versions — nibble, sniff, and share.

Pre-merge checks and finishing touches

❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
✅ Passed checks (2 passed)
Check name Status Explanation
Title Check ✅ Passed The PR title "Activecampaign contact added to segment" directly corresponds to the main change in this changeset: the addition of a new polling source called "New Contact Added to Segment" for the ActiveCampaign component. The title is concise and specific enough that a teammate reviewing the repository history would understand that a new feature related to detecting segment membership changes was introduced. The title avoids vague language and clearly communicates the primary purpose of the changeset, including support methods and version updates across related files.
Description Check ✅ Passed The PR description fulfills the repository template requirement by including a "## WHY" section header and providing substantive content that explains the purpose of the change. Beyond the template minimum, the author has included comprehensive sections on description, how it works, key features, use case examples, and specific implementation details. The description clearly articulates why this polling source is needed (to detect contacts added to segments), how it functions (polling with contact tracking), and the technical changes made to support it. This exceeds the basic template requirements and provides sufficient context for reviewers.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment

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

🧹 Nitpick comments (4)
components/activecampaign/activecampaign.app.mjs (1)

441-446: /segments helper included

OK to keep for legacy/hidden segments. Consider adding a short JSDoc noting it returns legacy segments vs. /audiences to avoid confusion later.

components/activecampaign/sources/new-contact-added-to-segment/new-contact-added-to-segment.mjs (3)

47-72: Pagination logic OK; consider minor resilience

Loop and offset/limit are fine. Optionally guard against transient failures with a bounded retry/backoff on 429/5xx to improve reliability.


39-46: Event id includes a timestamp; consider a stable id

Using ts in id makes replays non-idempotent. Since you already track membership in db, a stable id like ${segmentId}-${contact.id} simplifies dedupe.

Apply this diff:

-        id: `${segmentInfo.segmentId}-${contact.id}-${ts}`,
+        id: `${segmentInfo.segmentId}-${contact.id}`,

127-137: addedAt is “now”; call this out in summary or include segment info

If “addedAt” is the poll time (not true join time), consider reflecting that in summary or field name (e.g., detectedAt) to avoid confusion.

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 6da388e and d7854db.

📒 Files selected for processing (21)
  • components/activecampaign/activecampaign.app.mjs (3 hunks)
  • components/activecampaign/package.json (1 hunks)
  • components/activecampaign/sources/campaign-bounce/campaign-bounce.mjs (1 hunks)
  • components/activecampaign/sources/campaign-link-clicked/campaign-link-clicked.mjs (1 hunks)
  • components/activecampaign/sources/campaign-opened/campaign-opened.mjs (1 hunks)
  • components/activecampaign/sources/campaign-starts-sending/campaign-starts-sending.mjs (1 hunks)
  • components/activecampaign/sources/contact-added-to-list/contact-added-to-list.mjs (1 hunks)
  • components/activecampaign/sources/new-automation-webhook/new-automation-webhook.mjs (1 hunks)
  • components/activecampaign/sources/new-campaign-unsubscribe/new-campaign-unsubscribe.mjs (1 hunks)
  • components/activecampaign/sources/new-contact-added-to-segment/new-contact-added-to-segment.mjs (1 hunks)
  • components/activecampaign/sources/new-contact-added-to-segment/test-event.mjs (1 hunks)
  • components/activecampaign/sources/new-contact-note/new-contact-note.mjs (1 hunks)
  • components/activecampaign/sources/new-contact-task/new-contact-task.mjs (1 hunks)
  • components/activecampaign/sources/new-deal-note/new-deal-note.mjs (1 hunks)
  • components/activecampaign/sources/new-deal-task/new-deal-task.mjs (1 hunks)
  • components/activecampaign/sources/new-event/new-event.mjs (1 hunks)
  • components/activecampaign/sources/new-or-updated-account/new-or-updated-account.mjs (1 hunks)
  • components/activecampaign/sources/new-or-updated-calendar-feed/new-or-updated-calendar-feed.mjs (1 hunks)
  • components/activecampaign/sources/new-or-updated-contact/new-or-updated-contact.mjs (1 hunks)
  • components/activecampaign/sources/new-or-updated-deal/new-or-updated-deal.mjs (1 hunks)
  • components/activecampaign/sources/updated-contact/updated-contact.mjs (1 hunks)
🧰 Additional context used
🧬 Code graph analysis (2)
components/activecampaign/sources/new-contact-added-to-segment/new-contact-added-to-segment.mjs (1)
components/activecampaign/activecampaign.app.mjs (4)
  • limit (602-602)
  • offset (603-603)
  • response (496-501)
  • response (503-505)
components/activecampaign/activecampaign.app.mjs (1)
components/activecampaign/sources/new-contact-added-to-segment/new-contact-added-to-segment.mjs (4)
  • response (54-60)
  • response (84-88)
  • segment (89-89)
  • meta (135-135)
⏰ 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 (22)
components/activecampaign/package.json (1)

3-3: LGTM! Standard version bump for package release.

The version increment from 0.4.5 to 0.4.6 aligns with the addition of the new "Contact Added to Segment" polling source and related API enhancements.

components/activecampaign/sources/new-automation-webhook/new-automation-webhook.mjs (1)

10-10: LGTM! Metadata version update.

Version bumped to 0.0.7 as part of the package release cycle. No functional changes.

components/activecampaign/sources/new-deal-note/new-deal-note.mjs (1)

9-9: LGTM! Routine version update.

Metadata version bumped to 0.0.6. No functional changes.

components/activecampaign/sources/updated-contact/updated-contact.mjs (1)

8-8: LGTM! Metadata version update.

Version bumped to 0.0.6 with no functional changes.

components/activecampaign/sources/new-or-updated-account/new-or-updated-account.mjs (1)

10-10: LGTM! Metadata version update.

Version bumped to 0.0.5 as part of the release cycle. No functional changes.

components/activecampaign/sources/campaign-bounce/campaign-bounce.mjs (1)

9-9: LGTM! Routine version increment.

Metadata version updated to 0.0.6. No behavioral changes.

components/activecampaign/sources/new-deal-task/new-deal-task.mjs (1)

9-9: LGTM! Metadata version update.

Version bumped to 0.0.6 with no functional changes.

components/activecampaign/sources/new-contact-note/new-contact-note.mjs (1)

9-9: LGTM! Metadata version update.

Version bumped to 0.0.6 as part of the release cycle. No functional changes.

components/activecampaign/sources/campaign-starts-sending/campaign-starts-sending.mjs (1)

8-8: Version bump looks good.

The patch version increment from 0.0.5 to 0.0.6 is appropriate for this metadata-only update with no functional changes.

components/activecampaign/sources/new-or-updated-deal/new-or-updated-deal.mjs (1)

8-8: LGTM.

Consistent version increment aligned with the package update.

components/activecampaign/sources/new-event/new-event.mjs (1)

10-10: Version update confirmed.

No functional changes, version increment is appropriate.

components/activecampaign/sources/contact-added-to-list/contact-added-to-list.mjs (1)

10-10: Version increment approved.

The bump to 0.0.7 (vs. 0.0.6 for most other sources) is noted, likely reflecting an earlier independent update to this file.

components/activecampaign/sources/new-campaign-unsubscribe/new-campaign-unsubscribe.mjs (1)

9-9: LGTM.

Routine version increment with no functional impact.

components/activecampaign/sources/new-or-updated-calendar-feed/new-or-updated-calendar-feed.mjs (1)

10-10: Version update approved.

The patch increment from 0.0.4 to 0.0.5 is consistent with routine maintenance.

components/activecampaign/sources/campaign-link-clicked/campaign-link-clicked.mjs (1)

9-9: LGTM.

Routine metadata update consistent with the broader package version bump.

components/activecampaign/sources/campaign-opened/campaign-opened.mjs (1)

9-9: Version increment confirmed.

Metadata-only change with no functional impact.

components/activecampaign/sources/new-contact-task/new-contact-task.mjs (1)

9-9: Version bump LGTM

No behavioral change. Keep changelog/package version in sync.

components/activecampaign/activecampaign.app.mjs (2)

80-89: Segments prop: good async options wiring

Looks correct and follows existing options pattern.


90-97: Single Segment prop: good addition

Works with the new resolver for dropdowns.

components/activecampaign/sources/new-or-updated-contact/new-or-updated-contact.mjs (1)

8-8: Version bump verified and consistent

File correctly contains version 0.0.6 at line 8. Verified that 11 other AC source components share the same version, confirming consistency across the majority of sources. Version variations in other sources (0.0.7, 0.0.5, 0.0.1) appear intentional.

components/activecampaign/sources/new-contact-added-to-segment/test-event.mjs (1)

1-15: Sample payload is correctly formatted

The test event payload correctly uses camelCase (firstName, lastName) which aligns with the ActiveCampaign v3 Contacts API specification. The Contact object uses firstName / lastName in requests/responses for the standard v3 endpoints. The reviewer's conditional concern about snake_case misalignment does not apply to this use case.

components/activecampaign/sources/new-contact-added-to-segment/new-contact-added-to-segment.mjs (1)

82-95: Verify API endpoint availability and pagination structure before implementing fix

The review comment raises a valid concern—fetching only page 1 of /audiences could miss segments—but the proposed solution cannot be verified. Web searches do not provide access to the ActiveCampaign API v3 complete reference for the audiences endpoint. The fix assumes: (1) GET /audiences/{id} exists, (2) makeRequest() is available and correct, and (3) pagination metadata includes resp.meta.page.current_page and resp.meta.page.last_page, none of which could be confirmed from public documentation.

Before implementing, verify against the official ActiveCampaign API v3 reference that:

  • The direct audience lookup endpoint exists and is the correct path
  • The listAudiences pagination response includes those specific metadata fields
  • The SDK's makeRequest() method is the appropriate fallback approach

Copy link
Collaborator

@michelle0927 michelle0927 left a comment

Choose a reason for hiding this comment

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

Hi @choeqq. Thank you so much for your contribution! Once the suggested changes are made, this should be ready for QA.
Note: I tried making the changes, but was denied access by your repo.

@michelle0927 michelle0927 moved this from In Review to Changes Required in Component (Source and Action) Backlog Oct 29, 2025
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: 0

♻️ Duplicate comments (2)
components/activecampaign/activecampaign.app.mjs (2)

447-452: Do not merge: /audiences endpoint remains undocumented.

The GET /api/3/audiences endpoint is not officially documented by ActiveCampaign. As noted in the previous review, this creates maintenance and stability risks. Before merging:

  • Verify endpoint support and stability with ActiveCampaign
  • Confirm the actual response schema matches expectations (standard data + meta.page vs LIME-style collection)
  • Document why this undocumented endpoint is required

493-523: Fix unsafe property access and error handling structure.

Several critical issues that will cause crashes:

  1. Line 494: prevContext.page will throw TypeError when prevContext is undefined on first invocation
  2. Line 505: Error handler returns [] but should return {options: [], context: {page: null}}
  3. Lines 508-510: Destructuring response without guards—if listAudiences returns undefined or an unexpected structure, this will crash
  4. Lines 513, 518: Assumes data is an array and meta.page exists with the expected properties

Apply this diff to add proper guards:

-    async listSegmentOptions(prevContext) {
-      const page = prevContext.page || 1;
+    async listSegmentOptions(prevContext = {}) {
+      const page = prevContext?.page ?? 1;
 
       let response;
       try {
         response = await this.listAudiences({
           params: {
             sort: "-recent",
             page,
           },
         });
       } catch {
-        return [];
+        return {
+          options: [],
+          context: {
+            page: null,
+          },
+        };
       }
 
-      const {
-        data, meta,
-      } = response;
+      const { data = [], meta = {} } = response || {};
 
       return {
         options: data.map((segment) => ({
           label: segment.attributes.name,
           value: segment.id,
         })),
         context: {
-          page: meta.page.current_page < meta.page.last_page
+          page: meta?.page?.current_page < meta?.page?.last_page
             ? page + 1
             : null,
         },
       };
     },
🧹 Nitpick comments (2)
components/activecampaign/sources/new-contact-added-to-segment/new-contact-added-to-segment.mjs (2)

92-105: Consider fetching segment by ID or document the limitation.

The code only fetches the first page of audiences to find the segment name. If the segment appears on page 2 or later, it will use the fallback "Segment {id}" format. While the fallback prevents errors, this could be confusing for users.

Consider either:

  • Fetching the specific segment by ID (if a GET /audiences/{id} endpoint exists)
  • Paginating through all pages until the segment is found
  • Adding a comment documenting this limitation

143-143: Consider timestamp format consistency.

Line 143 uses new Date().toISOString() for addedAt, while the generateMeta method (line 49) uses Date.now() for the metadata timestamp. While both serve different purposes, using consistent formats throughout (either both ISO strings or both numeric timestamps) would improve code clarity.

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between af2ed05 and 42635c0.

📒 Files selected for processing (2)
  • components/activecampaign/activecampaign.app.mjs (3 hunks)
  • components/activecampaign/sources/new-contact-added-to-segment/new-contact-added-to-segment.mjs (1 hunks)
🧰 Additional context used
🧠 Learnings (1)
📚 Learning: 2024-10-10T19:18:27.998Z
Learnt from: GTFalcao
PR: PipedreamHQ/pipedream#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/activecampaign/sources/new-contact-added-to-segment/new-contact-added-to-segment.mjs
🧬 Code graph analysis (2)
components/activecampaign/activecampaign.app.mjs (1)
components/activecampaign/sources/new-contact-added-to-segment/new-contact-added-to-segment.mjs (4)
  • response (63-70)
  • response (94-98)
  • segment (99-99)
  • meta (146-146)
components/activecampaign/sources/new-contact-added-to-segment/new-contact-added-to-segment.mjs (1)
components/activecampaign/activecampaign.app.mjs (4)
  • limit (607-607)
  • offset (608-608)
  • response (496-496)
  • response (508-510)
⏰ 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 (8)
components/activecampaign/activecampaign.app.mjs (2)

80-97: LGTM: PropDefinitions follow established patterns.

The segments and segment propDefinitions are well-structured and consistent with other prop definitions in this file.


441-446: LGTM: Follows standard pattern.

The listSegments method follows the same pattern used by other list methods in this file.

components/activecampaign/sources/new-contact-added-to-segment/new-contact-added-to-segment.mjs (6)

1-28: LGTM: Component structure follows guidelines.

The component metadata, imports, and props are properly structured and follow Pipedream's component development guidelines.


30-38: LGTM: Proper first-run detection.

The initialization tracking methods correctly address the past review concern about segments that initially have zero contacts.


39-47: LGTM: State management methods.

The contact ID storage methods are correctly implemented with per-segment keys.


48-55: LGTM: Proper event metadata generation.

The generateMeta method creates appropriate unique IDs and summaries for event deduplication.


56-82: LGTM: Proper pagination handling.

The getSegmentContacts method correctly paginates through all contacts in a segment.


112-155: LGTM: Polling logic correctly implemented.

The main run logic properly handles:

  • First-run initialization without emitting retroactive events (per learnings)
  • Detecting newly added contacts by comparing current vs stored IDs
  • Emitting events with full contact data and metadata
  • Updating stored state

Based on learnings

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

♻️ Duplicate comments (2)
components/activecampaign/activecampaign.app.mjs (2)

449-460: The undocumented /audiences endpoint has already been flagged as a critical issue.

A previous review identified that the GET /api/3/audiences endpoint is not officially documented by ActiveCampaign and may use a non-standard LIME-style collection format rather than the expected data + meta.page structure.


501-531: Critical null-safety issues remain unresolved.

While the try-catch block (lines 504-514) handles API failures, the previously flagged critical issues with null safety are still present:

  1. Line 502: prevContext.page access when prevContext may be undefined
  2. Lines 516-518: Destructuring data and meta without defaults
  3. Lines 526-528: Direct access to meta.page.current_page and meta.page.last_page without optional chaining

Apply this diff to add the missing null guards:

-    async listSegmentOptions(prevContext) {
-      const page = prevContext.page || 1;
+    async listSegmentOptions(prevContext = {}) {
+      const page = prevContext?.page ?? 1;

       let response;
       try {
...
       }

-      const {
-        data, meta,
-      } = response;
+      const { data = [], meta = {} } = response || {};

       return {
         options: data.map((segment) => ({
           label: segment.attributes.name,
           value: segment.id,
         })),
         context: {
-          page: meta.page.current_page < meta.page.last_page
+          page: meta?.page?.current_page < meta?.page?.last_page
             ? page + 1
             : null,
         },
       };
🧹 Nitpick comments (1)
components/activecampaign/sources/new-contact-added-to-segment/new-contact-added-to-segment.mjs (1)

174-216: Potential property collision when enriching contact with custom fields.

Line 191 assigns custom field values directly to the contact object using the field title as the property name:

contact[fieldTitle] = fieldValue.value;

If a custom field is named "email", "id", "firstName", etc., it will overwrite the standard contact property. While custom field names are unlikely to collide with standard properties in practice, consider:

  • Using a nested object (e.g., contact.customFields = { ... })
  • Or prefixing custom field properties (e.g., contact[custom_${fieldTitle}])

Otherwise, the contact enrichment and event emission logic is well-structured and properly handles errors (line 195-197).

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 42635c0 and 6264342.

📒 Files selected for processing (2)
  • components/activecampaign/activecampaign.app.mjs (4 hunks)
  • components/activecampaign/sources/new-contact-added-to-segment/new-contact-added-to-segment.mjs (1 hunks)
🧰 Additional context used
🧠 Learnings (2)
📚 Learning: 2024-10-10T19:18:27.998Z
Learnt from: GTFalcao
PR: PipedreamHQ/pipedream#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/activecampaign/sources/new-contact-added-to-segment/new-contact-added-to-segment.mjs
📚 Learning: 2025-06-04T17:52:05.780Z
Learnt from: GTFalcao
PR: PipedreamHQ/pipedream#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/activecampaign/activecampaign.app.mjs
🧬 Code graph analysis (2)
components/activecampaign/sources/new-contact-added-to-segment/new-contact-added-to-segment.mjs (1)
components/activecampaign/activecampaign.app.mjs (4)
  • limit (615-615)
  • offset (616-616)
  • response (504-504)
  • response (516-518)
components/activecampaign/activecampaign.app.mjs (1)
components/activecampaign/sources/new-contact-added-to-segment/new-contact-added-to-segment.mjs (4)
  • response (69-74)
  • response (105-112)
  • response (136-140)
  • segment (141-141)
⏰ 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: Lint Code Base
  • GitHub Check: pnpm publish
  • GitHub Check: Publish TypeScript components
  • GitHub Check: Verify TypeScript components
🔇 Additional comments (7)
components/activecampaign/activecampaign.app.mjs (2)

80-97: LGTM: Segment prop definitions follow established patterns.

Both propDefinitions are well-structured and consistent with existing patterns in the codebase for campaigns, contacts, and lists.


331-338: LGTM: Contact field values method follows the established pattern.

The implementation is consistent with similar methods like getContactTags.

components/activecampaign/sources/new-contact-added-to-segment/new-contact-added-to-segment.mjs (5)

1-28: LGTM: Component structure and props are well-defined.

The component follows Pipedream guidelines with proper naming conventions, dedupe strategy, and polling interval configuration.


29-56: LGTM: State management methods properly track initialization and data.

The explicit initialization flag (lines 30-38) correctly addresses the previously identified issue where an initially empty segment would be treated as uninitialized on subsequent runs. Based on learnings.


57-89: LGTM: Field mapping caching is efficient and correct.

The cache-first approach (lines 58-61) avoids redundant API calls, and pagination properly handles large field lists.


98-124: Clarify the purpose of the forceQuery parameter.

Line 110 passes forceQuery: true to the listContacts API call, but this parameter is not documented in the code. Please verify:

  • Is this parameter required for segment-based contact queries?
  • What behavior does it control?
  • Should this be documented inline?

Otherwise, the pagination logic and contact fetching implementation look correct.


126-172: LGTM: First-run detection correctly implemented.

Lines 165-172 properly use the initialization flag to prevent emitting events for existing contacts on the first run, addressing the critical issue from previous reviews. Based on learnings.

Copy link
Collaborator

@michelle0927 michelle0927 left a comment

Choose a reason for hiding this comment

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

LGTM! Ready for QA!

@michelle0927 michelle0927 moved this from Changes Required to Ready for QA in Component (Source and Action) Backlog Oct 30, 2025
@vunguyenhung vunguyenhung moved this from Ready for QA to In QA in Component (Source and Action) Backlog Oct 31, 2025
@vunguyenhung vunguyenhung moved this from In QA to In Review in Component (Source and Action) Backlog Oct 31, 2025
@vunguyenhung vunguyenhung moved this from In Review to Ready for QA in Component (Source and Action) Backlog Oct 31, 2025
@vunguyenhung vunguyenhung moved this from Ready for QA to In QA in Component (Source and Action) Backlog Oct 31, 2025
@vunguyenhung vunguyenhung moved this from In QA to Ready for Release in Component (Source and Action) Backlog Oct 31, 2025
@vunguyenhung
Copy link
Collaborator

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

Test report
https://vunguyenhung.notion.site/Activecampaign-contact-added-to-segment-29cbf548bb5e817082d7ecce9225d0ba

@vunguyenhung vunguyenhung merged commit 7c496c8 into PipedreamHQ:master Oct 31, 2025
9 of 10 checks passed
@github-project-automation github-project-automation bot moved this from Ready for Release to Done in Component (Source and Action) Backlog Oct 31, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

User submitted Submitted by a user

Development

Successfully merging this pull request may close these issues.

5 participants