Skip to content

Conversation

@jcortes
Copy link
Collaborator

@jcortes jcortes commented Nov 27, 2025

WHY

Resolves #19119

Summary by CodeRabbit

  • New Features
    • New "New Comment" polling source to emit events when comments are added.
    • New "New Updates" polling source to emit events when rows or cells change.
    • Batched snapshot/storage support with configurable max rows for large spreadsheets.
    • Added test event fixtures for comments and updates to aid testing.
    • Google Sheets component version bumped to 0.13.0 (and internal source version updates).

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

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

vercel bot commented Nov 27, 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 Dec 4, 2025 5:44pm
pipedream-docs-redirect-do-not-edit Ignored Ignored Dec 4, 2025 5:44pm

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Nov 27, 2025

Walkthrough

Adds polling-based Google Sheets sources ("New Comment" and "New Updates"), shared processing modules and test fixtures, introduces batched storage for large sheets, and bumps package version to 0.13.0.

Changes

Cohort / File(s) Summary
Version Management
components/google_sheets/package.json
Version bumped from 0.12.0 to 0.13.0.
Shared New Comment Logic
components/google_sheets/sources/common/new-comment.mjs
New module exporting methods to read/write last-processed timestamp, generate event metadata, derive sheet id, fetch comments since lastTs, update lastTs, and emit events.
New Comment Polling Source + Fixture
components/google_sheets/sources/new-comment-polling/new-comment-polling.mjs, components/google_sheets/sources/new-comment-polling/test-event.mjs
New polling source that composes common comment logic with base timer/db props and exposes watchedDrive/sheetID; run() delegates to processSpreadsheet. Adds a comment event fixture.
Shared New Updates Logic (batching)
components/google_sheets/sources/common/new-updates.mjs
Adds maxRows prop, batching helpers (getBatchSize, getMaxRows, _getBatchKey, _getBatchedSheetValues, _setBatchedSheetValues), and migrates snapshot/diff/storage to batched read/write to support large sheets.
New Updates Polling Source + Fixture
components/google_sheets/sources/new-updates-polling/new-updates-polling.mjs, components/google_sheets/sources/new-updates-polling/test-event.mjs
New polling source for row/cell updates with props (googleSheets, db, timer, alert, watchedDrive, sheetID, worksheetIDs, monitoringRange), deploy hook to snapshot, content-diff and change detection methods, and a fixture for worksheet values/changes.
Version Bump in Existing Source
components/google_sheets/sources/new-updates/new-updates.mjs
version updated from 0.3.3 to 0.3.4 (no functional changes).

Sequence Diagram(s)

sequenceDiagram
    participant Timer as Polling Timer
    participant Source as Polling Source
    participant DB as Local DB
    participant API as Google Sheets API
    participant Emitter as Event Emitter

    loop polling interval
        Timer->>Source: run()
        Source->>DB: read lastTs / read batched snapshot
        DB-->>Source: lastTs / oldValues
        Source->>API: listComments(...) or getSpreadsheet/getValues(...)
        API-->>Source: comments or currentValues
        alt New comments or diffs found
            Source->>DB: write lastTs and/or write batched values
            loop For each new item
                Source->>Source: build meta / compute diff
                Source->>Emitter: $emit(item, meta)
            end
        else No changes
            Source->>Source: early exit
        end
    end
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

  • Review batching logic in components/google_sheets/sources/common/new-updates.mjs (batch size, maxRows enforcement, batch key lifecycle, reconstruction).
  • Validate timestamp persistence, ordering, and early-exit behavior in components/google_sheets/sources/common/new-comment.mjs.
  • Confirm props/methods composition and delegation between common modules and polling wrappers (new-comment-polling, new-updates-polling).
  • Inspect fixtures (test-event.mjs) for fidelity to expected Google API payload shapes and dedupe behavior.

Pre-merge checks and finishing touches

✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly describes the main change: adding polling options as an alternative to webhook-based Google Sheets triggers, which aligns with the actual code changes that introduce new polling sources.
Description check ✅ Passed The pull request description is minimal but sufficient, referencing the resolved issue #19119. However, it lacks details about what was implemented or the scope of changes.
Linked Issues check ✅ Passed The PR successfully implements polling sources for 'New Comment' and 'New Updates' as requested in issue #19119. Two of three targeted components (New Comment Polling and New Updates Polling) are fully implemented with test events and proper versioning.
Out of Scope Changes check ✅ Passed All changes are directly related to implementing polling alternatives for Google Sheets. Version bumps and package.json updates are standard for feature releases. No unrelated or out-of-scope modifications detected.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch google-sheets-polling-soures-alternative

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.

lcaresia
lcaresia previously approved these changes Dec 1, 2025
Copy link
Collaborator

@lcaresia lcaresia left a comment

Choose a reason for hiding this comment

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

LGTM!

@vunguyenhung
Copy link
Collaborator

@vunguyenhung
Copy link
Collaborator

Hello everyone, I have tested this PR and there're some test cases failed or needed improvement.

Please check test reports below for more information:

@jcortes
Copy link
Collaborator Author

jcortes commented Dec 2, 2025

Hi @vunguyenhung can you please share the steps with Google Sheets so I can reproduce the OOM problem, thanks!

@vunguyenhung
Copy link
Collaborator

Hi @jcortes, will draft the reproduce steps and share with you in a few hours

@jcortes jcortes force-pushed the google-sheets-polling-soures-alternative branch 2 times, most recently from d6b8d91 to 0923613 Compare December 2, 2025 19:40
@jcortes
Copy link
Collaborator Author

jcortes commented Dec 2, 2025

Hi @vunguyenhung I've made some changes to new-updates source, so maybe that can fix the OOM issue so test again with this change please, thanks!

@jcortes jcortes force-pushed the google-sheets-polling-soures-alternative branch from 0923613 to fd256c9 Compare December 2, 2025 19:42
@vunguyenhung
Copy link
Collaborator

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

Test reports

@vunguyenhung
Copy link
Collaborator

Hello everyone, I have tested this PR and there're some test cases failed or needed improvement.

Please check test reports below for more information:

@jcortes jcortes force-pushed the google-sheets-polling-soures-alternative branch from fd256c9 to 93e1cce Compare December 3, 2025 16:25
@jcortes
Copy link
Collaborator Author

jcortes commented Dec 3, 2025

Hi @vunguyenhung I've made the changes you requested, please test again, thanks!

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 7

Caution

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

⚠️ Outside diff range comments (2)
components/google_sheets/sources/common/new-updates.mjs (2)

188-193: Bug: Incorrect reference oldValues.length should be oldValues[i].length.

On line 192, oldValues.length returns the total row count instead of the column count for row i. This is a pre-existing bug but affects the accuracy of change detection when columns are added/removed.

       else
         colCount =
           newValues[i].length > oldValues[i].length
             ? newValues[i].length
-            : oldValues.length;
+            : oldValues[i].length;
       return colCount;

255-282: Consider emitting currentValues in the event payload for consistency.

The processSpreadsheet method emits worksheet and changes but not currentValues. Looking at the test fixture in test-event.mjs, the expected event structure includes currentValues. This inconsistency could cause issues for downstream consumers.

           this.$emit(
             {
               worksheet,
+              currentValues,
               changes,
             },
             this.getMeta(spreadsheet, worksheet),
           );
📜 Review details

Configuration used: CodeRabbit UI

Review profile: ASSERTIVE

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between be57ab6 and 93e1cce.

📒 Files selected for processing (8)
  • components/google_sheets/package.json (1 hunks)
  • components/google_sheets/sources/common/new-comment.mjs (1 hunks)
  • components/google_sheets/sources/common/new-updates.mjs (7 hunks)
  • components/google_sheets/sources/new-comment-polling/new-comment-polling.mjs (1 hunks)
  • components/google_sheets/sources/new-comment-polling/test-event.mjs (1 hunks)
  • components/google_sheets/sources/new-updates-polling/new-updates-polling.mjs (1 hunks)
  • components/google_sheets/sources/new-updates-polling/test-event.mjs (1 hunks)
  • components/google_sheets/sources/new-updates/new-updates.mjs (1 hunks)
