Skip to content

Conversation

@michelle0927
Copy link
Collaborator

@michelle0927 michelle0927 commented Apr 16, 2025

Resolves #16292

Summary by CodeRabbit

  • New Features

    • Added actions to create contacts, deals, and tasks in Cogmento CRM, supporting various input options and flexible assignment.
    • Introduced event sources to emit new events when contacts, deals, or tasks are created in Cogmento.
    • Implemented a reusable base component for efficient polling and event processing from Cogmento.
    • Enhanced Cogmento integration with full API interaction, dynamic property options, and pagination support.
  • Chores

    • Updated package version and added a new dependency for platform compatibility.

@vercel
Copy link

vercel bot commented Apr 16, 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 Apr 16, 2025 6:22pm
pipedream-docs ⬜️ Ignored (Inspect) Apr 16, 2025 6:22pm
pipedream-docs-redirect-do-not-edit ⬜️ Ignored (Inspect) Apr 16, 2025 6:22pm

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Apr 16, 2025

"""

Walkthrough

This update introduces a new integration for Cogmento CRM, adding both polling sources and actions. The sources emit events for new contacts, deals, and tasks by polling the Cogmento API, with a shared base module handling incremental event processing. The actions enable creating contacts, deals, and tasks via API calls, supporting various required and optional fields. The Cogmento app module is expanded to handle authentication, API requests, pagination, and dynamic property options. The package metadata is updated to include necessary dependencies.

Changes

File(s) Change Summary
components/cogmento/actions/create-contact/create-contact.mjs Added new action to create a contact in Cogmento CRM, supporting multiple input fields and preferences.
components/cogmento/actions/create-deal/create-deal.mjs Added new action to create a deal, supporting title, description, assignees, tags, close date, products, and amount.
components/cogmento/actions/create-task/create-task.mjs Added new action to create a task, supporting title, description, due date, assignees, deal, and contact linkage.
components/cogmento/cogmento.app.mjs Major expansion: implemented API request handling, authentication, pagination, and property option loaders for users, products, deals, and contacts. Added methods for listing and creating contacts, deals, and tasks.
components/cogmento/package.json Updated version and added dependency on @pipedream/platform.
components/cogmento/sources/common/base.mjs Introduced a reusable base source component for polling Cogmento API resources with timestamp-based incremental processing and event emission.
components/cogmento/sources/new-contact-created/new-contact-created.mjs New polling source: emits events when new contacts are created in Cogmento by extending the common base.
components/cogmento/sources/new-deal-created/new-deal-created.mjs New polling source: emits events when new deals are created in Cogmento by extending the common base.
components/cogmento/sources/new-task-created/new-task-created.mjs New polling source: emits events when new tasks are created in Cogmento by extending the common base.

Sequence Diagram(s)

sequenceDiagram
    participant User
    participant Action
    participant CogmentoApp
    participant CogmentoAPI

    User->>Action: Trigger create-contact/deal/task
    Action->>CogmentoApp: Call createContact/Deal/Task
    CogmentoApp->>CogmentoAPI: POST /contacts|deals|tasks
    CogmentoAPI-->>CogmentoApp: Response
    CogmentoApp-->>Action: Return result
    Action-->>User: Export summary/result
Loading
sequenceDiagram
    participant Source
    participant CogmentoApp
    participant CogmentoAPI
    participant EventStream

    Source->>CogmentoApp: listContacts/Deals/Tasks (with timestamp)
    CogmentoApp->>CogmentoAPI: GET /contacts|deals|tasks
    CogmentoAPI-->>CogmentoApp: Return items
    CogmentoApp-->>Source: Items list
    Source->>EventStream: Emit new events for items with new timestamps
Loading

Assessment against linked issues

Objective Addressed Explanation
Add polling sources: new-contact-created, new-deal-created, new-task-created (#16292)
Add actions: create-contact, create-deal, create-task (#16292)
Support required and optional fields as described for each action (#16292)
Implement core Cogmento app logic: API requests, pagination, dynamic options (#16292)

Suggested labels

ai-assisted

Poem

A Cogmento leap, with hops so bright,
New deals and contacts spring to light!
Tasks are born with gentle care,
Events pop up from everywhere.
With every API call and poll,
This rabbit’s code now takes control!
🐇✨
"""

