-
Notifications
You must be signed in to change notification settings - Fork 5.3k
[Components] Drift. Actions + Sources #16553
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?
Conversation
The latest updates on your projects. Learn more about Vercel for Git ↗︎ 1 Skipped Deployment
|
@SokolovskyiK is attempting to deploy a commit to the Pipedreamers Team on Vercel. A member of the Team first needs to authorize it. |
WalkthroughThis update introduces a comprehensive suite of new Drift integration components, including actions for creating, updating, retrieving, and deleting contacts, as well as several event sources for contact and conversation updates. The Drift app interface is significantly expanded to include robust API methods for contact CRUD operations, pagination, and utility helpers. New polling and webhook-based sources are provided for tracking new conversations, messages, leads, and contact updates. The package version is incremented to 0.7.0, and a utility function for object cleanup is added. Changes
Sequence Diagram(s)sequenceDiagram
participant User
participant Action
participant DriftApp
participant DriftAPI
User->>Action: Provide contact details
Action->>DriftApp: Call createContact / updateContact / getContactByEmailOrId
DriftApp->>DriftAPI: Make HTTP request (create/update/get)
DriftAPI-->>DriftApp: Respond with contact data
DriftApp-->>Action: Return contact data or status
Action-->>User: Output summary and result
sequenceDiagram
participant DriftWebhook
participant Source
participant DriftApp
participant DriftAPI
DriftWebhook->>Source: Send event (e.g., contact_updated)
Source->>DriftApp: Fetch contact details (getContactById)
DriftApp->>DriftAPI: GET contact by ID
DriftAPI-->>DriftApp: Return contact data
DriftApp-->>Source: Provide contact data
Source-->>Source: Enrich and emit event
Assessment against linked issues
Suggested labels
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/drift/actions/create-contact/create-contact.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/drift/actions/delete-contact/delete-contact.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/drift/actions/get-contact/get-contact.mjsOops! Something went wrong! :( ESLint: 8.57.1 Error [ERR_MODULE_NOT_FOUND]: Cannot find package 'jsonc-eslint-parser' imported from /eslint.config.mjs
✨ 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 (
|
Thank you so much for submitting this! We've added it to our backlog to review, and our team has been notified. |
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: 17
🧹 Nitpick comments (31)
components/drift/actions/create-contact/create-contact.mjs (3)
53-61
: Consider performance implications of object spreading with large customAttributesThe use of
...customAttributes
could lead to performance issues if the customAttributes object is very large. Also, be careful when spreading user-provided objects as they might contain properties that could override your predefined attributes.const attributes = removeNullEntries({ email, name, phone, source, - ...customAttributes, + ...(customAttributes || {}), });
63-72
: Fix extra space in error messageThere's an extra space between
Error
and the opening backtick in the error message.if (existingContact && existingContact.data.length > 0) { - throw new Error (`Contact ${email} already exists`); + throw new Error(`Contact ${email} already exists`); };
74-85
: Improve formatting of warning messages in summaryThe warning message concatenation could be formatted more clearly. If there are no warnings, the current implementation will still add a newline character.
- $.export("$summary", `Contact ${email} created.` + warnings.join("\n- ")); + $.export("$summary", `Contact ${email} created.${warnings.length ? '\n- ' + warnings.join("\n- ") : ''}`);components/drift/sources/new-lead-instance.mjs/new-lead-instance.mjs (2)
30-30
: Fix spacing and improve comment clarityThere's an extra space before the assignment operator, and the comment could be more descriptive.
- body.data.attributes = result.data.attributes; //inject more data + body.data.attributes = result.data.attributes; // Enrich webhook data with full contact attributes
32-36
: Consider adding validation for required fieldsThe code assumes that
body.data.endUserId
andbody.timeStamp
will always be present. Consider adding validation to handle cases where these fields might be missing.+ const id = body.data?.endUserId || `lead-${Date.now()}`; + const ts = body.timeStamp || Date.now(); + this.$emit(body, { summary: `Contact "${email}" ID "${contactId}" updated`, - id: body.data.endUserId, - ts: body.timeStamp, + id, + ts, });components/drift/sources/new-message-instant/new-message-instant.mjs (1)
12-17
: Add validation for the conversationId prop.The conversationId is defined as an integer type, but there's no validation to ensure it's a positive number.
Add validation for the conversationId in the run method:
async run(event) { const { body } = event; const { drift } = this; const warnings = []; + if (this.conversationId && (isNaN(this.conversationId) || this.conversationId <= 0)) { + warnings.push("Conversation ID must be a positive number"); + } if (this.emailOrId) warnings.push(...drift.checkEmailOrId(this.emailOrId)); if (warnings.length > 0) console.log(warnings.join("\n- "));components/drift/actions/get-contact/get-contact.mjs (1)
34-35
: Improve the warning message formatting.The warning messages are joined without a separator, which could make them harder to read.
- $.export("$summary", `Contact ${contact.attributes.email} ID "${contact.id}"` - + " fetched successfully." + warnings.join("\n- ")); + $.export("$summary", `Contact ${contact.attributes.email} ID "${contact.id}" fetched successfully.` + + (warnings.length ? "\n- " + warnings.join("\n- ") : ""));components/drift/sources/new-contact-update/new-contact-update.mjs (2)
24-26
: Use consistent object reference pattern.You're using
this.drift
while other files usedrift
directly. Stay consistent with accessing the drift object.- const result = await this.drift.getContactById({ + const result = await drift.getContactById({ contactId, });
32-35
: Remove redundant console.log statement.There are two consecutive console.log statements with similar content.
- console.log(body); - - console.log("Contact updated webhook payload:", body); + console.log("Contact updated webhook payload:", body);components/drift/actions/update-contact/update-contact.mjs (2)
8-8
: Use consistent version numbering across components.This component uses version "0.0.9" while other new components use "0.0.1". Maintain consistent versioning for new components.
- version: "0.0.9", + version: "0.0.1",
86-86
: Improve warning message formatting.The warning messages are joined without proper formatting, which could make them harder to read.
- $.export("$summary", `Contact ID ${contactId} updated successfully.` + warnings.join("\n- ")); + $.export("$summary", `Contact ID ${contactId} updated successfully.` + + (warnings.length ? "\n- " + warnings.join("\n- ") : ""));components/drift/actions/delete-contact/delete-contact.mjs (2)
28-32
: Handle array vs. object response explicitly for clarity
contact = contact.data[0] || contact.data;
works, but the implicit truthy check obscures intent and could mask edge–cases (e.g. whendata
is an empty array). Prefer an explicit test so future readers immediately see why the fallback exists and to avoid accidentally operating onundefined
.-let contact = await drift.getContactByEmailOrId($, emailOrId); -contact = contact.data[0] || contact.data; +const res = await drift.getContactByEmailOrId($, emailOrId); +const contact = Array.isArray(res.data) ? res.data[0] : res.data; + +if (!contact) { + throw new Error(`No contact returned for "${emailOrId}"`); +}
39-41
: Avoid dangling bullet when no warnings are present
warnings.join("\n- ")
always appends a newline + dash, so the summary becomes
…deleted successfully.-
whenwarnings
is empty. Build the string conditionally:-$.export("$summary", `Contact ${contactEmail} ID "${contactId}" deleted successfully.` + - warnings.join("\n- ")); +const summary = `Contact ${contactEmail} ID "${contactId}" deleted successfully.` + + (warnings.length ? `\n- ${warnings.join("\n- ")}` : ""); +$.export("$summary", summary);components/drift/drift.app.mjs (2)
108-114
: Remove unreachableelse
semicolon and streamline error pathBiome flags line 113 as unreachable because both branches
throw
. The trailing semicolon after the}
is unnecessary and may confuse linters.- } catch (error) { - if (error.status === 404) { - throw new Error(`No contact found with ID: ${contactId}`); - } else { - throw error; - }; - } + } catch (error) { + if (error.status === 404) { + throw new Error(`No contact found with ID: ${contactId}`); + } + throw error; + }🧰 Tools
🪛 Biome (1.9.4)
[error] 113-113: This code is unreachable
... because either this statement ...
... or this statement will throw an exception beforehand
(lint/correctness/noUnreachable)
132-136
: Typo in variable name & potential off-by-one
const firtsNew
→firstNew
. Small typo hinders readability.Also, throwing when the id is not found may abort an otherwise recoverable poll. Consider logging and returning an empty list instead.
-const firtsNew = arr.indexOf(lastKnown); -if (firtsNew === -1) throw new Error("Id not found"); -const newest = arr.slice(0, firtsNew); +const firstNew = arr.indexOf(lastKnown); +if (firstNew === -1) return []; +const newest = arr.slice(0, firstNew);components/drift/sources/new-conversation-instant/new-conversation-instant.mjs (2)
41-43
: Debug statement left in source
console.log("here");
looks like leftover debugging noise and will spam logs.- console.log("here");
100-101
: Event summary references contactId, not the conversation IDFor clarity to users looking at the event feed, consider using the conversation id (matches
id
field) or include both.-summary: `New conversation with ID ${conversations[i].contactId}`, +summary: `New conversation ${conversations[i].id} with contact ${conversations[i].contactId}`,components/drift/common/methods.mjs (14)
12-15
: Fix semicolon placement in conditional block.There's an unnecessary semicolon after the conditional block which doesn't follow JavaScript best practices.
isEmptyString(input) { if (this.isString(input)) { if (input.trim() === "") return true; - }; + } return false; },
35-38
: Fix semicolon placement in for loop.There's an unnecessary semicolon after the for loop which doesn't follow JavaScript best practices.
for (let i = 0; i < input.length; i++) { if (!this.isString(input[i])) return false; - }; + }
62-65
: Fix JSDoc comment formatting.The comment has inconsistent slashes. The closing delimiter should match the opening style.
/* ============================================================================================= Function tries to parse the input as JSON, If it is not return the value as it was passed - //==============================================================================================*/ + ==============================================================================================*/
92-95
: Fix semicolon placement after conditional block.There's an unnecessary semicolon after the conditional block which doesn't follow JavaScript best practices.
if (!this.isString(input)) { warnings.push("URL is not a string"); - - }; + }
97-100
: Fix semicolon placement after conditional block.There's an unnecessary semicolon after the conditional block which doesn't follow JavaScript best practices.
if (this.isEmptyString(input)) { warnings.push("URL is empty string"); return warnings; - }; + }
104-109
: Fix semicolon placement and improve regex check.There's an unnecessary semicolon after the conditional block, and the regex test could be improved.
// Reject if spaces, tabs, or newlines are present - if ((/[ \t\n]/.test(trimmedInput))) { + if (/[ \t\n]/.test(trimmedInput)) { warnings.push( "Url contains invalid characters like space, backslash etc., please check." + this._reasonMsg(input)); return warnings; - }; + }
119-121
: Fix semicolon placement after conditional block.There's an unnecessary semicolon after the conditional block which doesn't follow JavaScript best practices.
if (dubiousMatches) { warnings.push(" URL contains dubious or non-standard characters " + this._reasonMsg(input) ); - }; + }
130-135
: Fix semicolon placement and improve warning message.There's an unnecessary semicolon after the conditional block and the warning message could be better formatted.
// Warn if user typed only one slash (e.g., https:/) if (/^(https?):\/(?!\/)/.test(input)) { - warnings.push(` It looks like you're missing one slash after "${urlObject.protocol}".` + `Did you mean "${urlObject.protocol}//..."? ${this._reasonMsg(input)} `); - - }; + }
146-150
: Fix semicolon placement after catch block.There's an unnecessary semicolon after the catch block which doesn't follow JavaScript best practices.
} catch (err) { warnings.push(" URL contains potentionally unacceptable characters\"" + this._reasonMsg(input)); - - }; + }
147-148
: Fix typo in warning message.The warning message contains a typo in the word "potentially".
- warnings.push(" URL contains potentionally unacceptable characters\"" + + warnings.push(" URL contains potentially unacceptable characters\"" + this._reasonMsg(input));
198-204
: Consider using a more robust email validation regex.The current regex is fairly minimal. While it checks basic structure, it might be worth considering a more comprehensive pattern that better matches email RFC standards.
For a more robust but still reasonable email validation, consider:
- const basicPattern = /^[^@\s]+@[^@\s]+\.[^@\s]+$/; + // More comprehensive pattern checking for valid characters and structure + const basicPattern = /^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$/;This pattern better enforces valid characters in the local and domain parts, and requires a minimum domain extension length.
255-274
: Optimize thecheckEmailOrId
implementation.Currently, we convert the input to a number twice. We can optimize this by storing the result of the first conversion.
checkEmailOrId(input) { const warnings = []; const trimmed = this.trimIfString(input); + // Convert to number once + const numericValue = Number(trimmed); // If it's an ID like number or string (e.g 12345 or "12345"); // it's Valid. Return empty warnings array. - if (this.isIdNumber(Number(trimmed))) return warnings; + if (this.isIdNumber(numericValue)) return warnings; // If it's not a string. if (!this.isString(trimmed)) { warnings.push("Provided value is not an email or ID-like value (e.g., 1234 or '1234')."); return warnings; } warnings.push(...this.checkIfEmailValid(trimmed)); return warnings; },
283-285
: Improve error source determination.The current method of determining the error source is somewhat simplified. Errors can come from other sources beyond API responses and internal code.
Consider a more detailed error classification:
- const thrower = error?.response?.status - ? "API response" - : "Internal Code"; + let thrower = "Internal Code"; + + if (error?.response?.status) { + thrower = `API response (${error.response.status})`; + } else if (error?.code === 'ECONNREFUSED' || error?.code === 'ENOTFOUND') { + thrower = "Network connectivity"; + } else if (error?.code === 'ETIMEDOUT') { + thrower = "Request timeout"; + }
1-302
: Overall good structure but consider adding common validation interfaces.The utility module provides a comprehensive set of validation and helper functions. However, it would be beneficial to introduce some higher-level validation interfaces that combine multiple checks for common scenarios.
Consider adding a high-level validation method that combines related checks:
validateContactInput(input) { const warnings = []; // Check required fields if (!input.email && !input.id) { warnings.push("Either email or id must be provided for contact operations"); } // Validate email if provided if (input.email) { warnings.push(...this.checkIfEmailValid(input.email)); } // Validate id if provided if (input.id && !this.isIdNumber(Number(input.id))) { warnings.push("Contact ID must be a positive integer"); } return warnings; },This would help standardize validation across different actions that operate on contacts.
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
⛔ Files ignored due to path filters (1)
pnpm-lock.yaml
is excluded by!**/pnpm-lock.yaml
📒 Files selected for processing (12)
components/drift/actions/create-contact/create-contact.mjs
(1 hunks)components/drift/actions/delete-contact/delete-contact.mjs
(1 hunks)components/drift/actions/get-contact/get-contact.mjs
(1 hunks)components/drift/actions/update-contact/update-contact.mjs
(1 hunks)components/drift/common/methods.mjs
(1 hunks)components/drift/common/utils.mjs
(1 hunks)components/drift/drift.app.mjs
(1 hunks)components/drift/package.json
(1 hunks)components/drift/sources/new-contact-update/new-contact-update.mjs
(1 hunks)components/drift/sources/new-conversation-instant/new-conversation-instant.mjs
(1 hunks)components/drift/sources/new-lead-instance.mjs/new-lead-instance.mjs
(1 hunks)components/drift/sources/new-message-instant/new-message-instant.mjs
(1 hunks)
🧰 Additional context used
🪛 Biome (1.9.4)
components/drift/common/utils.mjs
[error] 19-19: Avoid the use of spread (...
) syntax on accumulators.
Spread syntax should be avoided on accumulators (like those in .reduce
) because it causes a time complexity of O(n^2)
.
Consider methods such as .splice or .push instead.
(lint/performance/noAccumulatingSpread)
components/drift/drift.app.mjs
[error] 113-113: This code is unreachable
... because either this statement ...
... or this statement will throw an exception beforehand
(lint/correctness/noUnreachable)
⏰ Context from checks skipped due to timeout of 90000ms (3)
- GitHub Check: Verify TypeScript components
- GitHub Check: Publish TypeScript components
- GitHub Check: pnpm publish
🔇 Additional comments (4)
components/drift/package.json (1)
3-3
: Version increment looks appropriateThe package version has been properly incremented from 0.6.0 to 0.7.0, which aligns with the significant feature additions in this PR (new actions and sources for the Drift integration).
components/drift/actions/create-contact/create-contact.mjs (1)
45-52
: LGTM: Validation setup is well implementedThe email validation setup and warnings collection are well implemented.
components/drift/sources/new-message-instant/new-message-instant.mjs (1)
65-65
:❓ Verification inconclusive
Verify the ID field used for event deduplication.
You're using
body.data.endUserId
as the event ID, but this field may not exist in new_message events. Consider using the message ID if available.
🏁 Script executed:
#!/bin/bash # Check Drift webhook documentation to verify fields in new_message events curl -s https://devdocs.drift.com/docs/webhook-events-1 | grep -A 20 "new_message"Length of output: 102475
🏁 Script executed:
#!/bin/bash # Fetch and extract the JSON schema for the Message model from Drift docs curl -s https://devdocs.drift.com/docs/message-model \ | sed -n 's/"/"/g' \ | sed -n -n '/<code class="rdmd-code lang-json/,/<\/code>/p' \ | sed 's/<[^>]*>//g'Length of output: 160
Confirm Message payload ID field for deduplication
Please verify whether the
new_message
webhook’sdata
object actually includes anendUserId
field. The docs show thatdata
follows the Message model but don’t listendUserId
—you may need to fall back to the message’s unique ID instead.• Location: components/drift/sources/new-message-instant/new-message-instant.mjs:65
• Suggested change (after confirming available fields):- id: body.data.endUserId, + id: body.data.id || body.data.messageId,components/drift/sources/new-conversation-instant/new-conversation-instant.mjs (1)
84-85
: Ensure numeric sort when IDs are strings
a.id - b.id
givesNaN
ifid
is a string. Cast explicitly:-conversations.sort((a, b) => a.id - b.id); +conversations.sort((a, b) => Number(a.id) - Number(b.id));
components/drift/sources/new-lead-instance.mjs/new-lead-instance.mjs
Outdated
Show resolved
Hide resolved
components/drift/sources/new-lead-instance.mjs/new-lead-instance.mjs
Outdated
Show resolved
Hide resolved
components/drift/sources/new-message-instant/new-message-instant.mjs
Outdated
Show resolved
Hide resolved
components/drift/sources/new-message-instant/new-message-instant.mjs
Outdated
Show resolved
Hide resolved
components/drift/sources/new-conversation-instant/new-conversation-instant.mjs
Outdated
Show resolved
Hide resolved
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
♻️ Duplicate comments (2)
components/drift/drift.app.mjs (2)
45-46
: Add fallback error handling for missing OAuth tokenSimilar to the issue in the
_makeRequest
method, the OAuth token should have appropriate error handling here.- "Authorization": `Bearer ${this.$auth?.oauth_access_token}`, + "Authorization": `Bearer ${this.$auth?.oauth_access_token ?? (() => { + throw new Error("Drift OAuth access token is required"); + })()}`,
32-34
: 🛠️ Refactor suggestionAdd fallback error handling for missing OAuth token
The current implementation doesn't handle the case where
this.$auth?.oauth_access_token
is undefined. This could lead to silent failures with unclear error messages.- "Authorization": `Bearer ${this.$auth?.oauth_access_token}`, + "Authorization": `Bearer ${this.$auth?.oauth_access_token ?? (() => { + throw new Error("Drift OAuth access token is required"); + })()}`,
🧹 Nitpick comments (4)
components/drift/drift.app.mjs (4)
40-48
: Reduce duplication by leveraging existing_makeRequest
methodThe
getNextPage
method duplicates the authorization header logic that already exists in_makeRequest
. This could lead to inconsistencies if authentication requirements change.- getNextPage($, url) { - return axios($, { - method: "GET", - url, - headers: { - "Authorization": `Bearer ${this.$auth?.oauth_access_token}`, - }, - }); - }, + getNextPage($, url) { + return axios($, { + method: "GET", + url, + headers: { + "Authorization": `Bearer ${this.$auth?.oauth_access_token}`, + }, + }); + },Alternatively, you could modify
_makeRequest
to accept a full URL instead of constructing it from base URL and path, then use it for both cases.
124-127
: Remove unnecessary semicolonFor consistency with the rest of the codebase, remove the unnecessary semicolon after the closing brace.
if (!response?.data?.length) { throw new Error(`No contact found with email: ${email}`); - }; + }
133-134
: Fix typo in variable nameThe variable name "firtsNew" appears to be a typo for "firstNew".
- const firtsNew = arr.indexOf(lastKnown); - if (firtsNew === -1) throw new Error("Id not found"); + const firstNew = arr.indexOf(lastKnown); + if (firstNew === -1) throw new Error("Id not found");
8-138
: Add JSDoc documentation for improved code readabilityThe methods in this file lack documentation. Adding JSDoc comments would improve code clarity and maintainability, especially for other developers who might need to work with this code in the future.
For example, add documentation to the
getContactByEmailOrId
method:/** * Retrieves a contact by either email or ID * @param {Object} $ - Pipedream event object * @param {string|number} emailOrId - Either an email address or a contact ID * @returns {Promise<Object>} - The contact data * @throws {Error} If no contact is found or if there's an API error */ async getContactByEmailOrId($, emailOrId) { // Existing implementation }Consider adding similar documentation to all methods in this file.
🧰 Tools
🪛 Biome (1.9.4)
[error] 113-113: This code is unreachable
... because either this statement ...
... or this statement will throw an exception beforehand
(lint/correctness/noUnreachable)
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (6)
components/drift/actions/get-contact/get-contact.mjs
(1 hunks)components/drift/drift.app.mjs
(1 hunks)components/drift/sources/new-contact-update/new-contact-update.mjs
(1 hunks)components/drift/sources/new-conversation-instant/new-conversation-instant.mjs
(1 hunks)components/drift/sources/new-lead-instance.mjs/new-lead-instance.mjs
(1 hunks)components/drift/sources/new-message-instant/new-message-instant.mjs
(1 hunks)
🚧 Files skipped from review as they are similar to previous changes (5)
- components/drift/sources/new-lead-instance.mjs/new-lead-instance.mjs
- components/drift/sources/new-message-instant/new-message-instant.mjs
- components/drift/actions/get-contact/get-contact.mjs
- components/drift/sources/new-conversation-instant/new-conversation-instant.mjs
- components/drift/sources/new-contact-update/new-contact-update.mjs
🧰 Additional context used
🪛 Biome (1.9.4)
components/drift/drift.app.mjs
[error] 113-113: This code is unreachable
... because either this statement ...
... or this statement will throw an exception beforehand
(lint/correctness/noUnreachable)
⏰ Context from checks skipped due to timeout of 90000ms (3)
- GitHub Check: Verify TypeScript components
- GitHub Check: pnpm publish
- GitHub Check: Publish TypeScript components
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/drift/sources/new-lead-instance/new-lead-instance.mjs (2)
3-12
: Component setup looks good but consider adding webhook setup instructionsThe component is well-structured with appropriate key, name, and description. The document link is helpful for reference.
However, since this is a webhook-based source, consider adding setup instructions either in the description or as a separate
hooks
section to guide users on how to configure the webhook in Drift.
32-36
: Update the summary message for consistencyThe summary message indicates an update ("Contact X updated"), but this component is designed to trigger when a new lead adds their email in chat (as stated in the description).
this.$emit(body, { - summary: `Contact "${email}" ID "${contactId}" updated`, + summary: `New lead identified: "${email}" (ID: "${contactId}")`, id: body.data.endUserId, ts: body.timeStamp, });
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (1)
components/drift/sources/new-lead-instance/new-lead-instance.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 (1)
components/drift/sources/new-lead-instance/new-lead-instance.mjs (1)
17-20
: Good event filtering logicThe event filtering logic is clear and appropriately logs and ignores non-relevant events.
components/drift/sources/new-lead-instance/new-lead-instance.mjs
Outdated
Show resolved
Hide resolved
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 (2)
components/drift/drift.app.mjs (2)
107-118
: Remove unnecessary semicolonsThere are unnecessary semicolons at the end of blocks that should be removed for consistency.
if (!response?.data?.length) { throw new Error(`No contact found with email: ${email}`); - }; - }; + } + }
123-128
: Fix typo in variable nameThere's a typo in the variable name at line 124 -
firtsNew
should befirstNew
.- const firtsNew = arr.indexOf(lastKnown); + const firstNew = arr.indexOf(lastKnown); if (firtsNew === -1) throw new Error("Id not found"); - const newest = arr.slice(0, firtsNew); + const newest = arr.slice(0, firstNew); return newest.reverse();
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (9)
components/drift/actions/create-contact/create-contact.mjs
(1 hunks)components/drift/actions/delete-contact/delete-contact.mjs
(1 hunks)components/drift/actions/get-contact/get-contact.mjs
(1 hunks)components/drift/actions/update-contact/update-contact.mjs
(1 hunks)components/drift/drift.app.mjs
(1 hunks)components/drift/sources/new-contact-update/new-contact-update.mjs
(1 hunks)components/drift/sources/new-conversation-instant/new-conversation-instant.mjs
(1 hunks)components/drift/sources/new-lead-instance/new-lead-instance.mjs
(1 hunks)components/drift/sources/new-message-instant/new-message-instant.mjs
(1 hunks)
🚧 Files skipped from review as they are similar to previous changes (8)
- components/drift/sources/new-message-instant/new-message-instant.mjs
- components/drift/actions/update-contact/update-contact.mjs
- components/drift/actions/create-contact/create-contact.mjs
- components/drift/actions/get-contact/get-contact.mjs
- components/drift/sources/new-contact-update/new-contact-update.mjs
- components/drift/actions/delete-contact/delete-contact.mjs
- components/drift/sources/new-lead-instance/new-lead-instance.mjs
- components/drift/sources/new-conversation-instant/new-conversation-instant.mjs
⏰ Context from checks skipped due to timeout of 90000ms (4)
- GitHub Check: Verify TypeScript components
- GitHub Check: pnpm publish
- GitHub Check: Publish TypeScript components
- GitHub Check: Lint Code Base
🔇 Additional comments (6)
components/drift/drift.app.mjs (6)
8-29
: HTTP request method implementation looks goodThe
_baseUrl()
and_makeRequest()
methods follow best practices for Pipedream apps with proper authorization header handling and flexible parameter passing.
31-39
: Well-structured pagination supportThe
getNextPage()
method properly implements pagination support for the Drift API, maintaining authorization headers consistency.
41-84
: CRUD operations for contacts are well-implementedAll contact management methods (getContactByEmail, createContact, updateContact, getContactById, deleteContactById) follow a consistent pattern with appropriate HTTP methods and paths.
90-105
: Good error handling for contact lookup by IDThe error handling for contact lookup by ID is well-implemented with specific error messages for 404 responses.
129-141
: Well-implemented JSON parsing utilityThe
parseIfJSONString
method safely handles JSON parsing with proper error handling, returning the original input if parsing fails.
142-144
: Simple and effective ID validation methodThe
isIdNumber
method provides a clean way to validate if an input is a positive integer ID.
Fixes #13240
Actions:
create-contact
delete-contact
get-contact
update-contact
Sources:
new-contact-update
new-conversation-instant
new-lead-instance
new-message-instant
Notes:
This task is over a year old. Since then, the Drift API has changed.
There is no longer a create-or-update endpoint — now create and update are separate actions.
Regarding new-lead-instant:
Drift does not support listing contacts — only fetching them by known ID or email.
However, their API now supports webhooks. So I implemented this source using webhooks instead of polling. Unfortunately, there's no "new contact" webhook event available.
To work around this, I created two sources:
new-lead-instance: Emits an event when a contact adds their email in chat.
new-contact-update: Emits an event when a contact is updated.
Polling vs Webhooks:
new-conversation-instant is currently implemented as a polling source.
If needed, I can rewrite it to use webhooks instead.
Summary by CodeRabbit