Skip to content

Conversation

michelle0927
Copy link
Collaborator

@michelle0927 michelle0927 commented Sep 11, 2025

Resolves #18339

Summary by CodeRabbit

  • Bug Fixes

    • Prevented undefined timestamps from being persisted during HubSpot event polling, improving polling reliability.
    • Apply "last modified" filtering only when a prior checkpoint exists, reducing missed or empty results on initial runs for several HubSpot sources.
  • Chores

    • Bumped versions across the HubSpot component and multiple HubSpot sources for consistency and maintenance.

Copy link

vercel bot commented Sep 11, 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 Sep 11, 2025 9:48pm
pipedream-docs-redirect-do-not-edit Ignored Ignored Sep 11, 2025 9:48pm

Copy link
Contributor

coderabbitai bot commented Sep 11, 2025

Walkthrough

The PR prevents undefined last-modified filters by initializing polling timestamps (maxTs = after || 0) and only adding GTE last-modified filters when an after value exists; it also bumps multiple HubSpot source versions and the HubSpot package version. No public API signatures changed.

Changes

Cohort / File(s) Summary of Changes
Package version bump
components/hubspot/package.json
Bump @pipedream/hubspot 1.7.3 → 1.7.4.
Common polling timestamp init
components/hubspot/sources/common/common.mjs
Initialize maxTs as `after
Conditional GTE filter in property-change sources
components/hubspot/sources/new-contact-property-change/new-contact-property-change.mjs, components/hubspot/sources/new-custom-object-property-change/new-custom-object-property-change.mjs, components/hubspot/sources/new-deal-property-change/new-deal-property-change.mjs, components/hubspot/sources/new-ticket-property-change/new-ticket-property-change.mjs
Refactor getParams(after) to build a params object and append the hs_lastmodifieddate/lastmodifieddate GTE filter only when after is truthy. Each file has a version bump.
Version-only bumps (metadata)
components/hubspot/sources/* (many files)
Patch/mini version increments across many HubSpot source modules (e.g., new-contact-added-to-list, delete-blog-article, new-engagement, new-event, new-form-submission, new-note, new-or-updated-*, new-task, new-ticket, new-social-media-message, new-email-event, new-email-subscriptions-timeline, new-deal-in-stage, etc.) with no code/behavior changes.

Sequence Diagram(s)

sequenceDiagram
  autonumber
  participant Timer
  participant Source as HubSpot Source
  participant DB as State DB (_after)
  participant HubSpot as HubSpot API

  Timer->>Source: run trigger
  Source->>DB: get("after")
  alt no after (first run)
    Note right of Source #f0f4c3: Build params WITHOUT GTE filter
  else after exists
    Note right of Source #d0f0ff: Append lastmodifieddate GTE = after
  end
  Source->>HubSpot: searchObjects(params)
  HubSpot-->>Source: results (items)
  Source->>Source: processEvents(items)\nmaxTs = after || 0\nupdate maxTs per item
  Source->>DB: _setAfter(maxTs)
  Source-->>Timer: done
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Possibly related PRs

Suggested labels

User submitted

Suggested reviewers

  • jcortes

Pre-merge checks (3 passed, 2 warnings)

❌ Failed checks (2 warnings)
Check name Status Explanation Resolution
Linked Issues Check ⚠️ Warning The changes address the immediate cause of the error by avoiding an undefined value being sent to the HubSpot GTE filter (sources now add the GTE filter only when after is truthy and common.mjs prevents persisting undefined by defaulting maxTs to 0), which fixes the "operator GTE requires a value" symptom. However, the linked issue asked for initializing a sensible default after (for example, now minus one day) so the initial query includes a valid timestamp; the PR does not implement that fallback and instead omits the time filter on initial runs, which changes initial query behavior. Because the PR does not implement the explicit default timestamp requested in the issue, it does not fully meet the stated objective. Either implement the intended default after value (e.g., set after = Date.now() - 24*60*60*1000 when undefined and include a GTE filter using that value) or explicitly document and justify the behavioral change of omitting the GTE filter on initial runs, and add tests verifying the chosen behavior and that no undefined values are sent to HubSpot.
Description Check ⚠️ Warning The current PR description only contains "Resolves #18339" and does not follow the repository's required template (the "## WHY" section is missing); it lacks a succinct explanation of why the change was made, what files were modified, the behavior change, and what testing was performed. This makes it difficult for reviewers to understand design decisions or confirm the fix addresses the linked issue without reading diffs. Update the PR description to follow the template: add a "## WHY" section that explains the bug, summarize the code changes (e.g., conditional GTE filters in HubSpot sources and the common.mjs default for persisted timestamps), state the expected runtime behavior and any tradeoffs, and list tests performed and the linked issue number (#18339).
✅ Passed checks (3 passed)
Check name Status Explanation
Title Check ✅ Passed The title "Hubspot - bug fix to sources w/ property changes" is aligned with the main intent of the changeset (fixes to HubSpot property-change sources) and is concise enough for a quick scan; it accurately indicates this is a HubSpot bug fix rather than unrelated work. It is slightly generic but still related to the primary change set.
Out of Scope Changes Check ✅ Passed All modified files are within the components/hubspot tree and are consistent with the stated bug-fix scope: most edits are version bumps and changes to how after/GTE filters are constructed; no unrelated directories or non-HubSpot components were changed. There are no obvious unrelated feature additions or refactors outside the HubSpot sources.
Docstring Coverage ✅ Passed No functions found in the changes. Docstring coverage check skipped.

Poem

A carrot crunch, a timestamp cheer,
I hop and set the value clear.
No GTE left wanting more—
We only filter when after's for.
Versions bumped, the burrow's bright. 🥕🐇


📜 Recent review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between a101237 and dd8b20f.

📒 Files selected for processing (25)
  • components/hubspot/sources/delete-blog-article/delete-blog-article.mjs (1 hunks)
  • components/hubspot/sources/new-company-property-change/new-company-property-change.mjs (1 hunks)
  • components/hubspot/sources/new-contact-added-to-list/new-contact-added-to-list.mjs (1 hunks)
  • components/hubspot/sources/new-contact-property-change/new-contact-property-change.mjs (3 hunks)
  • components/hubspot/sources/new-custom-object-property-change/new-custom-object-property-change.mjs (3 hunks)
  • components/hubspot/sources/new-deal-in-stage/new-deal-in-stage.mjs (1 hunks)
  • components/hubspot/sources/new-deal-property-change/new-deal-property-change.mjs (3 hunks)
  • components/hubspot/sources/new-email-event/new-email-event.mjs (1 hunks)
  • components/hubspot/sources/new-email-subscriptions-timeline/new-email-subscriptions-timeline.mjs (1 hunks)
  • components/hubspot/sources/new-engagement/new-engagement.mjs (1 hunks)
  • components/hubspot/sources/new-event/new-event.mjs (1 hunks)
  • components/hubspot/sources/new-form-submission/new-form-submission.mjs (1 hunks)
  • components/hubspot/sources/new-note/new-note.mjs (1 hunks)
  • components/hubspot/sources/new-or-updated-blog-article/new-or-updated-blog-article.mjs (1 hunks)
  • components/hubspot/sources/new-or-updated-company/new-or-updated-company.mjs (1 hunks)
  • components/hubspot/sources/new-or-updated-contact/new-or-updated-contact.mjs (1 hunks)
  • components/hubspot/sources/new-or-updated-crm-object/new-or-updated-crm-object.mjs (1 hunks)
  • components/hubspot/sources/new-or-updated-custom-object/new-or-updated-custom-object.mjs (1 hunks)
  • components/hubspot/sources/new-or-updated-deal/new-or-updated-deal.mjs (1 hunks)
  • components/hubspot/sources/new-or-updated-line-item/new-or-updated-line-item.mjs (1 hunks)
  • components/hubspot/sources/new-or-updated-product/new-or-updated-product.mjs (1 hunks)
  • components/hubspot/sources/new-social-media-message/new-social-media-message.mjs (1 hunks)
  • components/hubspot/sources/new-task/new-task.mjs (1 hunks)
  • components/hubspot/sources/new-ticket-property-change/new-ticket-property-change.mjs (3 hunks)
  • components/hubspot/sources/new-ticket/new-ticket.mjs (1 hunks)
✅ Files skipped from review due to trivial changes (21)
  • components/hubspot/sources/new-or-updated-blog-article/new-or-updated-blog-article.mjs
  • components/hubspot/sources/new-form-submission/new-form-submission.mjs
  • components/hubspot/sources/new-ticket/new-ticket.mjs
  • components/hubspot/sources/delete-blog-article/delete-blog-article.mjs
  • components/hubspot/sources/new-engagement/new-engagement.mjs
  • components/hubspot/sources/new-contact-added-to-list/new-contact-added-to-list.mjs
  • components/hubspot/sources/new-email-event/new-email-event.mjs
  • components/hubspot/sources/new-note/new-note.mjs
  • components/hubspot/sources/new-or-updated-contact/new-or-updated-contact.mjs
  • components/hubspot/sources/new-or-updated-line-item/new-or-updated-line-item.mjs
  • components/hubspot/sources/new-task/new-task.mjs
  • components/hubspot/sources/new-event/new-event.mjs
  • components/hubspot/sources/new-deal-in-stage/new-deal-in-stage.mjs
  • components/hubspot/sources/new-social-media-message/new-social-media-message.mjs
  • components/hubspot/sources/new-or-updated-product/new-or-updated-product.mjs
  • components/hubspot/sources/new-or-updated-custom-object/new-or-updated-custom-object.mjs
  • components/hubspot/sources/new-or-updated-deal/new-or-updated-deal.mjs
  • components/hubspot/sources/new-email-subscriptions-timeline/new-email-subscriptions-timeline.mjs
  • components/hubspot/sources/new-or-updated-crm-object/new-or-updated-crm-object.mjs
  • components/hubspot/sources/new-company-property-change/new-company-property-change.mjs
  • components/hubspot/sources/new-or-updated-company/new-or-updated-company.mjs
🚧 Files skipped from review as they are similar to previous changes (4)
  • components/hubspot/sources/new-ticket-property-change/new-ticket-property-change.mjs
  • components/hubspot/sources/new-custom-object-property-change/new-custom-object-property-change.mjs
  • components/hubspot/sources/new-contact-property-change/new-contact-property-change.mjs
  • components/hubspot/sources/new-deal-property-change/new-deal-property-change.mjs
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (4)
  • GitHub Check: Lint Code Base
  • GitHub Check: Publish TypeScript components
  • GitHub Check: Verify TypeScript components
  • GitHub Check: pnpm publish
✨ Finishing touches
  • 📝 Generate Docstrings
🧪 Generate unit tests
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch issue-18339

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.

@michelle0927 michelle0927 marked this pull request as ready for review September 11, 2025 17:52
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

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (5)
components/hubspot/sources/new-company-property-change/new-company-property-change.mjs (1)

62-74: Fix: Unconditional GTE filter sends undefined value (repro symptom).

This recreates the “operator GTE requires a value” error when after is not set on first run. Make the GTE filter conditional.

-    getParams(after) {
-      return {
-        object: "companies",
-        data: {
-          limit: DEFAULT_LIMIT,
-          properties: [
-            this.property,
-          ],
-          sorts: [
-            {
-              propertyName: "hs_lastmodifieddate",
-              direction: "DESCENDING",
-            },
-          ],
-          filterGroups: [
-            {
-              filters: [
-                {
-                  propertyName: this.property,
-                  operator: "HAS_PROPERTY",
-                },
-                {
-                  propertyName: "hs_lastmodifieddate",
-                  operator: "GTE",
-                  value: after,
-                },
-              ],
-            },
-          ],
-        },
-      };
-    },
+    getParams(after) {
+      const params = {
+        object: "companies",
+        data: {
+          limit: DEFAULT_LIMIT,
+          properties: [ this.property ],
+          sorts: [
+            { propertyName: "hs_lastmodifieddate", direction: "DESCENDING" },
+          ],
+          filterGroups: [
+            {
+              filters: [
+                { propertyName: this.property, operator: "HAS_PROPERTY" },
+              ],
+            },
+          ],
+        },
+      };
+      if (after) {
+        params.data.filterGroups[0].filters.push({
+          propertyName: "hs_lastmodifieddate",
+          operator: "GTE",
+          value: after,
+        });
+      }
+      return params;
+    },
components/hubspot/sources/common/common.mjs (3)

55-66: Advance the cursor even when nothing is emitted (seed on first run).

Currently, maxTs is only updated inside the isRelevant branch, so on first run (after undefined) sources that implement isRelevant(ts > after) won’t emit nor advance the cursor, and you may persist 0. Seed maxTs using every item’s ts; emit only when relevant.

Apply:

-    async processEvents(resources, after) {
-      let maxTs = after || 0;
-      for (const result of resources) {
-        if (await this.isRelevant(result, after)) {
-          this.emitEvent(result);
-          const ts = this.getTs(result);
-          if (ts > maxTs) {
-            maxTs = ts;
-          }
-        }
-      }
-      this._setAfter(maxTs);
-    },
+    async processEvents(resources, after) {
+      let maxTs = after || 0;
+      for (const result of resources) {
+        const ts = this.getTs(result);
+        if (await this.isRelevant(result, after, ts)) {
+          this.emitEvent(result);
+        }
+        if (ts > maxTs) {
+          maxTs = ts;
+        }
+      }
+      this._setAfter(maxTs);
+    },

110-141: Mirror seeding logic in paginateUsingHasMore.

Same first-run issue: cursor only advances when isRelevant, risking repeated first-page fetches on fresh deployments.

Apply:

-        for (const item of items) {
-          if (await this.isRelevant(item, after)) {
-            this.emitEvent(item);
-            const ts = this.getTs(item);
-            if (ts > maxTs) {
-              maxTs = ts;
-              this._setAfter(ts);
-            }
-          }
-        }
+        for (const item of items) {
+          const ts = this.getTs(item);
+          if (await this.isRelevant(item, after, ts)) {
+            this.emitEvent(item);
+          }
+          if (ts > maxTs) {
+            maxTs = ts;
+            this._setAfter(ts);
+          }
+        }

1-189: Guard GTE/updated__gte filters behind an after check.

Most property-change sources already push the GTE filter only when after is set; however components/hubspot/sources/new-or-updated-blog-article/new-or-updated-blog-article.mjs sets updated__gte: after unconditionally (around line 50) — wrap that assignment in if (after) or only include the param when after is defined to avoid HubSpot "requires a value" errors.

components/hubspot/sources/new-contact-property-change/new-contact-property-change.mjs (1)

49-81: Guard GTE filter — prefer 24h fallback or a nullish check (apply across HubSpot sources)

  • Good: avoiding an unconditional GTE prevents "operator GTE requires a value".
  • Findings: the truthy check pattern if (after) { ... operator: "GTE", value: after } appears in multiple HubSpot sources; components/hubspot/sources/new-company-property-change/new-company-property-change.mjs contains an unconditional GTE (uses after without a guard) — this must be fixed.
  • Action: Preferred (Option A) — default to now - 24h on first run to avoid fetching large historical datasets. Minimal (Option B) — change truthy check to a nullish check to avoid skipping valid 0-values.
  • Note: use the correct last-modified property per object (contacts: "lastmodifieddate", others: "hs_lastmodifieddate") when applying the change.

Option A (preferred: 24h fallback):

-      if (after) {
-        params.data.filterGroups[0].filters.push({
-          propertyName: "lastmodifieddate",
-          operator: "GTE",
-          value: after,
-        });
-      }
+      const from = (after ?? (Date.now() - 24 * 60 * 60 * 1000));
+      params.data.filterGroups[0].filters.push({
+        propertyName: "lastmodifieddate",
+        operator: "GTE",
+        value: from,
+      });

Option B (minimal: robust null-check):

-      if (after) {
+      if (after != null) {
         params.data.filterGroups[0].filters.push({
           propertyName: "lastmodifieddate",
           operator: "GTE",
           value: after,
         });
-      }
+      }

Apply the chosen change to these files (at the getParams / filter construction sites):

  • components/hubspot/sources/new-contact-property-change/new-contact-property-change.mjs
  • components/hubspot/sources/new-ticket-property-change/new-ticket-property-change.mjs
  • components/hubspot/sources/new-custom-object-property-change/new-custom-object-property-change.mjs
  • components/hubspot/sources/new-deal-property-change/new-deal-property-change.mjs
  • components/hubspot/sources/new-or-updated-contact/new-or-updated-contact.mjs
  • components/hubspot/sources/new-company-property-change/new-company-property-change.mjs (critical — currently uses GTE with after unguarded)
🧹 Nitpick comments (12)
components/hubspot/sources/new-email-event/new-email-event.mjs (1)

40-51: Guard startTimestamp to avoid passing undefined.

Some HTTP clients drop undefined, others serialize it. Safer to include only when after is truthy.

-    getParams(after) {
-      const params = {
-        limit: DEFAULT_LIMIT,
-        startTimestamp: after,
-      };
+    getParams(after) {
+      const params = { limit: DEFAULT_LIMIT };
+      if (after) params.startTimestamp = after;
       if (this.type) {
         params.eventType = this.type;
       }
       return {
         params,
       };
     },
components/hubspot/sources/new-social-media-message/new-social-media-message.mjs (1)

41-47: Conditionally include “since” to avoid empty param.

Prevents sending since: undefined on first run.

-    getParams(after) {
-      return {
-        params: {
-          withChannelKeys: this.channel,
-          since: after,
-        },
-      };
-    },
+    getParams(after) {
+      const params = { withChannelKeys: this.channel };
+      if (after) params.since = after;
+      return { params };
+    },
components/hubspot/sources/new-engagement/new-engagement.mjs (1)

19-19: Typo in user-facing text (“engagment”).

Correct spelling improves UX.

-      description: "Filter results by the type of engagment",
+      description: "Filter results by the type of engagement",
components/hubspot/sources/common/common.mjs (1)

183-187: Optional: default after for first run to reduce load.

If you prefer bounded first-run scans, consider seeding after to Date.now() - 24h when absent, and keep the conditional “only add GTE filter when after is set” in sources.

I can open a follow-up PR if you want this policy applied repo-wide.

components/hubspot/sources/new-deal-in-stage/new-deal-in-stage.mjs (1)

90-116: Advance cursor when no events emitted (first-run).

processDeals only updates after inside isRelevant, so fresh runs with undefined after won’t advance the cursor and may re-scan. Update maxTs for all items; emit only when relevant.

Suggested change:

-        for (const deal of results.results) {
-          const ts = await this.getTs(deal);
-          if (this.isRelevant(ts, after)) {
-            if (deal.properties.hubspot_owner_id) {
-              deal.properties.owner = await this.getOwner(
-                deal.properties.hubspot_owner_id,
-              );
-            }
-            this.emitEvent(deal, ts);
-            if (ts > maxTs) {
-              maxTs = ts;
-              this._setAfter(ts);
-            }
-          }
-        }
+        for (const deal of results.results) {
+          const ts = await this.getTs(deal);
+          if (this.isRelevant(ts, after)) {
+            if (deal.properties.hubspot_owner_id) {
+              deal.properties.owner = await this.getOwner(deal.properties.hubspot_owner_id);
+            }
+            this.emitEvent(deal, ts);
+          }
+          if (ts > maxTs) {
+            maxTs = ts;
+            this._setAfter(ts);
+          }
+        }
components/hubspot/sources/new-email-subscriptions-timeline/new-email-subscriptions-timeline.mjs (1)

29-35: Guard startTimestamp when after is unset.

To avoid sending an explicit 0 or undefined, only set startTimestamp when after is defined, or choose a bounded default (e.g., now - 24h).

-    getParams(after) {
-      return {
-        params: {
-          startTimestamp: after,
-        },
-      };
-    },
+    getParams(after) {
+      const params = {};
+      if (after) params.startTimestamp = after;
+      return { params };
+    },
components/hubspot/sources/new-or-updated-blog-article/new-or-updated-blog-article.mjs (1)

46-54: Avoid passing undefined query params.

Only include updated__gte when after is provided to prevent accidental “undefined” serialization by clients.

-    getParams(after) {
-      return {
-        params: {
-          limit: DEFAULT_LIMIT,
-          updated__gte: after,
-          sort: "-updatedAt",
-        },
-      };
-    },
+    getParams(after) {
+      const params = {
+        limit: DEFAULT_LIMIT,
+        sort: "-updatedAt",
+      };
+      if (after) params.updated__gte = after;
+      return { params };
+    },
components/hubspot/sources/delete-blog-article/delete-blog-article.mjs (1)

29-35: Avoid sending deletedAt__gte when after is undefined.

To mirror the property-change fixes and prevent malformed requests on first run, add the filter only when after is truthy.

-    getParams(after) {
-      return {
-        params: {
-          limit: 100,
-          deletedAt__gte: after,
-          sort: "-updatedAt",
-        },
-      };
-    },
+    getParams(after) {
+      const params = {
+        params: {
+          limit: 100,
+          sort: "-updatedAt",
+        },
+      };
+      if (after) {
+        params.params.deletedAt__gte = after;
+      }
+      return params;
+    },
components/hubspot/sources/new-ticket-property-change/new-ticket-property-change.mjs (2)

46-48: Guard against undefined timestamps to avoid emitting events without history.

On first run (updatedAfter falsy), tickets lacking history return undefined from getTs, and isRelevant would evaluate to true, producing events with ts: undefined. Guard on ts.

-    isRelevant(ticket, updatedAfter) {
-      return !updatedAfter || this.getTs(ticket) > updatedAfter;
-    },
+    isRelevant(ticket, updatedAfter) {
+      const ts = this.getTs(ticket);
+      return Boolean(ts) && (!updatedAfter || ts > updatedAfter);
+    },

50-83: Optional: apply a 24h baseline on first run to avoid heavy backfill and match the linked issue’s expectation.

If you want first-run to start from “now - 1 day”, set a fallback when after is falsy and always include the filter.

-      if (after) {
-        params.data.filterGroups[0].filters.push({
-          propertyName: "hs_lastmodifieddate",
-          operator: "GTE",
-          value: after,
-        });
-      }
+      const baselineAfter = Date.now() - 24 * 60 * 60 * 1000; // 24h
+      const filterAfter = (after ?? baselineAfter);
+      params.data.filterGroups[0].filters.push({
+        propertyName: "hs_lastmodifieddate",
+        operator: "GTE",
+        value: filterAfter,
+      });

If backfill is desired, keep current behavior; otherwise this caps first-run load.

components/hubspot/sources/new-custom-object-property-change/new-custom-object-property-change.mjs (1)

55-87: Conditional GTE avoids HubSpot error; mirror 24h fallback/null-check pattern.

Match contact/deal sources for consistent behavior and first-run load control.

Option A (preferred: 24h fallback):

-      if (after) {
-        params.data.filterGroups[0].filters.push({
-          propertyName: "hs_lastmodifieddate",
-          operator: "GTE",
-          value: after,
-        });
-      }
+      const from = (after ?? (Date.now() - 24 * 60 * 60 * 1000));
+      params.data.filterGroups[0].filters.push({
+        propertyName: "hs_lastmodifieddate",
+        operator: "GTE",
+        value: from,
+      });

Option B (minimal: robust null-check):

-      if (after) {
+      if (after != null) {
         params.data.filterGroups[0].filters.push({
           propertyName: "hs_lastmodifieddate",
           operator: "GTE",
           value: after,
         });
-      }
+      }
components/hubspot/sources/new-deal-property-change/new-deal-property-change.mjs (1)

47-79: Good guard against empty GTE; suggest consistent 24h default and null-check.

Same rationale as other sources: prevent broad first-run pulls and handle 0 safely.

Option A (preferred: 24h fallback):

-      if (after) {
-        params.data.filterGroups[0].filters.push({
-          propertyName: "hs_lastmodifieddate",
-          operator: "GTE",
-          value: after,
-        });
-      }
+      const from = (after ?? (Date.now() - 24 * 60 * 60 * 1000));
+      params.data.filterGroups[0].filters.push({
+        propertyName: "hs_lastmodifieddate",
+        operator: "GTE",
+        value: from,
+      });

Option B (minimal: robust null-check):

-      if (after) {
+      if (after != null) {
         params.data.filterGroups[0].filters.push({
           propertyName: "hs_lastmodifieddate",
           operator: "GTE",
           value: after,
         });
-      }
+      }
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between c4e584e and 0b21d0e.

📒 Files selected for processing (27)
  • components/hubspot/package.json (1 hunks)
  • components/hubspot/sources/common/common.mjs (1 hunks)
  • components/hubspot/sources/delete-blog-article/delete-blog-article.mjs (1 hunks)
  • components/hubspot/sources/new-company-property-change/new-company-property-change.mjs (1 hunks)
  • components/hubspot/sources/new-contact-added-to-list/new-contact-added-to-list.mjs (1 hunks)
  • components/hubspot/sources/new-contact-property-change/new-contact-property-change.mjs (3 hunks)
  • components/hubspot/sources/new-custom-object-property-change/new-custom-object-property-change.mjs (3 hunks)
  • components/hubspot/sources/new-deal-in-stage/new-deal-in-stage.mjs (1 hunks)
  • components/hubspot/sources/new-deal-property-change/new-deal-property-change.mjs (3 hunks)
  • components/hubspot/sources/new-email-event/new-email-event.mjs (1 hunks)
  • components/hubspot/sources/new-email-subscriptions-timeline/new-email-subscriptions-timeline.mjs (1 hunks)
  • components/hubspot/sources/new-engagement/new-engagement.mjs (1 hunks)
  • components/hubspot/sources/new-event/new-event.mjs (1 hunks)
  • components/hubspot/sources/new-form-submission/new-form-submission.mjs (1 hunks)
  • components/hubspot/sources/new-note/new-note.mjs (1 hunks)
  • components/hubspot/sources/new-or-updated-blog-article/new-or-updated-blog-article.mjs (1 hunks)
  • components/hubspot/sources/new-or-updated-company/new-or-updated-company.mjs (1 hunks)
  • components/hubspot/sources/new-or-updated-contact/new-or-updated-contact.mjs (1 hunks)
  • components/hubspot/sources/new-or-updated-crm-object/new-or-updated-crm-object.mjs (1 hunks)
  • components/hubspot/sources/new-or-updated-custom-object/new-or-updated-custom-object.mjs (1 hunks)
  • components/hubspot/sources/new-or-updated-deal/new-or-updated-deal.mjs (1 hunks)
  • components/hubspot/sources/new-or-updated-line-item/new-or-updated-line-item.mjs (1 hunks)
  • components/hubspot/sources/new-or-updated-product/new-or-updated-product.mjs (1 hunks)
  • components/hubspot/sources/new-social-media-message/new-social-media-message.mjs (1 hunks)
  • components/hubspot/sources/new-task/new-task.mjs (1 hunks)
  • components/hubspot/sources/new-ticket-property-change/new-ticket-property-change.mjs (3 hunks)
  • components/hubspot/sources/new-ticket/new-ticket.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/hubspot/sources/common/common.mjs
🧬 Code graph analysis (5)
components/hubspot/sources/common/common.mjs (2)
components/hubspot/sources/new-deal-in-stage/new-deal-in-stage.mjs (1)
  • maxTs (91-91)
components/hubspot/sources/new-form-submission/new-form-submission.mjs (1)
  • maxTs (26-26)
components/hubspot/sources/new-ticket-property-change/new-ticket-property-change.mjs (4)
components/hubspot/sources/common/common.mjs (2)
  • params (185-185)
  • after (184-184)
components/hubspot/sources/new-contact-property-change/new-contact-property-change.mjs (1)
  • params (49-73)
components/hubspot/sources/new-custom-object-property-change/new-custom-object-property-change.mjs (1)
  • params (55-79)
components/hubspot/sources/new-deal-property-change/new-deal-property-change.mjs (1)
  • params (47-71)
components/hubspot/sources/new-contact-property-change/new-contact-property-change.mjs (5)
components/hubspot/sources/new-or-updated-contact/new-or-updated-contact.mjs (1)
  • params (105-120)
components/hubspot/sources/common/common.mjs (2)
  • params (185-185)
  • after (184-184)
components/hubspot/sources/new-custom-object-property-change/new-custom-object-property-change.mjs (1)
  • params (55-79)
components/hubspot/sources/new-deal-property-change/new-deal-property-change.mjs (1)
  • params (47-71)
components/hubspot/sources/new-ticket-property-change/new-ticket-property-change.mjs (1)
  • params (50-74)
components/hubspot/sources/new-deal-property-change/new-deal-property-change.mjs (5)
components/hubspot/sources/new-or-updated-deal/new-or-updated-deal.mjs (1)
  • params (87-102)
components/hubspot/sources/common/common.mjs (2)
  • params (185-185)
  • after (184-184)
components/hubspot/sources/new-contact-property-change/new-contact-property-change.mjs (1)
  • params (49-73)
components/hubspot/sources/new-custom-object-property-change/new-custom-object-property-change.mjs (1)
  • params (55-79)
components/hubspot/sources/new-ticket-property-change/new-ticket-property-change.mjs (1)
  • params (50-74)
components/hubspot/sources/new-custom-object-property-change/new-custom-object-property-change.mjs (4)
components/hubspot/sources/common/common.mjs (2)
  • params (185-185)
  • after (184-184)
components/hubspot/sources/new-contact-property-change/new-contact-property-change.mjs (1)
  • params (49-73)
components/hubspot/sources/new-deal-property-change/new-deal-property-change.mjs (1)
  • params (47-71)
components/hubspot/sources/new-ticket-property-change/new-ticket-property-change.mjs (1)
  • params (50-74)
⏰ 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). (3)
  • GitHub Check: Verify TypeScript components
  • GitHub Check: Publish TypeScript components
  • GitHub Check: Lint Code Base
🔇 Additional comments (26)
components/hubspot/package.json (1)

3-3: Version bump only — LGTM.

components/hubspot/sources/new-task/new-task.mjs (1)

12-12: Version bump only — LGTM.

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

13-13: Version bump only — LGTM.

components/hubspot/sources/new-email-event/new-email-event.mjs (1)

11-11: Version bump only — LGTM.

components/hubspot/sources/new-social-media-message/new-social-media-message.mjs (1)

10-10: Version bump only — LGTM.

components/hubspot/sources/new-company-property-change/new-company-property-change.mjs (1)

10-10: Version bump noted.

components/hubspot/sources/new-engagement/new-engagement.mjs (1)

11-11: Version bump only — LGTM.

components/hubspot/sources/new-or-updated-crm-object/new-or-updated-crm-object.mjs (1)

10-10: Version bump only — LGTM.

components/hubspot/sources/new-or-updated-custom-object/new-or-updated-custom-object.mjs (1)

10-10: LGTM on version bump.

No functional changes here.

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

11-11: LGTM on version bump.

No logic changes.

components/hubspot/sources/new-deal-in-stage/new-deal-in-stage.mjs (1)

14-14: LGTM on version bump.

No functional changes in this file.

components/hubspot/sources/new-email-subscriptions-timeline/new-email-subscriptions-timeline.mjs (1)

9-9: LGTM on version bump.

No behavior changes.

components/hubspot/sources/new-or-updated-product/new-or-updated-product.mjs (1)

13-13: LGTM on version bump.

No functional changes detected.

components/hubspot/sources/new-or-updated-blog-article/new-or-updated-blog-article.mjs (1)

10-10: LGTM on version bump.

No logic changes.

components/hubspot/sources/new-ticket/new-ticket.mjs (1)

13-13: LGTM on version bump.

No behavior changes.

components/hubspot/sources/new-note/new-note.mjs (1)

11-11: Version bump only — OK.

components/hubspot/sources/new-form-submission/new-form-submission.mjs (1)

9-9: Version bump only — OK.

components/hubspot/sources/new-or-updated-company/new-or-updated-company.mjs (1)

13-13: Version bump only — OK.

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

15-15: Version bump only — OK.

components/hubspot/sources/new-or-updated-line-item/new-or-updated-line-item.mjs (1)

13-13: Version bump only — OK.

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

13-13: Version bump only — OK.

components/hubspot/sources/delete-blog-article/delete-blog-article.mjs (1)

9-9: Version bump only — OK.

components/hubspot/sources/new-ticket-property-change/new-ticket-property-change.mjs (1)

50-83: Fix looks good: conditional hs_lastmodifieddate filter resolves the “GTE requires a value” bug.

Building the base params and pushing the GTE filter only when after exists prevents malformed HubSpot requests on first run.

components/hubspot/sources/new-contact-property-change/new-contact-property-change.mjs (1)

10-10: Patch version bump looks good.

components/hubspot/sources/new-custom-object-property-change/new-custom-object-property-change.mjs (1)

10-10: Patch version bump looks good.

components/hubspot/sources/new-deal-property-change/new-deal-property-change.mjs (1)

10-10: Patch version bump looks good.

Copy link
Contributor

@choeqq choeqq left a comment

Choose a reason for hiding this comment

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

Hi @michelle0927, I hope you’re doing well!
Just wanted to kindly check in to see if there are any updates on this PR. My team and I were hoping to release this trigger to production earlier this week, and we’re really looking forward to seeing it merged into the master branch 🙏

@michelle0927
Copy link
Collaborator Author

Hi @choeqq. This PR is awaiting review from @jcortes. Once approved and once it passes QA, it'll be released. Probably within a few days.

Copy link
Collaborator

@jcortes jcortes left a comment

Choose a reason for hiding this comment

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

HI @michelle0927 lgtm! Ready for QA!

@vunguyenhung vunguyenhung merged commit a031ecb into master Sep 16, 2025
10 checks passed
@vunguyenhung vunguyenhung deleted the issue-18339 branch September 16, 2025 01:42
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.

[BUG] Breaking change on Hubspot common -> New contact property change
4 participants