Warning

There were issues while running some tools. Please review the errors and either fix the tool's configuration or disable the tool if it's a critical failure.

🔧 ESLint

If the error stems from missing dependencies, add them to the package.json file. For unrecoverable errors (e.g., due to private dependencies), disable the tool in the CodeRabbit configuration.

components/cogmento/sources/common/base.mjs

Oops! Something went wrong! :(

ESLint: 8.57.1

Error [ERR_MODULE_NOT_FOUND]: Cannot find package 'jsonc-eslint-parser' imported from /eslint.config.mjs
at packageResolve (node:internal/modules/esm/resolve:839:9)
at moduleResolve (node:internal/modules/esm/resolve:908:18)
at defaultResolve (node:internal/modules/esm/resolve:1038:11)
at ModuleLoader.defaultResolve (node:internal/modules/esm/loader:557:12)
at ModuleLoader.resolve (node:internal/modules/esm/loader:525:25)
at ModuleLoader.getModuleJob (node:internal/modules/esm/loader:246:38)
at ModuleJob._link (node:internal/modules/esm/module_job:126:49)


📜 Recent review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 8bc826a and 9c505ec.

📒 Files selected for processing (1)
  • components/cogmento/sources/common/base.mjs (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • components/cogmento/sources/common/base.mjs
⏰ Context from checks skipped due to timeout of 90000ms (3)
  • GitHub Check: pnpm publish
  • GitHub Check: Publish TypeScript components
  • GitHub Check: Verify TypeScript components

🪧 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.
    • 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 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 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 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 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: 1

🧹 Nitpick comments (10)
components/cogmento/actions/create-contact/create-contact.mjs (1)

64-94: Consider adding input validation and error handling.

While the implementation correctly builds the channels array and calls the API, it lacks validation for email format and phone numbers. Consider adding validation for these fields and specific error handling for common failure scenarios.

Also, there's no feedback if neither email nor phone is provided - consider adding a warning if both are missing, as contacts typically need at least one communication channel.

 async run({ $ }) {
   const channels = [];
+  
+  // Validate email format if provided
+  if (this.email && !/^\S+@\S+\.\S+$/.test(this.email)) {
+    throw new Error("Invalid email format");
+  }
+  
   if (this.email) {
     channels.push({
       channel_type: "Email",
       value: this.email,
     });
   }
   if (this.phone) {
     channels.push({
       channel_type: "Phone",
       value: this.phone,
     });
   }
+  
+  // Warn if no communication channels provided
+  if (channels.length === 0) {
+    $.export("warning", "Creating contact without any communication channels (email or phone)");
+  }

   const response = await this.cogmento.createContact({
     $,
     data: {
       first_name: this.firstName,
       last_name: this.lastName,
       channels,
       description: this.description,
       tags: this.tags,
       do_not_call: this.doNotCall,
       do_not_text: this.doNotText,
       do_not_email: this.doNotEmail,
     },
+    // Add specific error handling
+  }).catch((error) => {
+    if (error.response?.status === 409) {
+      throw new Error(`Contact creation failed: A contact with this information may already exist.`);
+    }
+    throw error;
   });
   $.export("$summary", `Successfully created contact: ${this.firstName} ${this.lastName}`);
   return response;
 },
components/cogmento/sources/new-deal-created/new-deal-created.mjs (1)

13-15: Consider handling advanced filtering or pagination.
Using this.cogmento.listDeals directly works for smaller data sets, but if the remote API returns many deals, you may need to incorporate pagination or filtering at the source level for efficiency.

components/cogmento/actions/create-deal/create-deal.mjs (1)

9-54: Enhance property validations for date and numeric fields.
Although it's common to keep them as plain strings in Pipedream, consider robust validation for closeDate (to ensure correct YYYY-MM-DD format) and amount (to prevent invalid or negative values). This can reduce user errors.

components/cogmento/actions/create-task/create-task.mjs (1)

9-49: Consider adding date format validations for dueDate.
The props are well-defined, but if users supply an incorrect date format, the API might reject the request or produce silent errors. Implementing a stricter validation or user guidance for the YYYY-MM-DD format may help.

components/cogmento/cogmento.app.mjs (3)

7-79: Allow listing all users for userIds if required.
Currently, userIds only returns the single current user. If multi-user assignment is desired, you might need to fetch the entire user list from Cogmento.


80-97: Consider adding timeouts or dedicated error handling in _makeRequest.
Relying on default Axios behavior is fine for many scenarios, but specifying request timeouts or refining error handling (for example, to parse known error codes) can improve API reliability.


149-177: Validate pagination edge cases in paginate method.
The loop relies on results and total from the API. If either is missing or zero, ensure there's no unexpected infinite loop. Also confirm that partial results are handled gracefully.

components/cogmento/sources/common/base.mjs (3)

41-66: Robust event processing implementation.

The event processing logic effectively handles pagination and timestamp tracking for incremental processing. The code properly emits new events and updates the last processed timestamp.

However, there's one improvement to consider: add a safeguard against empty responses or API errors.

  async processEvent(max) {
    const lastTs = this._getLastTs();
    let maxTs = lastTs;
    const resourceFn = this.getResourceFn();
    const args = this.getArgs();
    const tsField = this.getTsField();

+   try {
      const items = this.cogmento.paginate({
        fn: resourceFn,
        args,
        max,
      });

      for await (const item of items) {
        const ts = Date.parse(item[tsField]);
        if (ts >= lastTs) {
          const meta = this.generateMeta(item);
          this.$emit(item, meta);
          maxTs = Math.max(ts, maxTs);
        } else {
          break;
        }
      }

      this._setLastTs(maxTs);
+   } catch (error) {
+     console.error("Error processing Cogmento events:", error);
+     // Optionally emit an error event if needed
+   }
  },

79-81: Consider adding pagination limit to run method.

The run() method calls processEvent() without specifying a maximum number of events to process, unlike the deploy() hook which processes up to 25 events. For consistent behavior and to prevent excessive API calls, consider adding a reasonable limit.

async run() {
-  await this.processEvent();
+  await this.processEvent(100); // Process up to 100 events per run
},

25-30: Consider more flexible sorting configuration.

The getArgs() method hardcodes sorting by the timestamp field in descending order. For more flexibility, consider allowing subclasses to override or extend this behavior.

getArgs() {
+  const baseArgs = {
    params: {
      sort: `-${this.getTsField()}`,
    },
+  };
+  return this.extendArgs ? this.extendArgs(baseArgs) : baseArgs;
},
+ extendArgs(args) {
+   // Subclasses can override this method to extend the arguments
+   return args;
+ },
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between c37db1c and 8bc826a.

⛔ Files ignored due to path filters (1)
  • pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml
📒 Files selected for processing (9)
  • components/cogmento/actions/create-contact/create-contact.mjs (1 hunks)
  • components/cogmento/actions/create-deal/create-deal.mjs (1 hunks)
  • components/cogmento/actions/create-task/create-task.mjs (1 hunks)
  • components/cogmento/cogmento.app.mjs (1 hunks)
  • components/cogmento/package.json (2 hunks)
  • components/cogmento/sources/common/base.mjs (1 hunks)
  • components/cogmento/sources/new-contact-created/new-contact-created.mjs (1 hunks)
  • components/cogmento/sources/new-deal-created/new-deal-created.mjs (1 hunks)
  • components/cogmento/sources/new-task-created/new-task-created.mjs (1 hunks)
⏰ Context from checks skipped due to timeout of 90000ms (3)
  • GitHub Check: pnpm publish
  • GitHub Check: Verify TypeScript components
  • GitHub Check: Publish TypeScript components
🔇 Additional comments (15)
components/cogmento/package.json (2)

3-3: Version bump looks appropriate.

The version increment from 0.0.1 to 0.1.0 follows semantic versioning, indicating new features without breaking changes. This aligns with the introduction of new Cogmento components.


14-17: Dependencies addition is appropriate.

Adding the @pipedream/platform dependency is necessary for Pipedream components to leverage common utilities and interfaces. The caret version constraint (^3.0.3) allows for compatible updates.

components/cogmento/sources/new-task-created/new-task-created.mjs (2)

3-10: Component configuration looks good.

The component metadata is well-defined with a descriptive name, appropriate key, documentation link, and version set to 0.0.1 for a new component. The "dedupe: unique" setting will ensure no duplicate task events are emitted.


11-19: Method implementations are clear and focused.

The component effectively extends the common base by overriding only the necessary methods:

  • getResourceFn() returns the appropriate API method for tasks
  • getSummary() provides a clear, user-friendly summary format

This approach promotes code reuse and consistency across Cogmento source components.

components/cogmento/sources/new-contact-created/new-contact-created.mjs (2)

3-10: Component configuration is well-structured.

The component metadata follows the same pattern as other Cogmento sources, with appropriate key, name, description with documentation link, version, and deduplication strategy.


11-19: Method implementations maintain consistency with other source components.

The component correctly extends the common base by implementing:

  • getResourceFn() to return the contact-specific API method
  • getSummary() to format contact creation events consistently

This implementation maintains the pattern established across Cogmento source components.

components/cogmento/actions/create-contact/create-contact.mjs (2)

3-9: Action metadata is well-defined.

The component has appropriate key, name, description with documentation link, version, and type settings. The version 0.0.1 is correct for a new component.


9-63: Props are comprehensive and well-documented.

The component defines a good set of props for contact creation with:

  • Required fields (first name, last name)
  • Optional fields (email, phone, description, tags)
  • Boolean preferences (do not call, text, email)

Each prop has clear labels and descriptions to guide users.

components/cogmento/sources/new-deal-created/new-deal-created.mjs (3)

1-2: Reusing common base source logic is consistent.
Extending the shared common module is a good approach for deduplicating code and ensuring consistent polling/event logic.


3-10: Source metadata appears sufficiently descriptive.
The structure (key, name, description, version, type, dedupe) is aligned with conventional Pipedream source definitions, aiding maintainability and clarity.


16-18: Verify the presence of title from the API.
If item.title is missing or undefined, the summary string might look awkward. You may want to add fallback logic or confirm that title is always present in the Cogmento API response.

components/cogmento/actions/create-deal/create-deal.mjs (1)

55-74: Confirm proper error handling for invalid amount inputs.
Casting this.amount to a number (+this.amount) could yield NaN when the input is invalid, causing unexpected behavior in createDeal. Ensure that the API or the code gracefully handles such invalid values.

components/cogmento/actions/create-task/create-task.mjs (1)

51-71: Handle partial associations for tasks.
Assigning users, linking deals, or linking contacts is optional. When these fields are absent or invalid, ensure the API response is handled—either letting errors bubble up or providing user feedback.

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

98-148: Double-check the CRUD methods for error cases.
If the Cogmento API returns 4xx or 5xx errors, ensure that the calling code knows how to handle them. Consider logging or re-throwing useful error messages for debugging.

components/cogmento/sources/common/base.mjs (1)

1-82: Well-structured base component with reusability in mind.

The base component is well-designed with:

  • Proper state management for tracking processed events
  • Abstract methods that enforce implementation in subclasses
  • Pagination handling for efficient API consumption
  • Timestamp-based sorting and filtering
  • Clear separation of concerns between base and child components

This structure will promote consistency across the Cogmento integration sources and reduce code duplication.

Copy link
Collaborator

@luancazarine luancazarine left a comment

Choose a reason for hiding this comment

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

Hi @michelle0927, LGTM! Ready for QA!

@michelle0927 michelle0927 merged commit 86169a3 into master Apr 17, 2025
11 checks passed
@michelle0927 michelle0927 deleted the issue-16292 branch April 17, 2025 14:37
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.

[Components] cogmento

3 participants