-
Notifications
You must be signed in to change notification settings - Fork 5.5k
New Components - lawmatics #18271
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 - lawmatics #18271
Conversation
|
The latest updates on your projects. Learn more about Vercel for GitHub. 2 Skipped Deployments
|
WalkthroughAdds Lawmatics integration: create/update contact actions, a poll-based "new contact added" source, a parseObject utility, expanded app propDefinitions and HTTP helper methods (including pagination), and a package version/dependency bump. Changes
Sequence Diagram(s)sequenceDiagram
autonumber
actor User
participant CreateAction as Action: Create Contact
participant App as Lawmatics App
participant API as Lawmatics API
User->>CreateAction: Provide firstName, lastName, email, phone, notes
CreateAction->>App: createContact({ first_name, last_name, email, phone, notes* })
note right of CreateAction: *notes parsed via parseObject
App->>API: POST /contacts (JSON payload)
API-->>App: 201 Created (contact data)
App-->>CreateAction: contact data
CreateAction-->>User: Summary: "Successfully created contact: {id}"
sequenceDiagram
autonumber
actor User
participant UpdateAction as Action: Update Contact
participant App as Lawmatics App
participant API as Lawmatics API
User->>UpdateAction: Provide contactId and updated fields
UpdateAction->>App: updateContact({ contactId, data })
App->>API: PUT /contacts/{contactId}
API-->>App: 200 OK (updated contact)
App-->>UpdateAction: contact data
UpdateAction-->>User: Summary: "Successfully updated contact: {id}"
sequenceDiagram
autonumber
participant Timer as Timer
participant Source as Source: New Contact Added
participant App as Lawmatics App
participant API as Lawmatics API
participant DB as Source DB
Timer->>Source: run() / deploy()
Source->>DB: read lastTs
loop paginate (created_at desc)
Source->>App: listContacts({ page })
App->>API: GET /contacts
API-->>App: contacts page
App-->>Source: contacts[]
alt contact.created_at > lastTs
Source-->>Source: generateMeta(contact)
Source-->>Source: track newLastTs (first new)
Source-->>Timer: emit(contact, meta)
else old or equal
Source-->>Source: break loop
end
end
Source->>DB: write newLastTs (if any)
Estimated code review effort🎯 4 (Complex) | ⏱️ ~60 minutes Assessment against linked issues
Poem
✨ Finishing Touches
🧪 Generate unit tests
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. CodeRabbit Commands (Invoked using PR/Issue comments)Type Other keywords and placeholders
CodeRabbit Configuration File (
|
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: 6
🧹 Nitpick comments (6)
components/lawmatics/lawmatics.app.mjs (3)
11-27: Consider more robust contact label generationThe label construction could result in awkward spacing if firstName or lastName is missing but email exists. Consider filtering out falsy values before joining.
- label: `${firstName} ${lastName} ${email}`.trim() || value, + label: [firstName, lastName, email].filter(Boolean).join(' ') || value,
53-53: Fix typo and clarify JSON format in notes descriptionThe description contains "Example:" but should show valid JSON format for clarity.
- description: "An array of notes for the contact. Each note is an object with properties `name` and `body`. Example: `[{ name: 'Note 1', body: 'This is a note' }, { name: 'Note 2', body: 'This is another note' }]`", + description: "An array of notes for the contact. Each note is an object with properties `name` and `body`. Example: `[{ \"name\": \"Note 1\", \"body\": \"This is a note\" }, { \"name\": \"Note 2\", \"body\": \"This is another note\" }]`",
85-93: HTTP method should be uppercase for consistencyWhile lowercase HTTP methods work with axios, uppercase is the standard convention.
updateContact({ contactId, ...opts }) { return this._makeRequest({ path: `/contacts/${contactId}`, - method: "put", + method: "PUT", ...opts, }); },Also apply to the createContact method:
createContact(opts = {}) { return this._makeRequest({ path: "/contacts", - method: "post", + method: "POST", ...opts, }); },components/lawmatics/sources/new-contact-added/new-contact-added.mjs (1)
30-30: Improve contact summary generation to handle missing fieldsSimilar to the app file, the summary generation could produce awkward results when some fields are missing.
- summary: `${contact.attributes.first_name} ${contact.attributes.last_name} ${contact.attributes.email}`.trim() || contact.id, + summary: [contact.attributes.first_name, contact.attributes.last_name, contact.attributes.email].filter(Boolean).join(' ') || contact.id,components/lawmatics/actions/create-contact/create-contact.mjs (1)
46-53: Build payload dynamically to avoid sending undefineds.Some APIs reject fields explicitly set to undefined; better to omit them.
Apply:
- const { data } = await this.lawmatics.createContact({ - $, - data: { - first_name: this.firstName, - last_name: this.lastName, - email: this.email, - phone: this.phone, - notes: parseObject(this.notes), - }, - }); + const payload = { + first_name: this.firstName, + last_name: this.lastName, + email: this.email, + phone: this.phone, + notes: parseObject(this.notes), + }; + Object.keys(payload).forEach((k) => payload[k] === undefined && delete payload[k]); + const { data } = await this.lawmatics.createContact({ $, data: payload });components/lawmatics/actions/update-contact/update-contact.mjs (1)
50-60: Also omit undefineds in update payload to prevent accidental field clearing.Many CRMs interpret explicit null/undefined as “clear this field.”
Apply:
- const { data } = await this.lawmatics.updateContact({ - $, - contactId: this.contactId, - data: { - first_name: this.firstName, - last_name: this.lastName, - email: this.email, - phone: this.phone, - notes: parseObject(this.notes), - }, - }); + const payload = { + first_name: this.firstName, + last_name: this.lastName, + email: this.email, + phone: this.phone, + notes: parseObject(this.notes), + }; + Object.keys(payload).forEach((k) => payload[k] === undefined && delete payload[k]); + const { data } = await this.lawmatics.updateContact({ + $, + contactId: this.contactId, + data: payload, + });
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
💡 Knowledge Base configuration:
- MCP integration is disabled by default for public repositories
- Jira integration is disabled by default for public repositories
- Linear integration is disabled by default for public repositories
You can enable these sources in your CodeRabbit configuration.
⛔ Files ignored due to path filters (1)
pnpm-lock.yamlis excluded by!**/pnpm-lock.yaml
📒 Files selected for processing (6)
components/lawmatics/actions/create-contact/create-contact.mjs(1 hunks)components/lawmatics/actions/update-contact/update-contact.mjs(1 hunks)components/lawmatics/common/utils.mjs(1 hunks)components/lawmatics/lawmatics.app.mjs(1 hunks)components/lawmatics/package.json(2 hunks)components/lawmatics/sources/new-contact-added/new-contact-added.mjs(1 hunks)
🧰 Additional context used
🧬 Code graph analysis (3)
components/lawmatics/common/utils.mjs (2)
components/lawmatics/actions/create-contact/create-contact.mjs (1)
parseObject(44-53)components/lawmatics/actions/update-contact/update-contact.mjs (1)
parseObject(50-60)
components/lawmatics/actions/create-contact/create-contact.mjs (2)
components/lawmatics/actions/update-contact/update-contact.mjs (1)
parseObject(50-60)components/lawmatics/common/utils.mjs (2)
parseObject(1-27)parseObject(1-27)
components/lawmatics/actions/update-contact/update-contact.mjs (2)
components/lawmatics/actions/create-contact/create-contact.mjs (1)
parseObject(44-53)components/lawmatics/common/utils.mjs (2)
parseObject(1-27)parseObject(1-27)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (4)
- GitHub Check: pnpm publish
- GitHub Check: Verify TypeScript components
- GitHub Check: Publish TypeScript components
- GitHub Check: Lint Code Base
🔇 Additional comments (6)
components/lawmatics/package.json (1)
3-3: Version bump looks appropriate for new featuresThe version bump from 0.6.0 to 0.7.0 and the @pipedream/platform dependency update to ^3.1.0 are appropriate for adding new components and leveraging axios functionality.
Also applies to: 16-16
components/lawmatics/sources/new-contact-added/new-contact-added.mjs (1)
47-55: Verify and normalize Lawmaticscreated_attimestamps
Ensure the API returnscontact.attributes.created_atas a UTC-offset ISO 8601 string (e.g. ending in “Z”); if it omits the timezone, explicitly normalize to UTC (for example, append “Z” before callingDate.parse) to avoid local-timezone parsing discrepancies.components/lawmatics/common/utils.mjs (1)
12-14: LGTM: non‑mutating deep map for arrays.components/lawmatics/actions/create-contact/create-contact.mjs (1)
4-42: Props wiring looks consistent with app propDefinitions.components/lawmatics/actions/update-contact/update-contact.mjs (2)
10-48: Props are consistent; contactId presence handled by propDefinition.
61-62: Verify update response includesid. Ensurelawmatics.updateContactreturns a defineddata.id(or adjust to the actual property path) before using it in$summary.
GTFalcao
left a 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.
LGTM!
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 (1)
components/lawmatics/lawmatics.app.mjs (1)
90-111: Fix pagination: metadata read from response, not data array
data?.meta?.total_pagesis incorrect sincedatais the items array. Readmetafrom the response.Apply this diff:
- const { data } = await fn({ - params, - }); + const { data, meta } = await fn({ params }); @@ - totalPages = data?.meta?.total_pages; + totalPages = meta?.total_pages ?? totalPages ?? 1; params.page++; } while (params.page <= totalPages);
🧹 Nitpick comments (2)
components/lawmatics/lawmatics.app.mjs (2)
11-22: Safer option labels: fall back when email is missingSome contacts may lack email; add a fallback to name or id to avoid blank labels.
Apply this diff:
- return data.map(({ - id: value, attributes: { email }, - }) => ({ - value, - label: email, - })); + return data.map(({ + id: value, attributes: { email, first_name, last_name }, + }) => ({ + value, + label: email || [first_name, last_name].filter(Boolean).join(" ") || String(value), + }));
60-66: Add a client timeout to avoid hanging requestsSet a sensible timeout to fail fast on network issues.
Apply this diff:
return axios($, { url: `${this._baseUrl()}${path}`, headers: { Authorization: `Bearer ${this.$auth.oauth_access_token}`, }, + timeout: 10000, ...opts, });
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
💡 Knowledge Base configuration:
- MCP integration is disabled by default for public repositories
- Jira integration is disabled by default for public repositories
- Linear integration is disabled by default for public repositories
You can enable these sources in your CodeRabbit configuration.
📒 Files selected for processing (1)
components/lawmatics/lawmatics.app.mjs(1 hunks)
🧰 Additional context used
🧠 Learnings (1)
📚 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/lawmatics/lawmatics.app.mjs
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (4)
- GitHub Check: Lint Code Base
- GitHub Check: pnpm publish
- GitHub Check: Verify TypeScript components
- GitHub Check: Publish TypeScript components
🔇 Additional comments (5)
components/lawmatics/lawmatics.app.mjs (5)
1-1: LGTM on axios importImporting axios from @pipedream/platform is correct for authenticated requests via
$.
57-67: Authorization token usage is correct
Pipedream’s Lawmatics app uses OAuth2 and exposes the access token as$auth.oauth_access_token, so the existing header code is valid.
74-80: Use flat JSON payload for createContact
Lawmatics’ Contacts endpoint accepts a plain JSON object with contact properties (e.g., firstName, lastName, email)—nodata.type/data.attributesenvelope.Likely an incorrect or invalid review comment.
81-89: Confirmed correct use of PUT
The Lawmatics API supports a PUT request to/v1/contacts/{id}for updating contacts, so no change to PATCH is needed.
68-73: Confirm pagination parameters for GET /v1/contacts
GET /v1/contacts is correct (help.lawmatics.com); verify supported pagination query parameters (e.g. page, per_page/limit or page[size]) and update opts to include the appropriate params for consistent paging. Ensure the client handles the actual JSON response envelope and metadata shape.
|
/approve |
Resolves #17906
Summary by CodeRabbit
New Features
Chores