🧰 Additional context used
🧠 Learnings (1)
📚 Learning: 2025-01-23T03:55:15.166Z
Learnt from: GTFalcao
Repo: PipedreamHQ/pipedream PR: 15376
File: components/monday/sources/name-updated/name-updated.mjs:6-6
Timestamp: 2025-01-23T03:55:15.166Z
Learning: Source names in Monday.com components don't need to start with "New" if they emit events for updated items (e.g., "Name Updated", "Column Value Updated") rather than new items. This follows the component guidelines exception where the "New" prefix is only required when emits are limited to new items.

Applied to files:

  • components/google_sheets/sources/new-updates/new-updates.mjs
🧬 Code graph analysis (2)
components/google_sheets/sources/new-comment-polling/new-comment-polling.mjs (1)
components/google_sheets/actions/create-spreadsheet/create-spreadsheet.mjs (1)
  • googleSheets (60-66)
components/google_sheets/sources/new-updates-polling/new-updates-polling.mjs (1)
components/google_sheets/sources/common/new-updates.mjs (8)
  • spreadsheet (248-254)
  • sheetId (196-196)
  • sheetId (210-210)
  • baseId (197-197)
  • baseId (234-234)
  • baseId (281-281)
  • oldValues (198-198)
  • currentValues (199-202)
⏰ 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: Lint Code Base
  • GitHub Check: Publish TypeScript components
  • GitHub Check: Verify TypeScript components
🔇 Additional comments (6)
components/google_sheets/package.json (1)

3-3: LGTM!

The minor version bump from 0.12.0 to 0.13.0 is appropriate for introducing new polling source features.

components/google_sheets/sources/new-updates/new-updates.mjs (1)

12-12: LGTM!

Patch version bump appropriately reflects the inherited batching improvements from the common module.

components/google_sheets/sources/new-comment-polling/test-event.mjs (1)

1-21: LGTM!

The test fixture provides a realistic Google Drive comment structure with all necessary fields for testing the new polling source.

components/google_sheets/sources/new-updates-polling/test-event.mjs (1)

1-71: LGTM!

The test fixture accurately represents the event structure emitted by processSpreadsheet(), including worksheet metadata, current values, and change tracking.

components/google_sheets/sources/common/new-comment.mjs (1)

19-34: The code is correct. listComments properly handles undefined as the second parameter by omitting the startModifiedTime filter when it's not set, allowing the API to return recent comments on first run.

components/google_sheets/sources/new-updates-polling/new-updates-polling.mjs (1)

14-62: Props, polling timer, and DB usage look consistent with existing patterns

Using db: "$.service.db", $.interface.timer with DEFAULT_POLLING_SOURCE_TIMER_INTERVAL, and an explicit monitoringRange prop plus the informational alert aligns well with the new batched polling design and the performance concerns in large sheets. I don’t see issues here.

@vunguyenhung
Copy link
Collaborator

Hello everyone, I have tested this PR and there're some test cases failed or needed improvement.

Please check test reports below for more information:

@jcortes jcortes force-pushed the google-sheets-polling-soures-alternative branch from 93e1cce to 251e796 Compare December 4, 2025 17:44
@jcortes
Copy link
Collaborator Author

jcortes commented Dec 4, 2025

Hi @vunguyenhung please test again with latest push, thanks!

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

Caution

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

⚠️ Outside diff range comments (2)
components/google_sheets/sources/common/new-updates.mjs (2)

170-193: Bug in getColCount: uses oldValues.length instead of oldValues[i].length.

In the final else branch (line 188), the function returns oldValues.length (the row count) instead of oldValues[i].length (the column count of row i). This causes the for loop in getContentChanges to iterate an incorrect number of times, leading to missed or extra cells being processed.

The fix is to change line 192:

-            : oldValues.length;
+            : oldValues[i].length;

195-207: Fix getContentChanges to handle null oldValues from missing snapshot.

When _getBatchedSheetValues returns null (no prior snapshot exists), getContentDiff preserves that as null. On first run or when a new worksheet is added after the last snapshot, downstream code crashes:

  • getContentChanges at line 289 directly accesses oldValues.length without checking for null, causing a runtime error.
  • While getRowCount has a guard (if (oldValues && oldValues.length)), it only determines row count; the subsequent call to getContentChanges still receives null.
  • The guard at line 273 (if (rowCount === 0 && !oldValues)) only prevents the issue when both conditions hold; it does not protect the case where currentValues exists but oldValues is null.

Two straightforward fixes:

  1. Simpler: treat missing data as an empty array (restores prior behavior):
-      const oldValues = this._getBatchedSheetValues(baseId) || null;
+      const oldValues = this._getBatchedSheetValues(baseId) || [];
  1. Alternatively: guard before calling getContentChanges in processSpreadsheet:
       const changes = await this.getContentChanges(
         currentValues,
         oldValues,
       );
+      if (!oldValues) {
+        const baseId = `${spreadsheet.spreadsheetId}${worksheet.properties.sheetId}`;
+        const rawNewValues = currentValues.values || [];
+        const newValues = rawNewValues.slice(0, this.getMaxRows());
+        this._setBatchedSheetValues(baseId, newValues);
+        continue;
+      }

Option (1) is simpler and avoids the crash. Either way, this must be addressed.

♻️ Duplicate comments (6)
components/google_sheets/sources/common/new-updates.mjs (2)

91-112: Simplify _getBatchedSheetValues loop.

hasMore is redundant since you set it to false immediately before break. You can simplify the loop without changing behavior:

