Skip to content

DataForSEO new components #16717

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

Open
wants to merge 15 commits into
base: master
Choose a base branch
from
Open

DataForSEO new components #16717

wants to merge 15 commits into from

Conversation

GTFalcao
Copy link
Collaborator

@GTFalcao GTFalcao commented May 20, 2025

Closes #15507

12 actions among the requested components were implemented:

  • 9 backlinks components;
  • 2 business data components;
  • 1 page component

The rest were not clear on what endpoint was intended for the action - there are many, many available endpoints among the multiple APIs available in DataForSEO.

I'm opening this now with the above 12 new components, which is a significant amount on top of the 3 existing ones. If any more actions are needed they can be created moving forward as required.

Summary by CodeRabbit

  • New Features
    • Added multiple new actions for retrieving backlinks data, including history, summary, detailed lists, referring domains, domain pages summary, bulk backlinks, bulk ranks, bulk referring domains, and bulk spam scores via the DataForSEO API.
    • Introduced actions for parsing webpage content and searching or aggregating business listings.
  • Enhancements
    • Expanded configuration options for backlinks and business listings actions, including advanced filtering, ranking scale, tagging, and additional customizable parameters.
  • Bug Fixes
    • Improved descriptions and parameter handling for location coordinates and other properties.
  • Chores
    • Updated package version to 0.2.0.

Copy link

vercel bot commented May 20, 2025

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 May 20, 2025 1:44am
pipedream-docs ⬜️ Ignored (Inspect) May 20, 2025 1:44am
pipedream-docs-redirect-do-not-edit ⬜️ Ignored (Inspect) May 20, 2025 1:44am

Copy link
Contributor

coderabbitai bot commented May 20, 2025

Important

Review skipped

Review was skipped due to path filters

⛔ Files ignored due to path filters (1)
  • pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml

CodeRabbit blocks several paths by default. You can override this behavior by explicitly including those paths in the path filters. For example, including **/dist/** will override the default block on the dist directory, by removing the pattern from both the lists.

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Walkthrough

This update introduces multiple new action modules for the DataForSEO integration, primarily focused on backlinks, business data, and on-page content parsing. It also adds new property definitions, utility functions, and updates internal references for consistency. The package version is incremented to 0.2.0.

Changes

File(s) Change Summary
components/dataforseo/actions/get-backlinks-history/get-backlinks-history.mjs
components/dataforseo/actions/get-backlinks-summary/get-backlinks-summary.mjs
components/dataforseo/actions/get-backlinks/get-backlinks.mjs
components/dataforseo/actions/get-bulk-backlinks/get-bulk-backlinks.mjs
components/dataforseo/actions/get-bulk-ranks/get-bulk-ranks.mjs
components/dataforseo/actions/get-bulk-referring-domains/get-bulk-referring-domains.mjs
components/dataforseo/actions/get-bulk-spam-score/get-bulk-spam-score.mjs
components/dataforseo/actions/get-domain-pages-summary/get-domain-pages-summary.mjs
components/dataforseo/actions/get-referring-domains/get-referring-domains.mjs
components/dataforseo/actions/parse-page-content/parse-page-content.mjs
components/dataforseo/actions/search-business-listings/search-business-listings.mjs
components/dataforseo/actions/get-categories-aggregation/get-categories-aggregation.mjs
New action modules added for backlinks, business listings, on-page content, and utility endpoints, each defining their own methods, properties, and run logic.
components/dataforseo/actions/get-business-listings/get-business-listings.mjs
components/dataforseo/actions/get-keyword-difficulty/get-keyword-difficulty.mjs
components/dataforseo/actions/get-ranked-keywords/get-ranked-keywords.mjs
Internal import alias changed from app to dataforseo and version incremented; no logic changes.
components/dataforseo/common/utils.mjs Added optionalParseAsJSON and parseObjectEntries utility functions for JSON parsing.
components/dataforseo/dataforseo.app.mjs Expanded propDefinitions with new properties for backlinks and updated descriptions for clarity.
components/dataforseo/package.json Package version updated from 0.1.0 to 0.2.0.

Sequence Diagram(s)

sequenceDiagram
    participant User
    participant ActionModule
    participant DataForSEOAPI

    User->>ActionModule: Provide input parameters
    ActionModule->>ActionModule: Prepare request payload
    ActionModule->>DataForSEOAPI: POST to relevant endpoint (e.g., /backlinks/...)
    DataForSEOAPI-->>ActionModule: Return response data
    ActionModule->>User: Export summary and return data
Loading

Assessment against linked issues

Objective Addressed Explanation
Implement DataForSEO actions: Get Backlinks, Get Backlink Summary, Get Historical Backlink Summary, Get Bulk Backlink Rank, Get Bulk Backlink Stats, Get Backlinks Pages Summary, Get Bulk Referring Domain Stats, Get Referring Domains, Get Bulk Spam Scores (#15507)
Implement DataForSEO actions: Search Business Listings, Get Business Listings Categories Aggregation (#15507)
Implement DataForSEO actions: Parse Page Content (#15507)
Update app property definitions and utilities to support new actions (#15507)

Poem

A hop, a skip, a backlink found,
DataForSEO leaps abound!
With actions new and JSON neat,
Rabbits parse and never miss a beat.
From business search to spammy score,
This version brings so much more!
🐇✨


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
🪧 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>, please review it.
    • Explain this complex logic.
    • 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 explain this code block.
    • @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 gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and explain its main purpose.
    • @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.

Support

Need help? Create a ticket on our support page for assistance with any issues or questions.

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 using 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 generate docstrings to generate docstrings for this PR.
  • @coderabbitai generate sequence diagram to generate a sequence diagram of the changes in this 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.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration 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: 7

🧹 Nitpick comments (13)
components/dataforseo/actions/get-bulk-spam-score/get-bulk-spam-score.mjs (1)

1-48: New component looks good with a minor suggestion for the summary output

The implementation follows the established pattern for DataForSEO actions and correctly interacts with the bulk spam score endpoint.

Consider enhancing the success message to include more details about what was retrieved:

-    $.export("$summary", "Successfully retrieved bulk spam score");
+    $.export("$summary", `Successfully retrieved spam scores for ${this.targets.length} target(s)`);
components/dataforseo/actions/get-backlinks-history/get-backlinks-history.mjs (2)

21-25: Consider using a shared prop definition for the target parameter

The target property is defined inline, but it might be better to use a shared prop definition from the dataforseo app module if one exists (like backlinksTarget), to maintain consistency with other components.


66-66: Enhance the success summary message

Consider making the success message more informative by including details about the target domain and date range.

-    $.export("$summary", "Successfully retrieved backlinks history");
+    $.export("$summary", `Successfully retrieved backlinks history for ${this.target}${this.dateFrom ? ` from ${this.dateFrom}` : ""}${this.dateTo ? ` to ${this.dateTo}` : ""}`);
components/dataforseo/actions/get-bulk-referring-domains/get-bulk-referring-domains.mjs (1)

1-48: New component looks good with a minor suggestion for the summary output

The implementation follows the established pattern for DataForSEO actions and correctly interacts with the bulk referring domains endpoint.

Consider enhancing the success message to include more details about what was retrieved:

-    $.export("$summary", "Successfully retrieved bulk referring domains");
+    $.export("$summary", `Successfully retrieved referring domains data for ${this.targets.length} target(s)`);
components/dataforseo/actions/parse-page-content/parse-page-content.mjs (2)

34-46: Store Raw HTML description has incorrect markdown formatting

The markdown link in the storeRawHtml description is improperly formatted.

Apply this diff to fix the markdown link:

-      description: "Set to `true` if you want to get the HTML of the page using the [https://docs.dataforseo.com/v3/on_page/raw_html/](OnPage Raw HTML endpoint)",
+      description: "Set to `true` if you want to get the HTML of the page using the [OnPage Raw HTML endpoint](https://docs.dataforseo.com/v3/on_page/raw_html/)",

21-27: Consider adding URL validation

The URL property should be validated to ensure it's properly formatted.

Consider adding basic URL validation, for example:

  url: {
    type: "string",
    label: "URL",
    description:
      "The URL of the page to parse, e.g. `https://pipedream.com/`",
+   validate: (value) => {
+     try {
+       new URL(value);
+       return true;
+     } catch (err) {
+       return "Please enter a valid URL";
+     }
+   },
  },
components/dataforseo/actions/search-business-listings/search-business-listings.mjs (2)

53-60: Documentation link should be more specific

The documentation link in the additionalOptions description points to the general API endpoint. To help users find the exact parameters, it would be better to point to the specific "Request parameters" section.

     additionalOptions: {
       propDefinition: [
         dataforseo,
         "additionalOptions",
       ],
       description:
-        "Additional parameters to send in the request. [See the documentation](https://docs.dataforseo.com/v3/business_data/business_listings/search/live/) for all available parameters. Values will be parsed as JSON where applicable.",
+        "Additional parameters to send in the request. [See the documentation](https://docs.dataforseo.com/v3/business_data/business_listings/search/live/#request-parameters) for all available parameters. Values will be parsed as JSON where applicable.",
     },

8-9: Add explicit mention of the API used

To improve clarity of this component's purpose, consider adding explicit mention of Google Maps in the description.

   description:
-    "Get information about business entities listed on Google Maps. [See the documentation](https://docs.dataforseo.com/v3/business_data/business_listings/search/live/)",
+    "Get information about business entities listed on Google Maps using DataForSEO's Business Data API. [See the documentation](https://docs.dataforseo.com/v3/business_data/business_listings/search/live/)",
components/dataforseo/actions/get-domain-pages-summary/get-domain-pages-summary.mjs (2)

78-94: Consider adding pagination handling

The Domain Pages Summary endpoint likely returns paginated results for domains with many pages. Consider adding support for pagination parameters in the request or handling pagination in the response for large domains.

You could enhance the method to automatically handle pagination by checking for result_count and total_count in the response and making additional requests if needed:

async getDomainPagesSummaryWithPagination(args = {}, allResults = []) {
  const response = await this.getDomainPagesSummary(args);
  
  // Add results to our collection
  if (response?.tasks?.[0]?.result?.[0]?.items) {
    allResults.push(...response.tasks[0].result[0].items);
  }
  
  // Check if we need to paginate
  const resultCount = response?.tasks?.[0]?.result?.[0]?.items?.length || 0;
  const totalCount = response?.tasks?.[0]?.result?.[0]?.total_count || 0;
  
  if (allResults.length < totalCount && resultCount > 0) {
    // Prepare for next page
    const nextOffset = (args.data[0].offset || 0) + resultCount;
    args.data[0].offset = nextOffset;
    
    // Recursive call for next page
    return this.getDomainPagesSummaryWithPagination(args, allResults);
  }
  
  // Return all results and the original response structure
  const fullResponse = { ...response };
  if (fullResponse?.tasks?.[0]?.result?.[0]) {
    fullResponse.tasks[0].result[0].items = allResults;
  }
  
  return fullResponse;
}

70-76: Make documentation link more specific

To improve user experience, update the documentation link to point directly to the request parameters section rather than the general endpoint documentation.

     additionalOptions: {
       propDefinition: [
         dataforseo,
         "additionalOptions",
       ],
-      description: "Additional parameters to send in the request. [See the documentation](https://docs.dataforseo.com/v3/backlinks/domain_pages_summary/live/) for all available parameters. Values will be parsed as JSON where applicable.",
+      description: "Additional parameters to send in the request. [See the documentation](https://docs.dataforseo.com/v3/backlinks/domain_pages_summary/live/#request-parameters) for all available parameters. Values will be parsed as JSON where applicable.",
     },
components/dataforseo/actions/get-backlinks-summary/get-backlinks-summary.mjs (1)

70-76: Update documentation link to be more specific

The additionalOptions description should point directly to the request parameters section rather than the general endpoint documentation.

     additionalOptions: {
       propDefinition: [
         dataforseo,
         "additionalOptions",
       ],
-      description: "Additional parameters to send in the request. [See the documentation](https://docs.dataforseo.com/v3/backlinks/summary/live/) for all available parameters. Values will be parsed as JSON where applicable.",
+      description: "Additional parameters to send in the request. [See the documentation](https://docs.dataforseo.com/v3/backlinks/summary/live/#request-parameters) for all available parameters. Values will be parsed as JSON where applicable.",
     },
components/dataforseo/actions/get-referring-domains/get-referring-domains.mjs (1)

70-76: Update documentation link for better specificity

The documentation link in additionalOptions should point directly to the request parameters section instead of the general endpoint page.

     additionalOptions: {
       propDefinition: [
         dataforseo,
         "additionalOptions",
       ],
-      description: "Additional parameters to send in the request. [See the documentation](https://docs.dataforseo.com/v3/backlinks/referring_domains/live/) for all available parameters. Values will be parsed as JSON where applicable.",
+      description: "Additional parameters to send in the request. [See the documentation](https://docs.dataforseo.com/v3/backlinks/referring_domains/live/#request-parameters) for all available parameters. Values will be parsed as JSON where applicable.",
     },
components/dataforseo/actions/get-backlinks/get-backlinks.mjs (1)

79-96: Add error handling to improve resilience.

The run method doesn't have any error handling mechanisms. Consider adding try/catch blocks to handle potential API errors gracefully and provide meaningful error messages to the user.

  async run({ $ }) {
+   try {
      const response = await this.getBacklinks({
        $,
        data: [
          {
            target: this.target,
            mode: this.mode,
            filters: this.filters,
            order_by: this.order_by,
            rank_scale: this.rankScale,
            tag: this.tag,
            ...parseObjectEntries(this.additionalOptions),
          },
        ],
      });
      $.export("$summary", "Successfully retrieved backlinks data");
      return response;
+   } catch (error) {
+     $.export("$summary", `Error retrieving backlinks: ${error.message}`);
+     throw error;
+   }
  },
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
Cache: Disabled due to data retention organization setting
Knowledge Base: Disabled due to data retention organization setting

📥 Commits

Reviewing files that changed from the base of the PR and between a024e77 and 2d575bc.

⛔ Files ignored due to path filters (1)
  • pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml
📒 Files selected for processing (18)
  • components/dataforseo/actions/get-backlinks-history/get-backlinks-history.mjs (1 hunks)
  • components/dataforseo/actions/get-backlinks-summary/get-backlinks-summary.mjs (1 hunks)
  • components/dataforseo/actions/get-backlinks/get-backlinks.mjs (1 hunks)
  • components/dataforseo/actions/get-bulk-backlinks/get-bulk-backlinks.mjs (1 hunks)
  • components/dataforseo/actions/get-bulk-ranks/get-bulk-ranks.mjs (1 hunks)
  • components/dataforseo/actions/get-bulk-referring-domains/get-bulk-referring-domains.mjs (1 hunks)
  • components/dataforseo/actions/get-bulk-spam-score/get-bulk-spam-score.mjs (1 hunks)
  • components/dataforseo/actions/get-business-listings/get-business-listings.mjs (1 hunks)
  • components/dataforseo/actions/get-categories-aggregation/get-categories-aggregation.mjs (1 hunks)
  • components/dataforseo/actions/get-domain-pages-summary/get-domain-pages-summary.mjs (1 hunks)
  • components/dataforseo/actions/get-keyword-difficulty/get-keyword-difficulty.mjs (1 hunks)
  • components/dataforseo/actions/get-ranked-keywords/get-ranked-keywords.mjs (1 hunks)
  • components/dataforseo/actions/get-referring-domains/get-referring-domains.mjs (1 hunks)
  • components/dataforseo/actions/parse-page-content/parse-page-content.mjs (1 hunks)
  • components/dataforseo/actions/search-business-listings/search-business-listings.mjs (1 hunks)
  • components/dataforseo/common/utils.mjs (1 hunks)
  • components/dataforseo/dataforseo.app.mjs (3 hunks)
  • components/dataforseo/package.json (1 hunks)
🔇 Additional comments (24)
components/dataforseo/common/utils.mjs (2)

1-7: Well-implemented error handling in JSON parsing utility

This utility function provides a robust way to attempt JSON parsing without throwing exceptions, which is excellent for handling potentially malformed JSON input. It follows the principle of graceful degradation by falling back to the original value when parsing fails.


9-22: Good approach for handling nested JSON structures

The parseObjectEntries function elegantly handles the case where an object might contain JSON strings as values. The implementation correctly:

  1. Accepts an input with a sensible default
  2. Parses string inputs as JSON
  3. Recursively applies JSON parsing to each value
  4. Preserves the original structure

This utility will be valuable for processing the additionalOptions props in the new DataForSEO action modules.

components/dataforseo/package.json (1)

3-3: Appropriate version bump for feature additions

The version increment from 0.1.0 to 0.2.0 follows semantic versioning principles correctly, as this PR is adding substantial new functionality (12 new actions) without breaking existing functionality.

components/dataforseo/actions/get-business-listings/get-business-listings.mjs (3)

1-1: Consistent import naming convention applied

Changing the import alias from app to dataforseo improves code readability by making it immediately clear which app the module is associated with.


7-7: Version bump reflects refactoring changes

The patch version increment from 0.0.1 to 0.0.2 is appropriate for these non-functional refactoring changes.


10-50: Consistent renaming throughout the component

All references to the app module have been systematically updated from app to dataforseo, maintaining consistency throughout the file. This refactoring improves maintainability and readability without changing functionality.

components/dataforseo/actions/get-ranked-keywords/get-ranked-keywords.mjs (3)

1-1: Consistent import naming convention applied

Similar to the business listings component, the import alias has been standardized to dataforseo which improves code clarity and consistency across the codebase.


7-7: Version bump reflects refactoring changes

The patch version increment (0.0.1 to 0.0.2) properly indicates the non-functional nature of these changes.


10-31: Consistent renaming throughout the component

All references to the app module have been systematically updated for consistency, with no functional changes. This type of systematic refactoring improves maintainability.

components/dataforseo/actions/get-keyword-difficulty/get-keyword-difficulty.mjs (1)

1-1: LGTM - Clean refactoring of import alias and references

The change from app to dataforseo import alias across the component provides better clarity and consistency with other DataForSEO components. Version increment from 0.0.1 to 0.0.2 appropriately reflects these non-breaking changes.

Also applies to: 7-7, 10-10, 13-13, 19-19, 25-25, 31-31

components/dataforseo/actions/get-bulk-backlinks/get-bulk-backlinks.mjs (3)

10-18: LGTM! Method implementation is correct

The method correctly calls the DataForSEO API endpoint for bulk backlinks.


19-33: Props look good

The properties are properly defined with appropriate references to the dataforseo app prop definitions.


34-47: Run method is well-structured

The run method correctly assembles the request payload and handles the response.

components/dataforseo/actions/parse-page-content/parse-page-content.mjs (2)

10-18: LGTM! Method implementation is correct

The parsePageContent method is properly implemented to call the appropriate API endpoint.


55-70: LGTM! Run method is well-implemented

The run method correctly uses all defined properties and handles the API request and response properly.

components/dataforseo/actions/get-bulk-ranks/get-bulk-ranks.mjs (4)

3-9: Component metadata looks good

The component key, name, description, and version are appropriately defined.


10-18: Method implementation is correct

The getBacklinksBulkRanks method is properly defined to interact with the DataForSEO API endpoint for bulk ranks.


19-39: Props are well-defined

The properties are properly defined with appropriate references to the dataforseo app prop definitions.


40-54: Run method is well-structured

The run method correctly constructs the API request payload and handles the response.

components/dataforseo/actions/get-categories-aggregation/get-categories-aggregation.mjs (4)

3-10: Component metadata looks good

The component key, name, description, and version are appropriately defined.


11-19: Method implementation is correct

The getCategoriesAggregation method is properly implemented to interact with the DataForSEO business listings API.


20-61: Props are well-defined

The properties are correctly defined with appropriate references to the dataforseo app prop definitions. The additionalOptions description includes a helpful link to the documentation.


62-79: Run method implementation is solid

The run method correctly:

  1. Assembles the request payload with all the defined properties
  2. Properly transforms camelCase property names to snake_case for the API
  3. Uses the parseObjectEntries utility for additionalOptions
  4. Exports a summary and returns the response
components/dataforseo/dataforseo.app.mjs (1)

41-177: LGTM: Well-structured property definitions for backlinks operations.

The newly added property definitions are well-structured with appropriate types, labels, detailed descriptions, and options where needed. They provide a comprehensive foundation for the backlinks-related operations.

Comment on lines +26 to +39
dateFrom: {
type: "string",
label: "Starting Date",
description:
"Starting date of the time range, in `YYYY-MM-DD` format. Default and minimum value is `2019-01-01`",
optional: true,
},
dateTo: {
type: "string",
label: "End Date",
description:
"End date of the time range, in `YYYY-MM-DD` format. Default is today's date",
optional: true,
},
Copy link
Contributor

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Add validation for date format and range

The date parameters (dateFrom and dateTo) don't include validation for the YYYY-MM-DD format or checks that ensure the date range is valid (e.g., dateFrom ≤ dateTo and dateFrom ≥ 2019-01-01).

Consider adding validation in the run method:

  async run({ $ }) {
+    // Validate date format and range
+    const dateRegex = /^\d{4}-\d{2}-\d{2}$/;
+    
+    if (this.dateFrom && !dateRegex.test(this.dateFrom)) {
+      throw new Error("dateFrom must be in YYYY-MM-DD format");
+    }
+    
+    if (this.dateTo && !dateRegex.test(this.dateTo)) {
+      throw new Error("dateTo must be in YYYY-MM-DD format");
+    }
+    
+    if (this.dateFrom && this.dateTo && new Date(this.dateFrom) > new Date(this.dateTo)) {
+      throw new Error("dateFrom must be earlier than or equal to dateTo");
+    }
+    
+    const minDate = new Date("2019-01-01");
+    if (this.dateFrom && new Date(this.dateFrom) < minDate) {
+      throw new Error("dateFrom must not be earlier than 2019-01-01");
+    }

    const response = await this.getBacklinksHistory({
🤖 Prompt for AI Agents
In components/dataforseo/actions/get-backlinks-history/get-backlinks-history.mjs
around lines 26 to 39, the dateFrom and dateTo parameters lack validation for
the YYYY-MM-DD format and logical date range checks. Add validation in the run
method to verify that dateFrom and dateTo match the YYYY-MM-DD format, ensure
dateFrom is not earlier than 2019-01-01, and confirm that dateFrom is less than
or equal to dateTo if both are provided. Return or throw an error if these
validations fail to prevent invalid input.

Comment on lines +3 to +8
export default {
key: "dataforseo-get-bulk-ranks",
name: "Get Bulk Ranks",
description:
"Get the number of backlinks pointing to specified domains, subdomains, and pages. [See the documentation](https://docs.dataforseo.com/v3/backlinks/bulk_backlinks/live/)",
version: "0.0.1",
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue

Incorrect component key and name

There's a mismatch between the component's key/name and its functionality. The component is named "Get Bulk Ranks" (line 5) with key "dataforseo-get-bulk-ranks" (line 4), but it's actually retrieving bulk backlinks data from the /backlinks/bulk_backlinks/live endpoint (line 13) and the summary message mentions "backlinks" (line 44).

Apply this diff to fix the inconsistency:

-  key: "dataforseo-get-bulk-ranks",
-  name: "Get Bulk Ranks",
+  key: "dataforseo-get-bulk-backlinks",
+  name: "Get Bulk Backlinks",
📝 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
export default {
key: "dataforseo-get-bulk-ranks",
name: "Get Bulk Ranks",
description:
"Get the number of backlinks pointing to specified domains, subdomains, and pages. [See the documentation](https://docs.dataforseo.com/v3/backlinks/bulk_backlinks/live/)",
version: "0.0.1",
export default {
key: "dataforseo-get-bulk-backlinks",
name: "Get Bulk Backlinks",
description:
"Get the number of backlinks pointing to specified domains, subdomains, and pages. [See the documentation](https://docs.dataforseo.com/v3/backlinks/bulk_backlinks/live/)",
version: "0.0.1",
// …rest of the component
}
🤖 Prompt for AI Agents
In components/dataforseo/actions/get-bulk-backlinks/get-bulk-backlinks.mjs
around lines 3 to 8, the component key and name incorrectly refer to "bulk
ranks" instead of "bulk backlinks." Update the key to
"dataforseo-get-bulk-backlinks" and the name to "Get Bulk Backlinks" to
accurately reflect the component's functionality of retrieving bulk backlinks
data.

Comment on lines +62 to +75
async run({ $ }) {
const response = await this.getBacklinksHistory({
$,
data: [
{
categories: this.categories,
description: this.description,
title: this.title,
location_coordinate: this.locationCoordinate,
tag: this.tag,
...parseObjectEntries(this.additionalOptions),
},
],
});
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue

Critical Bug: Incorrect method call in run()

The run() method is calling this.getBacklinksHistory() but the method defined in this component is this.searchBusinessListings(). This is likely a copy-paste error from another component and will cause the action to fail when executed.

Apply this fix:

-    const response = await this.getBacklinksHistory({
+    const response = await this.searchBusinessListings({
       $,
       data: [
         {
           categories: this.categories,
           description: this.description,
           title: this.title,
           location_coordinate: this.locationCoordinate,
           tag: this.tag,
           ...parseObjectEntries(this.additionalOptions),
         },
       ],
     });
🤖 Prompt for AI Agents
In
components/dataforseo/actions/search-business-listings/search-business-listings.mjs
around lines 62 to 75, the run() method incorrectly calls
this.getBacklinksHistory(), which does not exist in this component. Replace this
call with this.searchBusinessListings() to correctly invoke the defined method
and ensure the action executes properly.

Comment on lines +78 to +94
async run({ $ }) {
const response = await this.getBacklinksSummary({
$,
data: [
{
target: this.target,
include_subdomains: this.includeSubdomains,
include_indirect_links: this.includeIndirectLinks,
exclude_internal_backlinks: this.excludeInternalBacklinks,
backlinks_status_type: this.backlinksStatusType,
backlinks_filters: this.backlinksFilters,
rank_scale: this.rankScale,
tag: this.tag,
...parseObjectEntries(this.additionalOptions),
},
],
});
Copy link
Contributor

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Add error handling for the API response

The current implementation doesn't handle potential API errors. Consider adding try/catch block and checking the response status.

   async run({ $ }) {
+    try {
       const response = await this.getBacklinksSummary({
         $,
         data: [
           {
             target: this.target,
             include_subdomains: this.includeSubdomains,
             include_indirect_links: this.includeIndirectLinks,
             exclude_internal_backlinks: this.excludeInternalBacklinks,
             backlinks_status_type: this.backlinksStatusType,
             backlinks_filters: this.backlinksFilters,
             rank_scale: this.rankScale,
             tag: this.tag,
             ...parseObjectEntries(this.additionalOptions),
           },
         ],
       });
+      
+      // Check if the response contains any errors
+      if (response?.tasks?.[0]?.status_code !== 20000) {
+        const errorMessage = response?.tasks?.[0]?.status_message || "Unknown error occurred";
+        throw new Error(`DataForSEO API error: ${errorMessage}`);
+      }
+      
       $.export(
         "$summary",
         "Successfully retrieved backlink summary",
       );
       return response;
+    } catch (error) {
+      $.export("$summary", `Error: ${error.message}`);
+      throw error;
+    }
   },
📝 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
async run({ $ }) {
const response = await this.getBacklinksSummary({
$,
data: [
{
target: this.target,
include_subdomains: this.includeSubdomains,
include_indirect_links: this.includeIndirectLinks,
exclude_internal_backlinks: this.excludeInternalBacklinks,
backlinks_status_type: this.backlinksStatusType,
backlinks_filters: this.backlinksFilters,
rank_scale: this.rankScale,
tag: this.tag,
...parseObjectEntries(this.additionalOptions),
},
],
});
async run({ $ }) {
try {
const response = await this.getBacklinksSummary({
$,
data: [
{
target: this.target,
include_subdomains: this.includeSubdomains,
include_indirect_links: this.includeIndirectLinks,
exclude_internal_backlinks: this.excludeInternalBacklinks,
backlinks_status_type: this.backlinksStatusType,
backlinks_filters: this.backlinksFilters,
rank_scale: this.rankScale,
tag: this.tag,
...parseObjectEntries(this.additionalOptions),
},
],
});
// Check if the response contains any errors
if (response?.tasks?.[0]?.status_code !== 20000) {
const errorMessage = response?.tasks?.[0]?.status_message || "Unknown error occurred";
throw new Error(`DataForSEO API error: ${errorMessage}`);
}
$.export(
"$summary",
"Successfully retrieved backlink summary",
);
return response;
} catch (error) {
$.export("$summary", `Error: ${error.message}`);
throw error;
}
},
🤖 Prompt for AI Agents
In components/dataforseo/actions/get-backlinks-summary/get-backlinks-summary.mjs
around lines 78 to 94, the run method lacks error handling for the API call.
Wrap the await call to getBacklinksSummary in a try/catch block to catch any
exceptions. Inside the try block, after receiving the response, check the
response status or success indicator and handle any error cases appropriately,
such as throwing an error or returning a meaningful message. In the catch block,
log or handle the error to prevent unhandled promise rejections.

Comment on lines +78 to +97
async run({ $ }) {
const response = await this.getReferringDomains({
$,
data: [
{
target: this.target,
include_subdomains: this.includeSubdomains,
include_indirect_links: this.includeIndirectLinks,
exclude_internal_backlinks: this.excludeInternalBacklinks,
backlinks_status_type: this.backlinksStatusType,
backlinks_filters: this.backlinksFilters,
rank_scale: this.rankScale,
tag: this.tag,
...parseObjectEntries(this.additionalOptions),
},
],
});
$.export("$summary", "Successfully retrieved referring domains");
return response;
},
Copy link
Contributor

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Add error handling and support for limit/offset parameters

The current implementation doesn't handle API errors. Additionally, the referring domains endpoint supports pagination via limit and offset parameters, which should be exposed or handled automatically.

   async run({ $ }) {
+    try {
       const response = await this.getReferringDomains({
         $,
         data: [
           {
             target: this.target,
             include_subdomains: this.includeSubdomains,
             include_indirect_links: this.includeIndirectLinks,
             exclude_internal_backlinks: this.excludeInternalBacklinks,
             backlinks_status_type: this.backlinksStatusType,
             backlinks_filters: this.backlinksFilters,
             rank_scale: this.rankScale,
             tag: this.tag,
             ...parseObjectEntries(this.additionalOptions),
           },
         ],
       });
+      
+      // Check if the response contains any errors
+      if (response?.tasks?.[0]?.status_code !== 20000) {
+        const errorMessage = response?.tasks?.[0]?.status_message || "Unknown error occurred";
+        throw new Error(`DataForSEO API error: ${errorMessage}`);
+      }
+      
       $.export("$summary", "Successfully retrieved referring domains");
       return response;
+    } catch (error) {
+      $.export("$summary", `Error: ${error.message}`);
+      throw error;
+    }
   },

You might also want to expose pagination parameters directly:

   props: {
     dataforseo,
     target: {
       propDefinition: [
         dataforseo,
         "backlinksTarget",
       ],
     },
+    limit: {
+      type: "integer",
+      label: "Limit",
+      description: "Number of results to return (max 1000)",
+      optional: true,
+      default: 100,
+    },
+    offset: {
+      type: "integer",
+      label: "Offset",
+      description: "Number of results to skip",
+      optional: true,
+      default: 0,
+    },
     backlinksStatusType: {
       propDefinition: [

Then update the run method to include these parameters:

       data: [
         {
           target: this.target,
+          limit: this.limit,
+          offset: this.offset,
           include_subdomains: this.includeSubdomains,
🤖 Prompt for AI Agents
In components/dataforseo/actions/get-referring-domains/get-referring-domains.mjs
around lines 78 to 97, the run method lacks error handling and does not support
pagination parameters limit and offset. To fix this, add try-catch around the
API call to handle and log errors gracefully. Also, include limit and offset as
parameters in the data object sent to getReferringDomains, either by exposing
them as class properties or method arguments, so pagination can be controlled.
Ensure these parameters are passed correctly in the request payload.

},
},
async run({ $ }) {
const response = await this.getBacklinkSummary({
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue

Critical method name mismatch error.

The run method calls this.getBacklinkSummary() but the defined method is getBacklinks(). This will cause a runtime error.

Apply this diff to fix the method name:

-    const response = await this.getBacklinkSummary({
+    const response = await this.getBacklinks({
📝 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
const response = await this.getBacklinkSummary({
const response = await this.getBacklinks({
🤖 Prompt for AI Agents
In components/dataforseo/actions/get-backlinks/get-backlinks.mjs at line 80, the
method call uses this.getBacklinkSummary(), but the correct method name defined
is getBacklinks(). Rename the method call from getBacklinkSummary to
getBacklinks to match the defined method and avoid runtime errors.

Comment on lines +170 to +171
description: "Additional parameters to send in the request. [See the documentation](https://developers.ringcentral.com/api-reference/External-Contacts/createContact) for all available parameters. Values will be parsed as JSON where applicable.",
optional: true,
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue

Fix incorrect documentation link.

The description for additionalOptions references RingCentral API documentation instead of DataForSEO documentation.

Apply this diff to fix the documentation link:

-      description: "Additional parameters to send in the request. [See the documentation](https://developers.ringcentral.com/api-reference/External-Contacts/createContact) for all available parameters. Values will be parsed as JSON where applicable.",
+      description: "Additional parameters to send in the request. [See the documentation](https://docs.dataforseo.com/v3/backlinks/backlinks/live/) for all available parameters. Values will be parsed as JSON where applicable.",
📝 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
description: "Additional parameters to send in the request. [See the documentation](https://developers.ringcentral.com/api-reference/External-Contacts/createContact) for all available parameters. Values will be parsed as JSON where applicable.",
optional: true,
description: "Additional parameters to send in the request. [See the documentation](https://docs.dataforseo.com/v3/backlinks/backlinks/live/) for all available parameters. Values will be parsed as JSON where applicable.",
optional: true,
🤖 Prompt for AI Agents
In components/dataforseo/dataforseo.app.mjs around lines 170 to 171, the
description for additionalOptions incorrectly links to the RingCentral API
documentation. Update the URL in the description to point to the correct
DataForSEO API documentation to ensure accurate reference for users.

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.

DataForSEO
1 participant