Skip to content

Conversation

@michelle0927
Copy link
Collaborator

@michelle0927 michelle0927 commented Sep 17, 2025

Resolves #18315

Summary by CodeRabbit

  • New Features

    • Added "Changes to Files in Drive" trigger to watch files, emit deduplicated/throttled events, optionally provide temporary download links, and seed recent changes on setup.
    • Webhook handling now returns an immediate 200 response for HTTP invocations.
  • Bug Fixes / Behavior

    • "Changes to Specific Files" shows an in-app notice about the 10-file limit and enforces it at setup.
    • Default per-file dedupe interval increased (less frequent duplicate events by default).
  • Chores

    • Bumped Google Drive component versions (including package).

@vercel
Copy link

vercel bot commented Sep 17, 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 21, 2025 3:50pm
pipedream-docs-redirect-do-not-edit Ignored Ignored Sep 21, 2025 3:50pm

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Sep 17, 2025

Walkthrough

Adds a new Google Drive source "Changes to Files in Drive" using the Drive Changes API; enforces a 10-file deploy-time limit for the "Changes to Specific Files" source with an info alert; fetches full file metadata and changes id generation in the shared-drive specific-files variant; adjusts common dedupe/default interval and webhook HTTP prop to support custom responses; and bumps several package/source versions.

Changes

Cohort / File(s) Summary
Package version bump
components/google_drive/package.json
Version updated from 1.0.7 to 1.1.0.
New source: Changes to Files in Drive
components/google_drive/sources/changes-to-files-in-drive/changes-to-files-in-drive.mjs
New source using Drive Changes API. Adds props (infoAlert, drive, files, includeLink, dir, dedupe props), deploy seeding of recent non-folder/non-trashed files (last 30 days), methods for update types, relevance checks, meta generation, change parsing, processing (including optional stashFile link generation) and minimum-interval throttling.
Specific files source: alert + deploy guard
components/google_drive/sources/changes-to-specific-files/changes-to-specific-files.mjs
Adds infoAlert prop explaining the 10-file limit, bumps version 0.3.00.3.1, and adds hooks.deploy() that throws ConfigurationError if this.files.length > 10, otherwise delegates to base deploy.
Shared-drive specific files: fetch full file metadata & metadata id change
components/google_drive/sources/changes-to-specific-files-shared-drive/changes-to-specific-files-shared-drive.mjs
Bumps version 0.3.00.3.1. processChange now fetches full file details via this.googleDrive.getFile(file.id) into fileInfo; when includeLink is enabled, stashes into fileInfo.file; emits fileInfo as payload; and generateMeta now uses timestamp-only id generation (\${fileId}-${ts}``).
Common dedupe change
components/google_drive/sources/common-dedupe-changes.mjs
Default perFileInterval changed from 1 to 3 (minutes).
Common webhook: custom HTTP response + run() change
components/google_drive/sources/common-webhook.mjs
http prop changed from http: "$.interface.http" to http: { type: "$.interface.http", customResponse: true }. run(event) now issues this.http.respond({ status: 200 }) for non-timer (HTTP) invocations before continuing processing.
Minor version bumps (no logic changes)
components/google_drive/sources/new-files-instant/new-files-instant.mjs, components/google_drive/sources/new-files-shared-drive/new-files-shared-drive.mjs, components/google_drive/sources/new-or-modified-comments/new-or-modified-comments.mjs, components/google_drive/sources/new-or-modified-files/new-or-modified-files.mjs, components/google_drive/sources/new-or-modified-folders/new-or-modified-folders.mjs, components/google_drive/sources/new-spreadsheet/new-spreadsheet.mjs
Version bumps only: new-files-instant 0.2.0→0.2.1; new-files-shared-drive 0.1.0→0.1.1; new-or-modified-comments 1.0.9→1.0.10; new-or-modified-files 0.4.0→0.4.1; new-or-modified-folders 0.2.2→0.2.3; new-spreadsheet 0.1.15→0.1.16.

Sequence Diagram(s)

sequenceDiagram
  autonumber
  actor U as User
  participant S as Source: Changes to Files in Drive
  participant GD as Google Drive (Changes API)
  participant ST as Stash Service (optional)
  participant E as Event Stream

  U->>S: Configure (drive, files, includeLink, dir, dedupe)
  Note over S: Deploy seeds recent changes (last 30 days)
  S->>GD: List recent changes
  GD-->>S: Change candidates (file metadata + headers)
  S->>S: Filter relevant files & check minimum interval
  alt includeLink enabled
    S->>ST: stashFile(file)
    ST-->>S: temp link + metadata
  end
  S->>E: Emit event {file payload, meta}
Loading
sequenceDiagram
  autonumber
  participant SS as Source: Changes to Specific Files
  participant Base as Base deploy

  Note over SS: Deploy-time validation (10-file limit)
  SS->>SS: if this.files.length > 10
  alt > 10 files
    SS-->>SS: throw ConfigurationError
  else <= 10 files
    SS->>Base: delegate deploy()
    Base-->>SS: complete
  end
Loading
sequenceDiagram
  autonumber
  participant H as Common Webhook
  participant HTTP as HTTP Interface
  participant S as Source Logic

  HTTP->>H: Incoming HTTP notification (not timer)
  H->>HTTP: respond({status:200})  %% customResponse path
  H->>S: continue processing headers & changes
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Poem

I hopped through change logs, swift and spry,
Seeded recent files beneath the sky.
Ten doors guarded, full files told,
Links stashed warm in burrows of gold.
A cheery hop — the updates fly! 🥕

Pre-merge checks and finishing touches

❌ Failed checks (3 warnings)
Check name Status Explanation Resolution
Linked Issues Check ⚠️ Warning The linked issue requires migrating all watchFile()-based triggers to the Changes API, implementing a watchChanges(fileIds = []) approach, and refactoring activateFileHook() and renewFileSubscription() across Drive and Sheets base files; this PR adds a Changes-API-based source and updates several google_drive sources but does not implement a centralized watchChanges function nor refactor the shared base files (base.mjs, drive.mjs, sheet.mjs) or google_sheets triggers, so the primary objectives are not fully satisfied. Either extend this PR to implement the watchChanges API and refactor activateFileHook()/renewFileSubscription() in the specified shared base files and update google_sheets triggers (with tests demonstrating no remaining watchFile() usage), or update the linked issue/PR description to explicitly narrow scope to the new source and the specific google_drive changes included here.
Out of Scope Changes Check ⚠️ Warning The PR contains behavioral changes not justified by the linked issue, notably changing the default perFileInterval from 1 to 3 in components/google_drive/sources/common-dedupe-changes.mjs and altering HTTP handling to use customResponse with an immediate 200 response in components/google_drive/sources/common-webhook.mjs, plus multiple unrelated version bumps; these affect runtime behavior and should be justified or split out. Separate or document these behavioral/default-value changes in their own PRs with rationale, tests, and changelog entries, or include explicit justification and regression tests in this PR showing why they are required for the Changes API migration and demonstrating they do not introduce unintended side effects.
Description Check ⚠️ Warning The PR description only contains "Resolves #18315" and does not follow the repository template (the required "## WHY" section is missing) nor does it provide a summary of changes, testing steps, migration notes, or relevant file-level details required by the template. Update the PR description to follow the repository template by adding a filled "## WHY" section explaining the rationale, a concise summary of the changes (including new source path and key modified files), testing/deployment instructions, migration or backward-compatibility notes (e.g., 10-file limit enforcement, per-file dedupe default change, webhook behavior), and links to any relevant docs or tests.
✅ Passed checks (2 passed)
Check name Status Explanation
Title Check ✅ Passed The title accurately and specifically summarizes the primary change: it names the new Google Drive source and states the key implementation shift from the File Subscriptions API to the Changes API, which matches the changeset (addition of components/google_drive/sources/changes-to-files-in-drive and related updates).
Docstring Coverage ✅ Passed No functions found in the changes. Docstring coverage check skipped.
✨ 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-18315

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

🧹 Nitpick comments (7)
components/google_drive/sources/changes-to-specific-files/changes-to-specific-files.mjs (1)

59-64: Null‑safe guard for files selection.

Accessing this.files.length can throw if files is unset. Make the check null/array‑safe to avoid deploy‑time crashes.

Apply this diff:

 async deploy() {
-  if (this.files.length > 10) {
-    throw new ConfigurationError("This source only supports up to 10 files");
-  }
+  if (!Array.isArray(this.files) || this.files.length === 0) {
+    throw new ConfigurationError("Select at least one file (max 10).");
+  }
+  if (this.files.length > 10) {
+    throw new ConfigurationError("This source only supports up to 10 files.");
+  }
   await changesToSpecificFiles.hooks.deploy.bind(this)();
 },
components/google_drive/sources/changes-to-files-in-drive/changes-to-files-in-drive.mjs (6)

62-66: Explicitly request file fields needed for seeding.

fields: "files" risks omitting name/modifiedTime (used later). Request them explicitly to avoid NaN timestamps and “Untitled” summaries during deploy seeding.

Apply this diff:

-      const args = this.getListFilesOpts({
-        q: `mimeType != "application/vnd.google-apps.folder" and modifiedTime > "${timeString}" and trashed = false`,
-        fields: "files",
-        pageSize: 5,
-      });
+      const args = this.getListFilesOpts({
+        q: `mimeType != "application/vnd.google-apps.folder" and modifiedTime > "${timeString}" and trashed = false`,
+        // Include nextPageToken and explicit file subfields used downstream
+        fields: "nextPageToken, files(id, name, modifiedTime, mimeType)",
+        pageSize: 5,
+      });

132-145: Reduce noisy logs and guard empty input.

The triple debug logs with full JSON can be very chatty in prod and may include large payloads. Add an early return and gate verbose logs.

Apply this diff:

-      console.log(`Processing ${changedFiles.length} changed files`);
-      console.log(`Changed files: ${JSON.stringify(changedFiles, null, 2)}!!!`);
-      console.log(`Files: ${this.files}!!!`);
+      if (!Array.isArray(changedFiles) || changedFiles.length === 0) {
+        return;
+      }
+      if (process.env.PIPEDREAM_DEBUG === "true") {
+        console.log(`Processing ${changedFiles.length} changed files`);
+      }

83-101: Harden meta timestamp fallback.

When headers are absent (deploy seeding) or modifiedTime is missing, Date.parse yields NaN. Provide a safe fallback to Date.now().

Apply this diff:

-      const ts = Date.parse(tsString);
+      const parsed = tsString ? Date.parse(tsString) : NaN;
+      const ts = Number.isFinite(parsed) ? parsed : Date.now();

120-129: Don’t fail the whole event if stashing the file fails.

Wrap stashFile in a try/catch so a transient download/export error doesn’t block emission of the change event.

Apply this diff:

-      if (this.includeLink) {
-        file.file = await stashFile(file, this.googleDrive, this.dir);
-      }
+      if (this.includeLink) {
+        try {
+          file.file = await stashFile(file, this.googleDrive, this.dir);
+        } catch (err) {
+          console.warn("stashFile failed, emitting without link:", err?.message || err);
+        }
+      }

106-119: Capture extra headers for diagnostics (optional).

Including x-goog-channel-id can help correlate webhook deliveries during debugging.

Apply this diff:

       return {
         change: {
           state: headers["x-goog-resource-state"],
           resourceURI: headers["x-goog-resource-uri"],
           changed: headers["x-goog-changed"], // "Additional details about the changes. Possible values: content, parents, children, permissions"
+          channelId: headers["x-goog-channel-id"],
         },
       };

103-105: Micro: speed up relevance checks for many files.

For large files lists, consider a Set to avoid O(n) membership checks on each file.

Example:

// initialize once (e.g., in activate/deploy or lazy getter)
this._filesSet = new Set(this.files);

// then:
isFileRelevant(file) {
  return this._filesSet.has(file.id);
}
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 2467552 and 8e5b65d.

📒 Files selected for processing (3)
  • components/google_drive/package.json (1 hunks)
  • components/google_drive/sources/changes-to-files-in-drive/changes-to-files-in-drive.mjs (1 hunks)
  • components/google_drive/sources/changes-to-specific-files/changes-to-specific-files.mjs (3 hunks)
🧰 Additional context used
🧬 Code graph analysis (1)
components/google_drive/sources/changes-to-files-in-drive/changes-to-files-in-drive.mjs (2)
components/google_drive/sources/changes-to-specific-files/changes-to-specific-files.mjs (2)
  • files (80-80)
  • file (238-240)
components/google_drive/google_drive.app.mjs (1)
  • changedFiles (393-395)
