Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Google Ads - Create Report improvement #12519

Merged
merged 20 commits into from
Jul 3, 2024

Conversation

GTFalcao
Copy link
Collaborator

@GTFalcao GTFalcao commented Jun 21, 2024

  • Added the option to search for and select specific objects to generate a report for, instead of always querying all objects,
  • Added option to filter by date range (predefined and custom).

Summary by CodeRabbit

  • New Features

    • Added object filtering and date range selection in report generation for Google Ads.
    • Enhanced resource listing with dynamic SQL query generation.
  • Bug Fixes

    • Adjusted data structures by removing outdated segments (e.g., day_of_week, month) from various modules.
  • Improvements

    • Streamlined data processing logic by removing redundant date-related segments.
    • Updated event emission for new Google Ads campaigns with a new version.

Copy link

vercel bot commented Jun 21, 2024

The latest updates on your projects. Learn more about Vercel for Git ↗︎

3 Skipped Deployments
Name Status Preview Comments Updated (UTC)
docs-v2 ⬜️ Ignored (Inspect) Visit Preview Jul 3, 2024 3:59am
pipedream-docs ⬜️ Ignored (Inspect) Jul 3, 2024 3:59am
pipedream-docs-redirect-do-not-edit ⬜️ Ignored (Inspect) Jul 3, 2024 3:59am

Copy link
Contributor

coderabbitai bot commented Jun 21, 2024

Walkthrough

The updates introduce an objectFilter and dateRange to the create-report action, which enhances filtering capabilities. Several segments arrays across multiple resource files were refined by removing selected fields, and a getOption utility function was added for consistent data mapping. Additionally, SQL query generator functions were improved, and a version upgrade was performed for handling new campaign creation events.

Changes

Files / Components Change Summary
create-report.mjs Updated version, added objectFilter and dateRange properties, modified buildQuery method.
queries.mjs Added listResources(resource, query) function for dynamic SQL query generation.
common/resources/ad.mjs Removed several date-related fields from the segments array.
common/resources/adGroup.mjs, ...campaign.mjs, ...customer.mjs Removed certain date-related segments and introduced the getOption function for mapping fields.
utils.mjs Introduced a new getOption(label, prefix) function for consistent data representation.
new-campaign-created.mjs Updated version to handle new campaign creation events more effectively.

Sequence Diagram(s)

sequenceDiagram
    participant User
    participant CreateReportAction as GoogleAdsCreateReport
    participant Queries as GoogleAdsQueries
    participant Utils as GoogleAdsUtils
    participant Database as GoogleAdsDatabase

    User->>CreateReportAction: Create Report
    CreateReportAction->>Queries: listResources(objectFilter, dateRange)
    Queries-->>CreateReportAction: SQL Query
    CreateReportAction->>Database: Execute SQL Query
    Database-->>CreateReportAction: Query Results
    CreateReportAction->>Utils: getOption(mapping data)
    Utils-->>CreateReportAction: Mapped Data
    CreateReportAction-->>User: Report Generated
Loading

Poem

On digital fields where ads do prance,
Reports now bloom with filters' dance.
Dates refined, and metrics true,
Campaigns rise fresh as morning dew.
Code enhanced, queries succinct,
Our work as rabbits, always distinct! 🐇✨

Tip

AI model upgrade

gpt-4o model for reviews and chat is now live

OpenAI claims that this model is better at understanding and generating code than the previous models. Please join our Discord Community to provide any feedback or to report any issues.


Thank you for using CodeRabbit. We offer it for free to the OSS community and would appreciate your support in helping us grow. If you find it useful, would you consider giving us a shout-out on your favorite social media?