-    _getBatchedSheetValues(baseId) {
-      const allValues = [];
-      let batchIndex = 0;
-      let hasMore = true;
-
-      while (hasMore) {
+    _getBatchedSheetValues(baseId) {
+      const allValues = [];
+      let batchIndex = 0;
+
+      while (true) {
         const batchKey = this._getBatchKey(baseId, batchIndex);
         const batchValues = this._getSheetValues(batchKey);
 
         if (!batchValues) {
-          hasMore = false;
           break;
         }
 
         allValues.push(...batchValues);
         batchIndex++;
       }

This improves readability without affecting functionality.


113-135: Avoid db.set(key, undefined) for clearing batches.

The current batch-clear loop relies on:

while (this.db.get(this._getBatchKey(baseId, batchIndex))) {
  this.db.set(this._getBatchKey(baseId, batchIndex), undefined);
  batchIndex++;
}

Using undefined as a sentinel is implementation‑dependent and makes it harder to reason about termination semantics. Prefer either a dedicated delete/clear API if available, or an explicit “empty” value (e.g. an empty string) that _getSheetValues can interpret as “no data”.

For example:

-      while (this.db.get(this._getBatchKey(baseId, batchIndex))) {
-        this.db.set(this._getBatchKey(baseId, batchIndex), undefined);
+      while (this.db.get(this._getBatchKey(baseId, batchIndex))) {
+        this.db.set(this._getBatchKey(baseId, batchIndex), "");
         batchIndex++;
       }

and adjust _getSheetValues to treat "" as empty if necessary. Please confirm the expected semantics of $.service.db.set(key, undefined) in this codebase.

#!/bin/bash
# Inspect how $.service.db is typically cleared in this repo
rg -n '\.db\.set\([^,]+,\s*undefined\)' -S
rg -n '\.db\.(delete|remove|clear)' -S
components/google_sheets/sources/new-updates-polling/new-updates-polling.mjs (3)

8-13: Clarify that this is a polling-based source in the metadata.

Since this is an alternative to the existing “New Updates (Instant)” webhook trigger, naming it simply "New Updates" and reusing the same description can be confusing in the UI.

Consider making polling explicit, for example:

-  name: "New Updates",
-  description: "Emit new event each time a row or cell is updated in a spreadsheet.",
+  name: "New Updates (Polling)",
+  description: "Emit new event each time a row or cell is updated in a spreadsheet using polling.",

115-138: Align baseId construction and monitoringRange behavior across snapshot and diff paths.

In takeSheetSnapshot you build:

const sheetId = this.getSheetId();
const baseId = `${sheetId}${worksheetId}`;

while in getContentDiff you use:

const baseId = `${spreadsheet.spreadsheetId}${worksheet.properties.sheetId}`;

These should be identical, but that currently relies on this.getSheetId() and spreadsheet.spreadsheetId always matching. To avoid subtle desyncs, standardize baseId construction everywhere, for example:

-      const sheetId = this.getSheetId();
-      const baseId = `${spreadsheet.spreadsheetId}${worksheet.properties.sheetId}`;
+      const sheetId = this.getSheetId();
+      const baseId = `${sheetId}${worksheet.properties.sheetId}`;

and mirror that in takeSheetSnapshot.

Also, when monitoringRange is set, getContentDiff iterates over every worksheet but always uses the same range:

const range = this.monitoringRange
  ? this.monitoringRange
  : worksheet.properties.title;

and takeSheetSnapshot picks spreadsheet.sheets[0] as the worksheet for the baseline. With multiple worksheets, this can:

  • Associate a baseline from the first sheet with diffs computed against another sheet, or
  • Re-fetch and diff the same range for every worksheet, emitting duplicate “changes”.

For monitoringRange‑based usage, consider either:

  • Restricting processing to the single worksheet that corresponds to the range (e.g., parse the sheet name from SheetName!A1:Z1000), or
  • Documenting and enforcing that monitoringRange is only supported when a single worksheet is selected.
#!/bin/bash
# Show all call sites of getContentDiff and takeSheetSnapshot for this source
rg -n "google_sheets-new-updates-polling" -S
rg -n "takeSheetSnapshot" components/google_sheets/sources -n -S

Also applies to: 140-153


165-167: Use getSheetId() in run() for consistency.

Elsewhere you already rely on getSheetId() (from the common/base mixins) to resolve the spreadsheet ID, but run() calls:

const spreadsheet = await this.googleSheets.getSpreadsheet(this.sheetID);

For consistency and future‑proofing, consider:

  async run() {
-    const spreadsheet = await this.googleSheets.getSpreadsheet(this.sheetID);
+    const spreadsheetId = this.getSheetId();
+    const spreadsheet = await this.googleSheets.getSpreadsheet(spreadsheetId);
     return this.processSpreadsheet(spreadsheet);
  },
Confirm that `getSheetId()` in the shared Google Sheets http-based base/common always reflects the same ID expected by `googleSheets.getSpreadsheet(...)`.
components/google_sheets/sources/new-comment-polling/new-comment-polling.mjs (1)

1-40: Wire in sampleEmit and drop unused ...common.props.

There’s already a test-event.mjs alongside this file, but it isn’t used, and common/new-comment.mjs doesn’t currently define any props. For better UI preview and cleaner metadata:

  1. Import and expose a sample event for the UI:
-import { DEFAULT_POLLING_SOURCE_TIMER_INTERVAL } from "@pipedream/platform";
+import { DEFAULT_POLLING_SOURCE_TIMER_INTERVAL } from "@pipedream/platform";
+import sampleEmit from "./test-event.mjs";
@@
 export default {
   ...common,
@@
   props: {
@@
-    sheetID: {
+    sheetID: {
       propDefinition: [
         googleSheets,
         "sheetID",
         (c) => ({
           driveId: googleSheets.methods.getDriveId(c.watchedDrive),
         }),
       ],
     },
-    ...common.props,
   },
   methods: {
     ...base.methods,
     ...common.methods,
   },
+  sampleEmit,
  1. Since common only exports methods today, spreading ...common.props is a no‑op and can be removed as above.
#!/bin/bash
# Verify that common/new-comment.mjs exports only methods (no props) and that other sources use sampleEmit similarly
rg -n "new-comment-polling" components/google_sheets/sources -n -S
rg -n "sampleEmit" components/google_sheets/sources -n -S
📜 Review details

Configuration used: CodeRabbit UI

Review profile: ASSERTIVE

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 93e1cce and 251e796.

📒 Files selected for processing (8)
  • components/google_sheets/package.json (1 hunks)
  • components/google_sheets/sources/common/new-comment.mjs (1 hunks)
  • components/google_sheets/sources/common/new-updates.mjs (7 hunks)
  • components/google_sheets/sources/new-comment-polling/new-comment-polling.mjs (1 hunks)
  • components/google_sheets/sources/new-comment-polling/test-event.mjs (1 hunks)
  • components/google_sheets/sources/new-updates-polling/new-updates-polling.mjs (1 hunks)
  • components/google_sheets/sources/new-updates-polling/test-event.mjs (1 hunks)
  • components/google_sheets/sources/new-updates/new-updates.mjs (1 hunks)
🧰 Additional context used
🧠 Learnings (2)
📚 Learning: 2024-10-10T19:18:27.998Z
Learnt from: GTFalcao
Repo: PipedreamHQ/pipedream PR: 14265
File: components/the_magic_drip/sources/common.mjs:35-43
Timestamp: 2024-10-10T19:18:27.998Z
Learning: In `components/the_magic_drip/sources/common.mjs`, when processing items in `getAndProcessData`, `savedIds` is intentionally updated with IDs of both emitted and non-emitted items to avoid emitting retroactive events upon first deployment and ensure only new events are emitted as they occur.

Applied to files:

  • components/google_sheets/sources/new-comment-polling/new-comment-polling.mjs
📚 Learning: 2025-01-23T03:55:15.166Z
Learnt from: GTFalcao
Repo: PipedreamHQ/pipedream PR: 15376
File: components/monday/sources/name-updated/name-updated.mjs:6-6
Timestamp: 2025-01-23T03:55:15.166Z
Learning: Source names in Monday.com components don't need to start with "New" if they emit events for updated items (e.g., "Name Updated", "Column Value Updated") rather than new items. This follows the component guidelines exception where the "New" prefix is only required when emits are limited to new items.

Applied to files:

  • components/google_sheets/sources/new-updates/new-updates.mjs
  • components/google_sheets/sources/new-updates-polling/new-updates-polling.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: pnpm publish
  • GitHub Check: Lint Code Base
  • GitHub Check: Publish TypeScript components
  • GitHub Check: Verify TypeScript components
🔇 Additional comments (4)
components/google_sheets/package.json (1)

3-3: Version bump looks appropriate.

The 0.13.0 bump aligns with the addition of new polling sources and batching behavior; no issues here.

components/google_sheets/sources/new-updates/new-updates.mjs (1)

10-13: Source version bump is consistent with underlying common changes.

Updating to 0.3.4 for the instant source matches the new batching logic introduced in the shared common/new-updates.mjs without altering the public surface.

components/google_sheets/sources/new-updates-polling/test-event.mjs (1)

1-70: Test fixture shape matches expected New Updates payload.

The worksheet, currentValues, and changes fields align with the structure produced by processSpreadsheet / getContentChanges (e.g., cell format B:4), so this looks good for UI preview and tests.

components/google_sheets/sources/new-comment-polling/test-event.mjs (1)

1-21: Comment test fixture is coherent and self-contained.

The payload mirrors a realistic drive#comment object with the fields used by generateMeta (e.g., id, content, createdTime), so it’s suitable as a sample event.

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.

[ACTION] Google Sheets - Provide polling options as an alternative to current webhook based ones

4 participants