⏰ 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 (5)
components/google_drive/package.json (1)

3-3: Version bump looks right for adding a new source.

Minor bump from 1.0.x → 1.1.0 aligns with a backwards‑compatible feature addition.

components/google_drive/sources/changes-to-specific-files/changes-to-specific-files.mjs (3)

6-6: Good addition: explicit ConfigurationError import.

Enables clear config‑time validation without generic exceptions.


19-19: Version bump acknowledged.

Patch bump to 0.3.1 is appropriate for a non‑breaking guard + copy change.


25-29: Helpful UX: info alert about the 10‑file limit.

Clear guidance to use the Changes API–based source for >10 files.

components/google_drive/sources/changes-to-files-in-drive/changes-to-files-in-drive.mjs (1)

1-74: Confirmed: source uses the Changes API (drive.changes.watch & drive.changes.list)

components/google_drive/google_drive.app.mjs implements listChanges (calls drive.changes.list) and a watch path that calls drive.changes.watch; components/google_drive/sources/changes-to-files-in-drive/changes-to-files-in-drive.mjs references changes.watch and contains no files.watch calls (files.watch is used only by changes-to-specific-files/watchFile).

jcortes
jcortes previously approved these changes Sep 17, 2025
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!

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

🧹 Nitpick comments (1)
components/google_drive/sources/changes-to-specific-files-shared-drive/changes-to-specific-files-shared-drive.mjs (1)

139-142: Trim noisy logs

The triple “!!!” debug prints are noisy. Prefer this.$logger.debug (or remove) and avoid logging entire file arrays in production paths.

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 8e5b65d and 962ab66.