Share
Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>.
    • Generate unit testing code for this file.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai generate unit testing code for this file.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai generate interesting stats about this repository and render them as a table.
    • @coderabbitai show all the console.log statements in this repository.
    • @coderabbitai read src/utils.ts and generate unit testing code.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (invoked as PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Additionally, you can add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.

CodeRabbit Configration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

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

Outside diff range and nitpick comments (1)
components/google_ads/actions/create-report/create-report.mjs (1)

Line range hint 143-167: Refactor suggestion for buildQuery method.

The method handles multiple aspects of SQL query construction. Consider refactoring to improve readability and maintainability. Breaking down the method into smaller functions for each part of the query (fields, segments, metrics, filters) could help manage complexity.

+ function constructSelectClause(fields, segments, metrics, resource) {
+   const selection = [...fields, ...segments, ...metrics];
+   return `SELECT ${selection.join(", ")} FROM ${resource}`;
+ }
+
+ function constructWhereClause(objectFilter, resource) {
+   return objectFilter ? ` WHERE ${resource}.id IN (${objectFilter.join(", ")})` : "";
+ }
+
+ function constructOrderByClause(orderBy, direction, resource) {
+   return orderBy ? ` ORDER BY ${resource}.${orderBy} ${direction}` : "";
+ }
+
- const selection = [...fields, ...segments, ...metrics];
- let query = `SELECT ${selection.join(", ")} FROM ${resource}`;
- if (orderBy && direction) {
-   query += ` ORDER BY ${`${resource}.${orderBy}`} ${direction}`;
- }
- if (limit) {
-   query += ` LIMIT ${limit}`;
- }
- if (objectFilter) {
-   query += ` WHERE ${resource}.id IN (${objectFilter.join(", ")})`;
- }
+ let query = constructSelectClause(fields, segments, metrics, resource)
+   + constructWhereClause(objectFilter, resource)
+   + constructOrderByClause(orderBy, direction, resource);
+ if (limit) {
+   query += ` LIMIT ${limit}`;
+ }
Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

Commits

Files that changed from the base of the PR and between 7ba4698 and 29bc96f.

Files selected for processing (9)
  • components/google_ads/actions/add-contact-to-list-by-email/add-contact-to-list-by-email.mjs (1 hunks)
  • components/google_ads/actions/create-customer-list/create-customer-list.mjs (1 hunks)
  • components/google_ads/actions/create-report/create-report.mjs (4 hunks)
  • components/google_ads/actions/send-offline-conversion/send-offline-conversion.mjs (1 hunks)
  • components/google_ads/common/queries.mjs (1 hunks)
  • components/google_ads/google_ads.app.mjs (1 hunks)
  • components/google_ads/package.json (1 hunks)
  • components/google_ads/sources/new-campaign-created/new-campaign-created.mjs (1 hunks)
  • components/google_ads/sources/new-lead-form-entry/new-lead-form-entry.mjs (1 hunks)
Files skipped from review due to trivial changes (6)
  • components/google_ads/actions/add-contact-to-list-by-email/add-contact-to-list-by-email.mjs
  • components/google_ads/actions/create-customer-list/create-customer-list.mjs
  • components/google_ads/actions/send-offline-conversion/send-offline-conversion.mjs
  • components/google_ads/package.json
  • components/google_ads/sources/new-campaign-created/new-campaign-created.mjs
  • components/google_ads/sources/new-lead-form-entry/new-lead-form-entry.mjs
Additional comments not posted (2)
components/google_ads/actions/create-report/create-report.mjs (1)

46-69: Well-implemented dynamic filtering for report generation.

The objectFilter property is well-implemented, allowing dynamic fetching of filter options based on user input. It enhances the flexibility of the report generation feature by enabling users to specify which objects to include in the report.

components/google_ads/google_ads.app.mjs (1)

190-196: Consistent implementation of resource listing.

The listResources method is implemented consistently with other similar methods in this file. It effectively uses the search method to execute the query generated by QUERIES.listResources.

Comment on lines 97 to 102
function listResources(resource) {
const name = resource === "customer"
? "descriptive_name"
: "name";
return `SELECT ${resource}.id, ${resource}.${name} FROM ${resource}`;
}
Copy link
Contributor

Choose a reason for hiding this comment

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

Simplify the conditional logic in listResources.

The function uses a ternary operator to determine the field name based on the resource type. Consider using a dictionary to map resource types to their respective field names for improved readability and maintainability.

-  const name = resource === "customer"
-    ? "descriptive_name"
-    : "name";
+  const fieldNames = {
+    customer: "descriptive_name",
+    default: "name",
+  };
+  const name = fieldNames[resource] || fieldNames.default;
Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
function listResources(resource) {
const name = resource === "customer"
? "descriptive_name"
: "name";
return `SELECT ${resource}.id, ${resource}.${name} FROM ${resource}`;
}
function listResources(resource) {
const fieldNames = {
customer: "descriptive_name",
default: "name",
};
const name = fieldNames[resource] || fieldNames.default;
return `SELECT ${resource}.id, ${resource}.${name} FROM ${resource}`;
}

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

Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

Commits

Files that changed from the base of the PR and between 29bc96f and aa99707.

Files selected for processing (5)
  • components/google_ads/actions/create-report/common-constants.mjs (1 hunks)
  • components/google_ads/common/resources/ad.mjs (1 hunks)
  • components/google_ads/common/resources/adGroup.mjs (1 hunks)
  • components/google_ads/common/resources/campaign.mjs (2 hunks)
  • components/google_ads/common/resources/customer.mjs (2 hunks)
Additional comments not posted (5)
components/google_ads/actions/create-report/common-constants.mjs (1)

1-55: Excellent addition of predefined date range options.

The introduction of DATE_RANGE_OPTIONS provides a clear and structured way to handle date ranges in reports, which enhances usability and maintainability. This is a solid implementation following best practices for constant definitions.

components/google_ads/common/resources/adGroup.mjs (1)

Line range hint 1-57: Review of adGroup resource constants.

The constants defined for fields, segments, and metrics are comprehensive and cover a wide range of attributes relevant to ad groups. This will facilitate detailed data fetching and manipulation in ad group-related operations. It's good to see such a detailed and thought-out list, which should help in maintaining and scaling the ad group functionalities.

components/google_ads/common/resources/customer.mjs (1)

Line range hint 1-65: Review of customer resource constants.

The constants for fields, segments, and metrics related to the customer resource are well-defined and comprehensive. This setup ensures that all necessary customer data points can be accessed and utilized effectively, supporting robust customer management and analysis capabilities.

components/google_ads/common/resources/campaign.mjs (1)

Line range hint 1-68: Review of campaign resource constants.

The constants for fields, segments, and metrics related to the campaign resource are thoroughly defined, ensuring a comprehensive approach to campaign data management. This will significantly aid in the detailed and effective management of campaigns across various dimensions and metrics.
[APROVED]

components/google_ads/common/resources/ad.mjs (1)

Line range hint 169-180: Segments array updated to remove time-related fields.

The removal of specific time-related segments such as "date", "day_of_week", etc., is consistent with the PR's objectives to streamline data processing. However, it's crucial to ensure that these changes do not adversely impact other functionalities that might depend on these segments.

#!/bin/bash
# Description: Verify that the removal of time-related segments does not break existing functionalities.

# Test: Search for usage of removed segments. Expect: No occurrences that could lead to runtime errors.
rg --type mjs --glob '*.*mjs' 'date|day_of_week|month|month_of_year|quarter|week|year'

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

Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

Commits

Files that changed from the base of the PR and between aa99707 and 958c743.

Files selected for processing (1)
  • components/google_ads/actions/create-report/create-report.mjs (5 hunks)
Files skipped from review as they are similar to previous changes (1)
  • components/google_ads/actions/create-report/create-report.mjs

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

Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

Commits

Files that changed from the base of the PR and between 958c743 and f1ebcdb.

Files selected for processing (2)
  • components/google_ads/actions/create-report/create-report.mjs (5 hunks)
  • components/google_ads/common/queries.mjs (1 hunks)
Files skipped from review as they are similar to previous changes (2)
  • components/google_ads/actions/create-report/create-report.mjs
  • components/google_ads/common/queries.mjs

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

Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

Commits

Files that changed from the base of the PR and between f1ebcdb and 23bad2f.

Files selected for processing (1)
  • components/google_ads/actions/create-report/create-report.mjs (5 hunks)
Files skipped from review as they are similar to previous changes (1)
  • components/google_ads/actions/create-report/create-report.mjs

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

Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

Commits

Files that changed from the base of the PR and between 23bad2f and 2e5655b.

Files selected for processing (5)
  • components/google_ads/actions/create-report/create-report.mjs (5 hunks)
  • components/google_ads/common/resources/ad.mjs (1 hunks)
  • components/google_ads/common/resources/adGroup.mjs (1 hunks)
  • components/google_ads/common/resources/campaign.mjs (2 hunks)
  • components/google_ads/common/resources/customer.mjs (2 hunks)
Files skipped from review as they are similar to previous changes (5)
  • components/google_ads/actions/create-report/create-report.mjs
  • components/google_ads/common/resources/ad.mjs
  • components/google_ads/common/resources/adGroup.mjs
  • components/google_ads/common/resources/campaign.mjs
  • components/google_ads/common/resources/customer.mjs

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

Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

Commits

Files that changed from the base of the PR and between 2e5655b and dc1c76c.

Files selected for processing (3)
  • components/google_ads/actions/create-report/create-report.mjs (5 hunks)
  • components/google_ads/common/queries.mjs (1 hunks)
  • components/google_ads/google_ads.app.mjs (3 hunks)
Files skipped from review as they are similar to previous changes (2)
  • components/google_ads/actions/create-report/create-report.mjs
  • components/google_ads/google_ads.app.mjs
Additional comments not posted (1)
components/google_ads/common/queries.mjs (1)

97-110: Refactor to simplify conditional logic and address potential security risk.

The function listResources uses ternary operators to determine fields based on the resource type. Consider using a dictionary for cleaner and more maintainable code. Additionally, ensure the query parameter is sanitized to prevent SQL injection.

-  const name = resource === "customer"
-    ? "descriptive_name"
-    : "name";
-  const fieldResource = resource === "ad_group_ad"
-    ? "ad_group_ad.ad"
-    : resource;
+  const fieldNames = {
+    customer: "descriptive_name",
+    ad_group_ad: "ad_group_ad.ad",
+    default: "name",
+  };
+  const name = fieldNames[resource] || fieldNames.default;
+  const fieldResource = fieldNames[resource] || resource;

+  let result = `SELECT ${fieldResource}.id, ${fieldResource}.${name} FROM ${resource}`;
+  if (query) {
+    const safeQuery = sanitize(query); // Ensure `sanitize` properly escapes SQL characters
+    result += ` WHERE ${fieldResource}.${name} LIKE '%${safeQuery}%'`;
+  }

To verify the sanitization, please ensure that a sanitize function exists and is robust enough to handle SQL injection attempts.

@dylburger dylburger added the triaged For maintainers: This issue has been triaged by a Pipedream employee label Jun 26, 2024
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

Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

Commits

Files that changed from the base of the PR and between dc1c76c and 957fcf6.

Files selected for processing (1)
  • components/google_ads/actions/create-report/create-report.mjs (5 hunks)
Files skipped from review as they are similar to previous changes (1)
  • components/google_ads/actions/create-report/create-report.mjs

lcaresia
lcaresia previously approved these changes Jun 27, 2024
@vunguyenhung
Copy link
Collaborator

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

Please check the test report below for more information
https://vunguyenhung.notion.site/Google-Ads-Create-Report-improvement-12519-bc258c09eda7418586a9bca0778b22dd

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

Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

Commits

Files that changed from the base of the PR and between 957fcf6 and d18cdcd.

Files selected for processing (8)
  • components/google_ads/actions/create-report/create-report.mjs (5 hunks)
  • components/google_ads/common/queries.mjs (3 hunks)
  • components/google_ads/common/resources/ad.mjs (4 hunks)
  • components/google_ads/common/resources/adGroup.mjs (4 hunks)
  • components/google_ads/common/resources/campaign.mjs (5 hunks)
  • components/google_ads/common/resources/customer.mjs (5 hunks)
  • components/google_ads/common/utils.mjs (1 hunks)
  • components/google_ads/sources/new-campaign-created/new-campaign-created.mjs (2 hunks)
Files skipped from review as they are similar to previous changes (5)
  • components/google_ads/common/queries.mjs
  • components/google_ads/common/resources/ad.mjs
  • components/google_ads/common/resources/adGroup.mjs
  • components/google_ads/common/resources/customer.mjs
  • components/google_ads/sources/new-campaign-created/new-campaign-created.mjs
Additional comments not posted (12)
components/google_ads/common/utils.mjs (1)

34-39: LGTM!

The getOption function is simple and clear. It takes a label and a prefix, returning an object with the label and a value that concatenates the prefix and the label.

components/google_ads/actions/create-report/create-report.mjs (8)

7-7: LGTM!

The import statement for DATE_RANGE_OPTIONS is necessary for the new dateRange property.


21-21: LGTM!

The version update to "0.1.0" reflects the significant changes to the functionality.


47-76: LGTM!

The objectFilter property allows filtering objects for the report, enhancing the functionality.


77-96: LGTM!

The dateRange property allows selecting a date range for the report, enhancing the functionality.


99-103: LGTM!

The fields property allows selecting fields for the report, enhancing the functionality.


107-113: LGTM!

The segments property allows selecting segments for the report, enhancing the functionality.


118-122: LGTM!

The metrics property allows selecting metrics for the report, enhancing the functionality.


201-237: LGTM!

The buildQuery method has been updated to handle object filtering, date range selection, and query construction, enhancing the functionality.

components/google_ads/common/resources/campaign.mjs (3)

1-1: LGTM!

The import statement for getOption is necessary for the new functionality.


98-98: LGTM!

The fields array has been updated to use the getOption function, enhancing the data processing logic.


131-131: LGTM!

The segments array has been updated to use the getOption function, enhancing the data processing logic.

@vunguyenhung
Copy link
Collaborator

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

Please check the test report below for more information
https://vunguyenhung.notion.site/Google-Ads-Create-Report-improvement-12519-bc258c09eda7418586a9bca0778b22dd

@GTFalcao
Copy link
Collaborator Author

GTFalcao commented Jul 3, 2024

@vunguyenhung I cannot reproduce that error, but I believe it's related to the previous default value ("date") remaining in the optional prop after updating the component (the new default value is "segments.date"). If you reload the additionalProps and/or re-select that prop's value (or simply configure the action from scratch), that error won't occur. Better yet, I'll add a check to add the prefix in case the value entered does not have it.

Note: that default value is not present in the live version, so this wouldn't occur to users updating their components after releasing.

Btw, your setup gives me a business rule error where "metrics cannot be requested for a manager account", although this is a dynamic business rule on Google's end and not an error in the component (you'll have to either select a managed account, or not request metrics).

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

Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

Commits

Files that changed from the base of the PR and between d18cdcd and e7d2333.

Files selected for processing (2)
  • components/google_ads/actions/create-report/create-report.mjs (5 hunks)
  • components/google_ads/common/utils.mjs (1 hunks)
Files skipped from review as they are similar to previous changes (2)
  • components/google_ads/actions/create-report/create-report.mjs
  • components/google_ads/common/utils.mjs

@vunguyenhung
Copy link
Collaborator

Hi @GTFalcao, I think it's fine if it's business logic error. I faced the same issue, which I assume all other cases works

@vunguyenhung
Copy link
Collaborator

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

Test report
https://vunguyenhung.notion.site/Google-Ads-Create-Report-improvement-12519-bc258c09eda7418586a9bca0778b22dd

@GTFalcao
Copy link
Collaborator Author

GTFalcao commented Jul 3, 2024

/approve

@GTFalcao GTFalcao merged commit f2c374b into master Jul 3, 2024
11 checks passed
@GTFalcao GTFalcao deleted the google-ads-create-report-improvement branch July 3, 2024 19:22
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
triaged For maintainers: This issue has been triaged by a Pipedream employee
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants