-
Notifications
You must be signed in to change notification settings - Fork 5.5k
New Components - selzy #16692
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
New Components - selzy #16692
Conversation
|
The latest updates on your projects. Learn more about Vercel for Git ↗︎ 3 Skipped Deployments
|
WalkthroughThis update introduces a comprehensive Selzy integration, adding action components for creating email messages and campaigns, utility and constants modules, and several event source components for real-time and polling-based monitoring of campaigns and subscribers. The Selzy app interface is fully implemented with API methods, pagination, and prop definitions. Supporting test events and base classes for sources are also included. Changes
Sequence Diagram(s)sequenceDiagram
participant User
participant ActionComponent
participant SelzyApp
participant SelzyAPI
User->>ActionComponent: Provide action input (e.g., create campaign)
ActionComponent->>SelzyApp: Call API method with parameters
SelzyApp->>SelzyAPI: Make HTTP request to Selzy endpoint
SelzyAPI-->>SelzyApp: Return API response
SelzyApp-->>ActionComponent: Return processed response
ActionComponent-->>User: Output result/summary
sequenceDiagram
participant SelzyWebhook
participant SourceComponent
participant User
SelzyWebhook->>SourceComponent: Send webhook event (e.g., new subscriber)
SourceComponent->>SourceComponent: Parse and deduplicate event
SourceComponent-->>User: Emit event with summary and data
Assessment against linked issues
Suggested reviewers
Poem
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
components/selzy/actions/create-campaign/create-campaign.mjsOops! Something went wrong! :( ESLint: 8.57.1 Error [ERR_MODULE_NOT_FOUND]: Cannot find package 'jsonc-eslint-parser' imported from /eslint.config.mjs components/selzy/sources/new-campaign/new-campaign.mjsOops! Something went wrong! :( ESLint: 8.57.1 Error [ERR_MODULE_NOT_FOUND]: Cannot find package 'jsonc-eslint-parser' imported from /eslint.config.mjs 📜 Recent review detailsConfiguration used: CodeRabbit UI 📒 Files selected for processing (2)
🚧 Files skipped from review as they are similar to previous changes (2)
⏰ Context from checks skipped due to timeout of 90000ms (4)
✨ Finishing Touches
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. 🪧 TipsChatThere are 3 ways to chat with CodeRabbit:
SupportNeed 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)
Other keywords and placeholders
CodeRabbit Configuration File (
|
Sources - New Campaign - New Campaign Status (Instant) - New Subscriber (Instant) Actions - Create Subscriber - Send Campaign - Create Campaign
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: 5
🧹 Nitpick comments (3)
components/selzy/common/utils.mjs (1)
26-38: Effective utility for cleaning objectsThe
clearEmptyfunction provides a straightforward way to remove empty, null, or undefined values from objects. This is particularly useful for API requests where empty parameters should be omitted rather than sent as empty values.Consider adding support for handling nested objects and arrays to make this utility even more versatile:
export const clearEmpty = (obj) => { if (!obj) return undefined; const newObj = { ...obj, }; Object.keys(newObj).forEach((key) => { if (newObj[key] === "" || newObj[key] === null || newObj[key] === undefined) { delete newObj[key]; + } else if (typeof newObj[key] === 'object' && newObj[key] !== null) { + // Recursively clean nested objects and arrays + const cleaned = clearEmpty(newObj[key]); + if (Array.isArray(newObj[key]) && cleaned.length === 0) { + delete newObj[key]; // Remove empty arrays + } else if (!Array.isArray(newObj[key]) && Object.keys(cleaned).length === 0) { + delete newObj[key]; // Remove empty objects + } else { + newObj[key] = cleaned; + } } }); return newObj; };components/selzy/actions/create-campaign/create-campaign.mjs (1)
95-104:additionalPropsshould return mutatedpropsto persist UI changesReturning
{}may discard the visibility toggles you just set. Return the mutated object instead:- return {}; + return props;Without this, the GA fields can remain hidden in the UI even after the user checks Track GA.
components/selzy/sources/new-campaign/new-campaign.mjs (1)
61-66: Event timestamp should reflect campaign creation time
Date.parse(new Date())merely returns now; using the campaign’s own timestamp is more valuable.- ts: Date.parse(new Date()), + ts: Date.parse(item.start_time),
📜 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
⛔ Files ignored due to path filters (1)
pnpm-lock.yamlis excluded by!**/pnpm-lock.yaml
📒 Files selected for processing (13)
components/selzy/actions/create-campaign/create-campaign.mjs(1 hunks)components/selzy/actions/create-email-message/create-email-message.mjs(1 hunks)components/selzy/common/constants.mjs(1 hunks)components/selzy/common/utils.mjs(1 hunks)components/selzy/package.json(2 hunks)components/selzy/selzy.app.mjs(1 hunks)components/selzy/sources/common/base.mjs(1 hunks)components/selzy/sources/new-campaign-status-instant/new-campaign-status-instant.mjs(1 hunks)components/selzy/sources/new-campaign-status-instant/test-event.mjs(1 hunks)components/selzy/sources/new-campaign/new-campaign.mjs(1 hunks)components/selzy/sources/new-campaign/test-event.mjs(1 hunks)components/selzy/sources/new-subscriber-instant/new-subscriber-instant.mjs(1 hunks)components/selzy/sources/new-subscriber-instant/test-event.mjs(1 hunks)
🧰 Additional context used
🪛 GitHub Actions: Pull Request Checks
components/selzy/actions/create-campaign/create-campaign.mjs
[error] 1-1: Component folder name, component file name without extension and component key without slug should be the same. See https://pipedream.com/docs/components/guidelines/#folder-structure
⏰ 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 (26)
components/selzy/package.json (2)
3-3: Version bump from 0.0.1 to 0.1.0 is appropriateThe version increment follows semantic versioning principles, indicating this is a minor release with new functionality but no breaking changes, which aligns with introducing new Selzy integration components.
14-16: Proper dependency configurationAdded the Pipedream platform dependency correctly with appropriate versioning using the caret notation to accept compatible updates. This ensures the Selzy components have access to the required platform functionality.
components/selzy/sources/new-campaign-status-instant/test-event.mjs (1)
1-13: Appropriate test event structure for webhook testingThis test event correctly models a campaign status webhook payload with all the necessary fields that would be expected from the Selzy API. The sample data includes authentication tokens, campaign identifiers, and status information that will be useful for development and testing.
Note that the event_time is set to a future date (2025-05-16). While this doesn't affect functionality, it's worth noting that using dates closer to the present might make the test data feel more realistic.
components/selzy/sources/new-campaign/test-event.mjs (1)
1-11: Well-structured test event for campaign pollingThe test event provides a comprehensive sample of campaign data including ID, timing, status, and messaging details. This structure appears to match Selzy's API response format for campaigns.
Note that the start_time is set to a future date (2025-06-10). While this won't impact functionality, using dates closer to the present might make the test data feel more realistic during development and testing.
components/selzy/sources/new-subscriber-instant/test-event.mjs (1)
1-10: Complete test event for subscriber webhook testingThis test event provides all the necessary fields for testing the subscriber webhook integration, including authentication details, event metadata, and subscription information.
Note that the event_time is set to a future date (2025-05-16). While this doesn't affect functionality, using dates closer to the present might make the test data feel more realistic during development.
components/selzy/common/utils.mjs (1)
1-24: Robust object parsing utility with proper error handlingThe
parseObjectfunction correctly handles multiple input types including arrays and strings, with appropriate error handling for JSON parsing. The function gracefully falls back to returning the original value when parsing fails, making it resilient against malformed inputs.components/selzy/common/constants.mjs (3)
1-1: Well-defined pagination limit constant.Setting a fixed pagination limit of 100 is a good practice to control API call data sizes.
3-16: Good organization of message format options.The message format options are well-structured with clear labels and corresponding values. This makes it easy for users to understand the available choices when creating email messages.
18-35: Clear text alignment options with descriptive labels.The wrap type options are well-defined with informative labels that include both the alignment name and a description of what it does, which improves the user experience.
components/selzy/sources/new-campaign-status-instant/new-campaign-status-instant.mjs (4)
1-3: Clean imports with good separation of concerns.The module correctly imports the common base module and a sample event for testing purposes.
4-12: Well-structured component metadata.The component is properly defined with appropriate metadata, including a descriptive name, clear description, semantic versioning, and suitable deduplication strategy.
13-22: Effective method implementations for webhook filtering and event summarization.The
getEventTypemethod correctly specifies the wildcard filter for campaign status events, and thegetSummarymethod provides a clear human-readable description of the event.
23-24: Good practice including sample event for testing.Including the sample emit data makes testing and development easier.
components/selzy/sources/new-subscriber-instant/new-subscriber-instant.mjs (5)
1-3: Clean imports with good separation of concerns.The module correctly imports the common base module and a sample event for testing purposes.
4-12: Well-structured component metadata.The component is properly defined with appropriate metadata, including a descriptive name, clear description, semantic versioning, and suitable deduplication strategy.
12-22: Well-designed optional list filtering capability.The
listIdproperty is properly defined as optional, allowing users to monitor all lists or a specific one. The description clearly explains the purpose of this property.
23-35: Effective event filtering and summary implementation.The
getEventTypemethod properly handles both filtered and unfiltered list scenarios, and thegetSummarymethod creates a clear description that includes the subscriber's email.
36-37: Good practice including sample event for testing.Including the sample emit data makes testing and development easier.
components/selzy/sources/common/base.mjs (4)
1-11: Well-structured props with required dependencies.The base component correctly imports the Selzy app and sets up necessary props for HTTP interface with custom response handling and database service.
12-31: Robust webhook lifecycle management.The
activateanddeactivatehooks properly create and clean up webhooks, ensuring good resource management. The webhook configuration includes necessary parameters for JSON POST format and active status.
32-40: Appropriate handling of webhook verification.The
runmethod correctly responds to GET requests with a 200 status code, which is typically used for webhook verification by service providers.
42-48: Effective event emission with proper metadata.The event emission includes a composite ID for deduplication (using campaign ID or email with timestamp), a human-readable summary, and the parsed timestamp for proper sorting and filtering in the Pipedream UI.
components/selzy/actions/create-email-message/create-email-message.mjs (1)
108-110: Good defensive validation of mutually-exclusive template fields
The earlyConfigurationErrorprevents a hard-to-debug API error. 👍components/selzy/actions/create-campaign/create-campaign.mjs (1)
112-125: Boolean → int cast is fine, but empty fields are already strippedBecause
clearEmpty()will remove falsy values, the&& +this.trackReadidiom works and keeps the payload minimal – nice touch.components/selzy/selzy.app.mjs (2)
70-77:messageIdoption loader is returning templates, not messages
listTemplates(type: "system")is unlikely to list user-created messages.
If Selzy exposes alistMessages/getMessagesendpoint, switch to that; otherwise users will pick the wrong IDs.
116-124: Robust request helper – good centralisationConsolidating auth, base URL and axios call parameters here keeps every API wrapper consistent and DRY.
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
♻️ Duplicate comments (1)
components/selzy/actions/create-campaign/create-campaign.mjs (1)
8-13: Component key matches folder name correctlyThe component key "selzy-create-campaign" now matches the folder/file name "create-campaign", which resolves the previous build error mentioned in past review comments.
🧹 Nitpick comments (4)
components/selzy/actions/create-campaign/create-campaign.mjs (4)
95-104: Refactor the additionalProps method to follow expected patternsThe
additionalPropsmethod directly modifies thepropsparameter and returns an empty object, which is not the conventional pattern for this method. Typically, this method should return properties to be added, not modify existing ones.Consider refactoring to follow this pattern:
async additionalProps() { const gaAllowed = this.trackGa; - props.gaMedium.hidden = !gaAllowed; - props.gaSource.hidden = !gaAllowed; - props.gaCampaign.hidden = !gaAllowed; - props.gaContent.hidden = !gaAllowed; - props.gaTerm.hidden = !gaAllowed; - return {}; + return { + gaMedium: { + hidden: !gaAllowed, + }, + gaSource: { + hidden: !gaAllowed, + }, + gaCampaign: { + hidden: !gaAllowed, + }, + gaContent: { + hidden: !gaAllowed, + }, + gaTerm: { + hidden: !gaAllowed, + }, + }; }
115-124: Simplify boolean to numeric conversionThe current approach for converting boolean values to numbers is functional but could be simplified for better readability.
Consider using ternary operators or a utility function for consistent conversion:
- track_read: this.trackRead && +this.trackRead, - track_links: this.trackLinks && +this.trackLinks, - track_ga: this.trackGa && +this.trackGa, + track_read: this.trackRead ? 1 : 0, + track_links: this.trackLinks ? 1 : 0, + track_ga: this.trackGa ? 1 : 0,Or create a utility function:
const boolToNum = (value) => value ? 1 : 0;Then use it:
track_read: boolToNum(this.trackRead),
117-117: Consider adding fallback for empty arraysThe current implementation joins the array with a comma but doesn't handle empty arrays explicitly.
Consider adding a check to handle potential empty arrays:
- contacts: parseObject(this.contacts)?.join(","), + contacts: parseObject(this.contacts)?.length ? parseObject(this.contacts).join(",") : undefined,
130-130: Consider updating the summary message for consistencyThe summary message specifies "email campaign" but the component name is more generically "Create Campaign".
Either update the summary message to be consistent with the component name or update the component name to specify "email campaign" if that's the specific focus:
- $.export("$summary", `Successfully created email campaign with ID: ${response.result.campaign_id}`); + $.export("$summary", `Successfully created campaign with ID: ${response.result.campaign_id}`);
📜 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
⛔ Files ignored due to path filters (1)
pnpm-lock.yamlis excluded by!**/pnpm-lock.yaml
📒 Files selected for processing (1)
components/selzy/actions/create-campaign/create-campaign.mjs(1 hunks)
⏰ Context from checks skipped due to timeout of 90000ms (4)
- GitHub Check: pnpm publish
- GitHub Check: Publish TypeScript components
- GitHub Check: Lint Code Base
- GitHub Check: Verify TypeScript components
🔇 Additional comments (2)
components/selzy/actions/create-campaign/create-campaign.mjs (2)
106-108: LGTM! Good validation check for mutually exclusive parametersThe validation check ensures that users cannot provide both
contactsandcontactsUrlsimultaneously, which aligns with the API requirements.
1-7: LGTM! Appropriate imports and error handlingThe imports are correct, and the code properly uses the ConfigurationError class from the Pipedream platform for error handling. The utility functions are imported correctly from the common folder.
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 (2)
components/selzy/actions/create-campaign/create-campaign.mjs (2)
109-115: Optimize Google Analytics parameter handling.Currently, GA parameters are passed to the API even when
trackGais false. Consider only including them when GA tracking is enabled to reduce payload size and improve clarity.track_ga: this.trackGa && +this.trackGa, - ga_medium: this.gaMedium, - ga_source: this.gaSource, - ga_campaign: this.gaCampaign, - ga_content: this.gaContent, - ga_term: this.gaTerm, + ...(this.trackGa && { + ga_medium: this.gaMedium, + ga_source: this.gaSource, + ga_campaign: this.gaCampaign, + ga_content: this.gaContent, + ga_term: this.gaTerm, + }),
118-118: Enhance error handling with more context.The current error handling only passes through the API error message. Consider providing more context about the operation that failed.
- if (response.error) throw new ConfigurationError(response.error); + if (response.error) throw new ConfigurationError(`Failed to create campaign: ${response.error}`);
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (3)
components/selzy/actions/create-campaign/create-campaign.mjs(1 hunks)components/selzy/actions/create-email-message/create-email-message.mjs(1 hunks)components/selzy/sources/new-campaign/new-campaign.mjs(1 hunks)
🚧 Files skipped from review as they are similar to previous changes (2)
- components/selzy/actions/create-email-message/create-email-message.mjs
- components/selzy/sources/new-campaign/new-campaign.mjs
⏰ Context from checks skipped due to timeout of 90000ms (4)
- GitHub Check: Publish TypeScript components
- GitHub Check: pnpm publish
- GitHub Check: Lint Code Base
- GitHub Check: Verify TypeScript components
🔇 Additional comments (1)
components/selzy/actions/create-campaign/create-campaign.mjs (1)
1-10: LGTM! Key/folder name mismatch resolved.The component key now correctly matches the folder and file name, resolving the build issue mentioned in the previous 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: 2
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (2)
components/selzy/actions/create-email-message/create-email-message.mjs(1 hunks)components/selzy/sources/new-campaign/new-campaign.mjs(1 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
- components/selzy/actions/create-email-message/create-email-message.mjs
⏰ Context from checks skipped due to timeout of 90000ms (4)
- GitHub Check: Verify TypeScript components
- GitHub Check: pnpm publish
- GitHub Check: Lint Code Base
- GitHub Check: Publish TypeScript components
🔇 Additional comments (4)
components/selzy/sources/new-campaign/new-campaign.mjs (4)
1-20: LGTM: Standard component setupThe component configuration follows Pipedream conventions correctly with appropriate props, dedupe strategy, and polling setup.
22-27: LGTM: Clean state managementThe database methods for tracking the last processed campaign ID are simple and effective.
42-48: LGTM: Correct lastId trackingThe logic correctly sets the lastId to the newest campaign's ID before reversing the array for emission. The past review comment appears to be outdated or incorrect for this implementation.
59-67: LGTM: Proper deployment and run logicThe deploy hook appropriately limits initial events to 25, and the run method enables unlimited polling for ongoing monitoring.
Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
|
/approve |
Resolves #16657.
Summary by CodeRabbit
New Features
Improvements
Chores