📒 Files selected for processing (2)
  • components/google_drive/sources/changes-to-files-in-drive/changes-to-files-in-drive.mjs (1 hunks)
  • components/google_drive/sources/changes-to-specific-files-shared-drive/changes-to-specific-files-shared-drive.mjs (2 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • components/google_drive/sources/changes-to-files-in-drive/changes-to-files-in-drive.mjs
🧰 Additional context used
🧬 Code graph analysis (1)
components/google_drive/sources/changes-to-specific-files-shared-drive/changes-to-specific-files-shared-drive.mjs (1)
components/google_drive/sources/changes-to-files-in-drive/changes-to-files-in-drive.mjs (4)
  • fileInfo (125-125)
  • eventToEmit (126-129)
  • changes (121-121)
  • meta (130-130)
⏰ 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: Verify TypeScript components
  • GitHub Check: Publish TypeScript components
  • GitHub Check: pnpm publish
🔇 Additional comments (1)
components/google_drive/sources/changes-to-specific-files-shared-drive/changes-to-specific-files-shared-drive.mjs (1)

31-31: Version bump to 0.3.1 looks good; ensure consistency across artifacts

Keep this in sync with package/version docs and any release notes.

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

🧹 Nitpick comments (3)
components/google_drive/sources/common-dedupe-changes.mjs (2)

16-16: Default raised to 3 min — update the user-facing alert text to match.

The alert still says “at least 1 minute.” Sync it to 3 minutes to avoid confusion.

Apply:

-      content: `This source can emit many events in quick succession while a file is being edited. By default, it will not emit another event for the same file for at least 1 minute.
+      content: `This source can emit many events in quick succession while a file is being edited. By default, it will not emit another event for the same file for at least 3 minutes.
 \
 You can change or disable this minimum interval using the prop \`Minimum Interval Per File\`.`,

Also applies to: 6-9


1-19: Optional: de‑duplicate the “3” with a single constant to prevent future drift.

Keeps the alert copy and the prop default in lockstep.

+const DEFAULT_PER_FILE_INTERVAL_MINUTES = 3;
+
 export default {
   props: {
     intervalAlert: {
       type: "alert",
       alertType: "info",
-      content: `This source can emit many events in quick succession while a file is being edited. By default, it will not emit another event for the same file for at least 1 minute.
+      content: `This source can emit many events in quick succession while a file is being edited. By default, it will not emit another event for the same file for at least ${DEFAULT_PER_FILE_INTERVAL_MINUTES} minutes.
 \
 You can change or disable this minimum interval using the prop \`Minimum Interval Per File\`.`,
     },
     perFileInterval: {
       type: "integer",
       label: "Minimum Interval Per File",
       description: "How many minutes to wait until the same file can emit another event.\n\nIf set to `0`, this interval is disabled and all events will be emitted.",
       min: 0,
       max: 60,
-      default: 3,
+      default: DEFAULT_PER_FILE_INTERVAL_MINUTES,
       optional: true,
     },
   },

Also applies to: 16-16

components/google_drive/sources/common-webhook.mjs (1)

163-166: Early 200 before processing is good; add a try/catch around change processing for resilience.

If processing throws after the ACK, we silently fail and may reprocess on the next delivery. Log explicitly to aid ops.

-    const driveId = this.getDriveId();
-    const changedFilesStream = this.googleDrive.listChanges(pageToken, driveId);
-    for await (const changedFilesPage of changedFilesStream) {
-      const {
-        changedFiles,
-        nextPageToken,
-      } = changedFilesPage;
-
-      // Process all the changed files retrieved from the current page
-      await this.processChanges(changedFiles, headers);
-
-      // After successfully processing the changed files, we store the page
-      // token of the next page
-      this._setPageToken(nextPageToken);
-    }
+    const driveId = this.getDriveId();
+    try {
+      const changedFilesStream = this.googleDrive.listChanges(pageToken, driveId);
+      for await (const changedFilesPage of changedFilesStream) {
+        const { changedFiles, nextPageToken } = changedFilesPage;
+        await this.processChanges(changedFiles, headers);
+        this._setPageToken(nextPageToken);
+      }
+    } catch (err) {
+      console.error("Error processing Google Drive changes", {
+        err,
+        channelID,
+        pageToken,
+        driveId,
+      });
+    }

Also applies to: 196-210

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 5611138 and fc04d8a.

📒 Files selected for processing (9)
  • components/google_drive/sources/changes-to-files-in-drive/changes-to-files-in-drive.mjs (1 hunks)
  • components/google_drive/sources/common-dedupe-changes.mjs (1 hunks)
  • components/google_drive/sources/common-webhook.mjs (2 hunks)
  • components/google_drive/sources/new-files-instant/new-files-instant.mjs (1 hunks)
  • components/google_drive/sources/new-files-shared-drive/new-files-shared-drive.mjs (1 hunks)
  • components/google_drive/sources/new-or-modified-comments/new-or-modified-comments.mjs (1 hunks)
  • components/google_drive/sources/new-or-modified-files/new-or-modified-files.mjs (1 hunks)
  • components/google_drive/sources/new-or-modified-folders/new-or-modified-folders.mjs (1 hunks)
  • components/google_drive/sources/new-spreadsheet/new-spreadsheet.mjs (1 hunks)
✅ Files skipped from review due to trivial changes (6)
  • components/google_drive/sources/new-or-modified-comments/new-or-modified-comments.mjs
  • components/google_drive/sources/new-or-modified-files/new-or-modified-files.mjs
  • components/google_drive/sources/new-files-shared-drive/new-files-shared-drive.mjs
  • components/google_drive/sources/new-or-modified-folders/new-or-modified-folders.mjs
  • components/google_drive/sources/new-spreadsheet/new-spreadsheet.mjs
  • components/google_drive/sources/new-files-instant/new-files-instant.mjs
🚧 Files skipped from review as they are similar to previous changes (1)
  • components/google_drive/sources/changes-to-files-in-drive/changes-to-files-in-drive.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). (3)
  • GitHub Check: Verify TypeScript components
  • GitHub Check: Publish TypeScript components
  • GitHub Check: Lint Code Base
🔇 Additional comments (1)
components/google_drive/sources/common-webhook.mjs (1)

13-16: Approve — customResponse enabled; no duplicate responders found

Enabling customResponse is correct for a fast 200 ACK. Repo search shows the only responder in components/google_drive is this.http.respond at components/google_drive/sources/common-webhook.mjs:164–166.

@michelle0927
Copy link
Collaborator Author

/approve

@michelle0927 michelle0927 merged commit 6545da9 into master Sep 22, 2025
10 checks passed
@michelle0927 michelle0927 deleted the issue-18315 branch September 22, 2025 14: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.

[TRIGGER] Migrate from Google Drive File Subscriptions API to Changes API to Avoid Rate Limits

3 participants