-
Notifications
You must be signed in to change notification settings - Fork 5.5k
Add Adversus Actions: Create/Update Lead, Add Note/Activity, Change Lead Status, Assign to Campaign #18912
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
base: master
Are you sure you want to change the base?
Add Adversus Actions: Create/Update Lead, Add Note/Activity, Change Lead Status, Assign to Campaign #18912
Conversation
|
The latest updates on your projects. Learn more about Vercel for GitHub. 1 Skipped Deployment
|
|
Thank you so much for submitting this! We've added it to our backlog to review, and our team has been notified. |
|
Thanks for submitting this PR! When we review PRs, we follow the Pipedream component guidelines. If you're not familiar, here's a quick checklist:
|
WalkthroughAdds API docs to README; introduces four Adversus action modules (create-or-update-lead, add-note-activity, change-lead-status, assign-to-campaign); refactors the Adversus app with propDefinitions, authentication helpers, a centralized request helper, and new API wrapper methods used by the actions. Changes
Sequence Diagram(s)sequenceDiagram
participant Action as Action Module
participant App as adversus.app
participant Auth as _auth()
participant HTTP as _makeRequest()
participant API as Adversus API
Note over Action,App: Action invokes high-level app methods
Action->>App: call (createLead / updateLead / addNoteToLead / addActivityToLead / changeLeadStatus / assignLeadToCampaign)
App->>Auth: _auth()
Auth-->>App: credentials
App->>HTTP: _makeRequest(path, method, data)
HTTP->>API: HTTP request (baseUrl + basic auth)
API-->>HTTP: response
HTTP-->>App: response data
App-->>Action: return result
Action->>Action: export $summary
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~25 minutes
Poem
Pre-merge checks and finishing touches❌ Failed checks (1 warning)
✅ Passed checks (2 passed)
✨ Finishing touches
🧪 Generate unit tests (beta)
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. Comment |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 2
🧹 Nitpick comments (1)
components/adversus/adversus.app.mjs (1)
6-22: Consider adding async options for dynamic ID selection.The propDefinitions currently require users to manually enter IDs. Consider enhancing the user experience by adding async options that fetch available leads, campaigns, and statuses from the API.
Example pattern for leadId:
leadId: { type: "string", label: "Lead ID", description: "The ID of the lead", async options({ page }) { const response = await this.listLeads({ page }); return response.map(lead => ({ label: `${lead.firstName} ${lead.lastName} (${lead.email})`, value: lead.id, })); }, },Note: This requires implementing a
listLeads()method and confirming the API supports listing resources.
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (7)
components/adversus/PR_STEPS.md(1 hunks)components/adversus/README.md(1 hunks)components/adversus/actions/add-note-activity/add-note-activity.mjs(1 hunks)components/adversus/actions/assign-to-campaign/assign-to-campaign.mjs(1 hunks)components/adversus/actions/change-lead-status/change-lead-status.mjs(1 hunks)components/adversus/actions/create-or-update-lead/create-or-update-lead.mjs(1 hunks)components/adversus/adversus.app.mjs(1 hunks)
🧰 Additional context used
🧠 Learnings (4)
📚 Learning: 2025-09-15T22:01:17.593Z
Learnt from: GTFalcao
PR: PipedreamHQ/pipedream#18362
File: components/leonardo_ai/README.md:45-49
Timestamp: 2025-09-15T22:01:17.593Z
Learning: In Leonardo AI components (and likely other Pipedream components), prefer using info alert props on the component itself rather than detailed "Key Features" sections in README files for action documentation.
Applied to files:
components/adversus/PR_STEPS.mdcomponents/adversus/README.md
📚 Learning: 2024-10-30T15:24:39.294Z
Learnt from: jcortes
PR: PipedreamHQ/pipedream#14467
File: components/gainsight_px/actions/create-account/create-account.mjs:4-6
Timestamp: 2024-10-30T15:24:39.294Z
Learning: In `components/gainsight_px/actions/create-account/create-account.mjs`, the action name should be "Create Account" instead of "Create Memory".
Applied to files:
components/adversus/actions/create-or-update-lead/create-or-update-lead.mjs
📚 Learning: 2025-06-04T17:52:05.780Z
Learnt from: GTFalcao
PR: PipedreamHQ/pipedream#16954
File: components/salesloft/salesloft.app.mjs:14-23
Timestamp: 2025-06-04T17:52:05.780Z
Learning: In the Salesloft API integration (components/salesloft/salesloft.app.mjs), the _makeRequest method returns response.data which directly contains arrays for list endpoints like listPeople, listCadences, listUsers, and listAccounts. The propDefinitions correctly call .map() directly on these responses without needing to destructure a nested data property.
Applied to files:
components/adversus/adversus.app.mjs
📚 Learning: 2025-09-15T22:01:11.472Z
Learnt from: GTFalcao
PR: PipedreamHQ/pipedream#18362
File: components/leonardo_ai/actions/generate-image/generate-image.mjs:103-105
Timestamp: 2025-09-15T22:01:11.472Z
Learning: In Pipedream components, pipedream/platform's axios implementation automatically excludes undefined values from HTTP requests, so there's no need to manually check for truthiness before including properties in request payloads.
Applied to files:
components/adversus/adversus.app.mjs
🧬 Code graph analysis (3)
components/adversus/actions/create-or-update-lead/create-or-update-lead.mjs (2)
components/adversus/actions/assign-to-campaign/assign-to-campaign.mjs (1)
response(36-40)components/adversus/actions/change-lead-status/change-lead-status.mjs (1)
response(36-40)
components/adversus/actions/assign-to-campaign/assign-to-campaign.mjs (2)
components/adversus/actions/change-lead-status/change-lead-status.mjs (1)
response(36-40)components/adversus/actions/create-or-update-lead/create-or-update-lead.mjs (1)
response(62-64)
components/adversus/actions/change-lead-status/change-lead-status.mjs (2)
components/adversus/actions/assign-to-campaign/assign-to-campaign.mjs (1)
response(36-40)components/adversus/actions/create-or-update-lead/create-or-update-lead.mjs (1)
response(62-64)
🔇 Additional comments (15)
components/adversus/README.md (2)
5-8: LGTM!The API documentation section provides a helpful reference link for users.
13-15: LGTM!The expanded use cases effectively demonstrate practical workflow scenarios and add value to the documentation.
components/adversus/actions/create-or-update-lead/create-or-update-lead.mjs (2)
62-71: LGTM!The conditional logic for update vs. create is clean and well-implemented. The summary messages clearly indicate which operation was performed.
53-64: Verify with Adversus API documentation whether empty payloads are accepted.The action allows all fields to be optional, which could result in an empty data object
{}being sent to the API. The code incomponents/adversus/actions/create-or-update-lead/create-or-update-lead.mjs(lines 54–60) spreads only truthy values, and no validation enforces that at least one field is provided. Confirm with Adversus API documentation (https://solutions.adversus.io/api) or their support whether:
- POST /leads and PUT /leads/{leadId} accept empty or minimal payloads
- Whether specific fields are required for lead creation/updates
If the API rejects empty payloads, add validation to require at least one field.
components/adversus/actions/assign-to-campaign/assign-to-campaign.mjs (2)
14-34: LGTM!The props correctly use propDefinitions for leadId and campaignId, maintaining consistency across actions. Both IDs are appropriately required for this operation.
35-45: LGTM!The run method correctly calls the API with the required IDs and optional additional fields. The implementation is clean and follows the established pattern.
components/adversus/actions/add-note-activity/add-note-activity.mjs (3)
14-46: LGTM!The props are well-defined with clear descriptions. The examples for activityType are particularly helpful for users.
47-71: LGTM!The promise building logic cleanly handles the optional nature of notes and activities. The use of conditional spreading for activity fields is appropriate.
73-82: LGTM!Excellent validation and execution logic. The error handling ensures meaningful input, Promise.all enables efficient concurrent operations, and the smart return logic (single result vs. array) provides a better user experience.
components/adversus/actions/change-lead-status/change-lead-status.mjs (2)
14-34: LGTM!The props correctly use propDefinitions and appropriately require both leadId and statusId for the status change operation.
35-45: LGTM!The run method is clean and follows the established pattern. The implementation correctly delegates to the app module's changeLeadStatus method.
components/adversus/adversus.app.mjs (4)
24-46: LGTM!The internal helper methods follow Pipedream conventions. The flexible authentication mapping in
_auth()and the centralized_makeRequest()method provide a clean foundation for the API methods.
47-74: LGTM!The API methods are cleanly implemented with appropriate HTTP methods and path construction. The consistent pattern makes the codebase maintainable.
75-86: LGTM!The data merging pattern correctly ensures
statusIdis included in the request payload while allowing additional fields from the caller. The destructuring and spreading logic is clean and appropriate.
87-98: LGTM!The method mirrors the changeLeadStatus pattern, providing consistency across the codebase. The data merging correctly ensures
campaignIdis included in the request.
components/adversus/actions/create-or-update-lead/create-or-update-lead.mjs
Show resolved
Hide resolved
…ead Status, Assign to Campaign - Added Create or Update Lead action - Added Add Note or Activity action - Added Change Lead Status action - Added Assign Lead to Campaign action - Updated adversus.app.mjs with API methods, authentication, and JSDoc comments - Updated README.md with API documentation link - Added comprehensive JSDoc documentation to all methods (meets 80% coverage requirement) - Fixed data merging in changeLeadStatus and assignLeadToCampaign methods - Used propDefinition pattern for consistency across all actions
745c9f3 to
697baf7
Compare
|
@coderabbitai please re-scan the PR. All docstrings have been added with JSDoc format to all methods in adversus.app.mjs and all run methods in the action files. |
|
Tip For best results, initiate chat on the files or code changes. 🧩 Analysis chain🏁 Script executed: Length of output: 4465 🏁 Script executed: Length of output: 2386 🏁 Script executed: Length of output: 1307 🏁 Script executed: Length of output: 1284 🏁 Script executed: Length of output: 2157 @harshasiddartha Thank you for adding the JSDoc documentation! I've scanned the PR and can confirm that all the requested documentation is now in place. Here's what I verified: ✅ adversus.app.mjsAll 9 methods now have proper JSDoc documentation:
✅ Action FilesAll 4 action run methods have JSDoc documentation:
The JSDoc comments follow best practices with proper (='.'=) |
|
@coderabbitai please review the latest changes. All docstrings have been added and the PR has been updated with a single clean commit. |
|
Tip For best results, initiate chat on the files or code changes. 🧩 Analysis chain🏁 Script executed: Length of output: 13424 @harshasiddartha Excellent work! I've completed a thorough review of all the files in the PR. The code looks great and the JSDoc documentation is comprehensive and well-formatted. Here's my detailed assessment: ✅ Documentation CompleteAll methods now have proper JSDoc documentation:
✅ Code Quality & Best PracticesYour implementation follows Pipedream component guidelines excellently:
💡 Minor Enhancement Suggestions (Optional)These are not blockers, just ideas for future improvements:
leadId: {
type: "string",
label: "Lead ID",
description: "The ID of the lead",
async options({ page }) {
// Fetch and return leads from API
},
},
if (!this.firstName && !this.lastName && !this.email && !this.phone && !this.additionalFields) {
throw new Error("At least one field must be provided to create or update a lead");
}
🎯 SummaryYour PR is ready for merge from a code quality perspective! The documentation is complete, the code follows best practices, and the implementation is solid. The suggestions above are optional enhancements that could be addressed in future PRs if desired. Great job on the clean, single commit and comprehensive documentation! 🚀 |
There was a problem hiding this 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 (3)
components/adversus/actions/create-or-update-lead/create-or-update-lead.mjs (1)
69-75: Pass the step context when invoking app methods.Without forwarding
$, we lose request logging / metrics in Pipedream, making debugging harder. Please include$in the payload you pass tocreateLead/updateLead.- const response = this.leadId - ? await this.adversus.updateLead(this.leadId, { data }) - : await this.adversus.createLead({ data }); + const response = this.leadId + ? await this.adversus.updateLead(this.leadId, { + $, + data, + }) + : await this.adversus.createLead({ + $, + data, + });components/adversus/actions/add-note-activity/add-note-activity.mjs (1)
55-87: Forward$to preserve request traces.Please include the step context when calling the app methods so HTTP requests show up in execution logs.
promises.push( - this.adversus.addNoteToLead(this.leadId, { + this.adversus.addNoteToLead(this.leadId, { + $, data: { note: this.note, ...(this.additionalFields || {}), }, }) @@ promises.push( - this.adversus.addActivityToLead(this.leadId, { + this.adversus.addActivityToLead(this.leadId, { + $, data: { ...(this.activityType && { type: this.activityType }), ...(this.activityDescription && { description: this.activityDescription }), ...(this.additionalFields || {}), },components/adversus/actions/change-lead-status/change-lead-status.mjs (1)
41-49: Forward$when calling the app method.Passing the step context keeps HTTP traces in the execution logs; please include
$.- const response = await this.adversus.changeLeadStatus(this.leadId, this.statusId, { + const response = await this.adversus.changeLeadStatus(this.leadId, this.statusId, { + $, data: { ...(this.additionalFields || {}), }, });
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (6)
components/adversus/README.md(1 hunks)components/adversus/actions/add-note-activity/add-note-activity.mjs(1 hunks)components/adversus/actions/assign-to-campaign/assign-to-campaign.mjs(1 hunks)components/adversus/actions/change-lead-status/change-lead-status.mjs(1 hunks)components/adversus/actions/create-or-update-lead/create-or-update-lead.mjs(1 hunks)components/adversus/adversus.app.mjs(1 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
- components/adversus/actions/assign-to-campaign/assign-to-campaign.mjs
🧰 Additional context used
🧠 Learnings (5)
📚 Learning: 2025-09-15T22:01:17.593Z
Learnt from: GTFalcao
Repo: PipedreamHQ/pipedream PR: 18362
File: components/leonardo_ai/README.md:45-49
Timestamp: 2025-09-15T22:01:17.593Z
Learning: In Leonardo AI components (and likely other Pipedream components), prefer using info alert props on the component itself rather than detailed "Key Features" sections in README files for action documentation.
Applied to files:
components/adversus/README.md
📚 Learning: 2024-10-30T15:24:39.294Z
Learnt from: jcortes
Repo: PipedreamHQ/pipedream PR: 14467
File: components/gainsight_px/actions/create-account/create-account.mjs:4-6
Timestamp: 2024-10-30T15:24:39.294Z
Learning: In `components/gainsight_px/actions/create-account/create-account.mjs`, the action name should be "Create Account" instead of "Create Memory".
Applied to files:
components/adversus/actions/create-or-update-lead/create-or-update-lead.mjs
📚 Learning: 2025-09-11T01:53:51.070Z
Learnt from: GTFalcao
Repo: PipedreamHQ/pipedream PR: 18334
File: components/buddee/actions/list-employees/list-employees.mjs:147-155
Timestamp: 2025-09-11T01:53:51.070Z
Learning: In Buddee list-employees action, the "manager" prop should be a boolean type to filter employees who have direct reports, not an employeeId propDefinition which would send an employee ID instead of the expected boolean value.
Applied to files:
components/adversus/actions/create-or-update-lead/create-or-update-lead.mjs
📚 Learning: 2025-06-04T17:52:05.780Z
Learnt from: GTFalcao
Repo: PipedreamHQ/pipedream PR: 16954
File: components/salesloft/salesloft.app.mjs:14-23
Timestamp: 2025-06-04T17:52:05.780Z
Learning: In the Salesloft API integration (components/salesloft/salesloft.app.mjs), the _makeRequest method returns response.data which directly contains arrays for list endpoints like listPeople, listCadences, listUsers, and listAccounts. The propDefinitions correctly call .map() directly on these responses without needing to destructure a nested data property.
Applied to files:
components/adversus/adversus.app.mjs
📚 Learning: 2025-09-15T22:01:11.472Z
Learnt from: GTFalcao
Repo: PipedreamHQ/pipedream PR: 18362
File: components/leonardo_ai/actions/generate-image/generate-image.mjs:103-105
Timestamp: 2025-09-15T22:01:11.472Z
Learning: In Pipedream components, pipedream/platform's axios implementation automatically excludes undefined values from HTTP requests, so there's no need to manually check for truthiness before including properties in request payloads.
Applied to files:
components/adversus/adversus.app.mjs
🧬 Code graph analysis (2)
components/adversus/actions/change-lead-status/change-lead-status.mjs (2)
components/adversus/actions/assign-to-campaign/assign-to-campaign.mjs (1)
response(41-45)components/adversus/actions/create-or-update-lead/create-or-update-lead.mjs (1)
response(69-71)
components/adversus/actions/create-or-update-lead/create-or-update-lead.mjs (2)
components/adversus/actions/assign-to-campaign/assign-to-campaign.mjs (1)
response(41-45)components/adversus/actions/change-lead-status/change-lead-status.mjs (1)
response(41-45)
components/adversus/actions/create-or-update-lead/create-or-update-lead.mjs
Show resolved
Hide resolved
- Validate that at least one field is provided before making API call - Prevents 400 errors from Adversus API when empty payload is sent - Provides clear error message to users
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hi @harshasiddartha please increase the version of package.json to "version": "0.7.0", since you are adding new components to the app. I've just left a couple of suggestions which are options other than that it's looking good thanks!
- Update package.json version to 0.7.0 - Simplify _auth() to only use username and password (remove fallbacks) - Simplify _makeRequest to directly use this._auth()
|
Hi @jcortes! Thank you for the review feedback. I've addressed all your suggestions: ✅ Updated package.json version to ✅ Simplified ✅ Simplified All changes have been committed and pushed. The PR is ready for your review! |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 0
🧹 Nitpick comments (1)
components/adversus/adversus.app.mjs (1)
6-22: Consider adding async options for dynamic prop lists.The current propDefinitions provide static string inputs, which is functional. However, to enhance user experience, consider implementing async options to fetch and display available leads, campaigns, and statuses as dropdown lists from the Adversus API.
For example, for
leadId:leadId: { type: "string", label: "Lead ID", description: "The ID of the lead", async options({ page }) { // Fetch leads from API and return { label, value } pairs const leads = await this.listLeads({ page }); return leads.map(lead => ({ label: lead.name || lead.id, value: lead.id, })); }, },This pattern would require adding corresponding list methods (e.g.,
listLeads(),listCampaigns(),listStatuses()) to the app file.
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (2)
components/adversus/adversus.app.mjs(1 hunks)components/adversus/package.json(1 hunks)
✅ Files skipped from review due to trivial changes (1)
- components/adversus/package.json
🧰 Additional context used
🧠 Learnings (2)
📚 Learning: 2025-06-04T17:52:05.780Z
Learnt from: GTFalcao
Repo: PipedreamHQ/pipedream PR: 16954
File: components/salesloft/salesloft.app.mjs:14-23
Timestamp: 2025-06-04T17:52:05.780Z
Learning: In the Salesloft API integration (components/salesloft/salesloft.app.mjs), the _makeRequest method returns response.data which directly contains arrays for list endpoints like listPeople, listCadences, listUsers, and listAccounts. The propDefinitions correctly call .map() directly on these responses without needing to destructure a nested data property.
Applied to files:
components/adversus/adversus.app.mjs
📚 Learning: 2025-09-15T22:01:11.472Z
Learnt from: GTFalcao
Repo: PipedreamHQ/pipedream PR: 18362
File: components/leonardo_ai/actions/generate-image/generate-image.mjs:103-105
Timestamp: 2025-09-15T22:01:11.472Z
Learning: In Pipedream components, pipedream/platform's axios implementation automatically excludes undefined values from HTTP requests, so there's no need to manually check for truthiness before including properties in request payloads.
Applied to files:
components/adversus/adversus.app.mjs
🔇 Additional comments (7)
components/adversus/adversus.app.mjs (7)
1-1: LGTM!Correct import for Pipedream components.
24-40: LGTM!Authentication and base URL helpers are correctly implemented. The use of
this.$auth.usernameandthis.$auth.passwordaligns with Pipedream's authentication patterns.
41-59: LGTM!The centralized request method correctly implements the Pipedream pattern with axios, basic auth, and proper option spreading. The default
$ = thisprovides a sensible fallback for error reporting.
60-84: LGTM!Both
createLeadandupdateLeadmethods are clean wrappers around_makeRequestwith correct HTTP methods and paths. The template literal for/leads/${leadId}is properly used.
85-110: LGTM!Both
addNoteToLeadandaddActivityToLeadmethods correctly use POST requests to the appropriate nested endpoints. The implementation is consistent with other methods in the file.
111-129: LGTM! Good data merging approach.The method correctly handles data merging by:
- Destructuring
datafromoptsto avoid overwriting it- Reconstructing the
dataobject withstatusIdwhile preserving additional fields fromoptsData- Using
...(optsData || {})to safely handle undefined casesThis pattern ensures the required
statusIdparameter is always included while allowing callers to pass additional fields.
130-148: LGTM! Consistent data merging pattern.This method uses the same correct data merging approach as
changeLeadStatus, ensuringcampaignIdis always included while preserving additional optional fields. The consistency across these two methods is good for maintainability.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hi @harshasiddartha lgtm! Ready for QA!
For Integration QA: |
|
Hi everyone, all test cases are passed! Ready for release! Test reports
|
|
@harshasiddartha Thanks for your contribution! This is still failing the Lint Code Base PR Check. You'll need to run |
WHY
These actions address common use cases for Pipedream users integrating with Adversus. Currently, the Adversus component only has basic app configuration, but lacks the essential actions needed for lead management workflows. Adding these actions enables users to:
These actions fill a critical gap in the Adversus integration, allowing users to build comprehensive automation workflows that weren't previously possible.
WHAT
This PR adds four new actions to the Adversus component:
All actions include API documentation references to https://solutions.adversus.io/api
Changes Made
App File Updates (
adversus.app.mjs)createLead()- Create a new leadupdateLead()- Update an existing leadaddNoteToLead()- Add a note to a leadaddActivityToLead()- Add an activity to a leadchangeLeadStatus()- Change lead statusassignLeadToCampaign()- Assign lead to campaignchangeLeadStatusandassignLeadToCampaignmethodsNew Actions
Documentation
Testing
Summary by CodeRabbit