Skip to content

Conversation

@jcortes
Copy link
Collaborator

@jcortes jcortes commented Nov 11, 2025

WHY

Resolves #18894

Summary by CodeRabbit

  • New Features

    • LinkedIn: profile & company search with filters and limits; fetch profile, company, conversations, and messages
    • Connection tools: send connection requests, send messages, check invitation status
    • Authentication flows: login, verify code, and token-based calls
    • Dynamic conversation selection and improved multi-value input handling
  • Chores

    • Component version bumped and platform integration updated

@jcortes jcortes self-assigned this Nov 11, 2025
@vercel
Copy link

vercel bot commented Nov 11, 2025

The latest updates on your projects. Learn more about Vercel for GitHub.

2 Skipped Deployments
Project Deployment Preview Comments Updated (UTC)
pipedream-docs Ignored Ignored Nov 14, 2025 3:43pm
pipedream-docs-redirect-do-not-edit Ignored Ignored Nov 14, 2025 3:43pm

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Nov 11, 2025

Walkthrough

Adds a LinkUp API integration: new app component with an Axios HTTP wrapper, expanded propDefinitions and public methods, a small utils module, package bump, and ten new action modules for authentication, profile/company lookup, search, messaging, conversations, invitations, and connection requests.

Changes

Cohort / File(s) Summary
App config & core utils
components/linkupapi/linkupapi.app.mjs, components/linkupapi/package.json, components/linkupapi/common/utils.mjs
New Axios-based HTTP helpers and centralized request methods (getUrl, _getHeaders, _makeRequest, post) plus many app methods (login, verify, getProfileInfo, searchProfiles, searchCompanies, getCompanyInfo, connectToProfile, getInvitationsStatus, sendMessage, getConversationMessages, getConversations). Expanded propDefinitions (email, password, country, loginToken, code, linkedinUrl, conversationId with async options, messageText, location, companyUrl). Added getOptionalProp util. Bumped package version to 0.1.0 and added @pipedream/platform dependency.
Authentication actions
components/linkupapi/actions/login/login.mjs, components/linkupapi/actions/verify-code/verify-code.mjs
New actions linkupapi-login and linkupapi-verify-code that call app.login and app.verify respectively, export success summaries, and return API responses.
Profile & company info / search
components/linkupapi/actions/get-profile-info/get-profile-info.mjs, components/linkupapi/actions/get-company-info/get-company-info.mjs, components/linkupapi/actions/search-profiles/search-profiles.mjs, components/linkupapi/actions/search-companies/search-companies.mjs
New actions to fetch profile/company info and search profiles/companies. Each maps action props to snake_case payloads, delegates to corresponding app.* methods, exports summaries, and supports optional parameters.
Networking actions
components/linkupapi/actions/connect-to-profile/connect-to-profile.mjs, components/linkupapi/actions/get-invitations-status/get-invitations-status.mjs
New actions for sending connection requests and checking invitation status; both call app.* methods with mapped payloads, export summaries, and return responses.
Messaging & conversations
components/linkupapi/actions/send-message/send-message.mjs, components/linkupapi/actions/get-conversation-messages/get-conversation-messages.mjs
New actions to send messages and retrieve conversation messages. They validate inputs (e.g., linkedinUrl or conversationId), map fields to API payloads, call app.sendMessage / app.getConversationMessages, export summaries, and return responses.

Sequence Diagram(s)

sequenceDiagram
    participant User
    participant Action
    participant App
    participant LinkUpAPI

    User->>Action: Trigger action with props
    activate Action
    Action->>Action: Read/destructure props
    Action->>App: app.<method>({ $, data: {...} })
    activate App
    App->>App: Build URL & headers (_getHeaders)
    App->>LinkUpAPI: HTTP POST with snake_case payload
    activate LinkUpAPI
    LinkUpAPI-->>App: Return response
    deactivate LinkUpAPI
    App-->>Action: Return response
    deactivate App
    Action->>Action: $.export("$summary","...")
    Action-->>User: Return response
    deactivate Action
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

  • Areas to focus review on:
    • components/linkupapi/linkupapi.app.mjs — header construction, request flow, error handling, and URL assembly.
    • conversationId async options and pagination in propDefinitions.
    • Consistency of snake_case payload mappings across actions vs API docs.
    • Input validation and error handling in get-conversation-messages and send-message.
    • components/linkupapi/common/utils.mjs — behavior of getOptionalProp with arrays.

Suggested labels

User submitted

Suggested reviewers

  • lcaresia

Pre-merge checks and finishing touches

❌ Failed checks (2 warnings)
Check name Status Explanation Resolution
Description check ⚠️ Warning The PR description is incomplete; it only contains 'Resolves #18894' without explaining the WHY section or providing context about the changes. Expand the description to explain why these new Linkup API components are being added and what functionality they provide.
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
✅ Passed checks (3 passed)
Check name Status Explanation
Title check ✅ Passed The PR title '[Components] linkup api - new components' directly describes the main change: adding new Linkup API components to the system.
Linked Issues check ✅ Passed The PR successfully implements all required functionality for issue #18894: comprehensive Linkup API support including authentication (login, verify), profile operations (get profile info, search profiles, connect to profile), messaging (send message, get conversation messages), company operations (search companies, get company info), and utility functions.
Out of Scope Changes check ✅ Passed All changes are directly aligned with the objective of adding Linkup API components; no out-of-scope modifications detected. The package version bump and dependency addition are appropriate for releasing new components.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch linkupapi-new-components

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 3

📜 Review details

Configuration used: CodeRabbit UI

Review profile: ASSERTIVE

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between a6d21f7 and d719bcf.

⛔ Files ignored due to path filters (1)
  • pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml
📒 Files selected for processing (13)
  • components/linkupapi/actions/connect-to-profile/connect-to-profile.mjs (1 hunks)
  • components/linkupapi/actions/get-company-info/get-company-info.mjs (1 hunks)
  • components/linkupapi/actions/get-conversation-messages/get-conversation-messages.mjs (1 hunks)
  • components/linkupapi/actions/get-invitations-status/get-invitations-status.mjs (1 hunks)
  • components/linkupapi/actions/get-profile-info/get-profile-info.mjs (1 hunks)
  • components/linkupapi/actions/login/login.mjs (1 hunks)
  • components/linkupapi/actions/search-companies/search-companies.mjs (1 hunks)
  • components/linkupapi/actions/search-profiles/search-profiles.mjs (1 hunks)
  • components/linkupapi/actions/send-message/send-message.mjs (1 hunks)
  • components/linkupapi/actions/verify-code/verify-code.mjs (1 hunks)
  • components/linkupapi/common/utils.mjs (1 hunks)
  • components/linkupapi/linkupapi.app.mjs (1 hunks)
  • components/linkupapi/package.json (2 hunks)
🧰 Additional context used
🧠 Learnings (5)
📚 Learning: 2024-12-12T19:23:09.039Z
Learnt from: jcortes
Repo: PipedreamHQ/pipedream PR: 14935
File: components/sailpoint/package.json:15-18
Timestamp: 2024-12-12T19:23:09.039Z
Learning: When developing Pipedream components, do not add built-in Node.js modules like `fs` to `package.json` dependencies, as they are native modules provided by the Node.js runtime.

Applied to files:

  • components/linkupapi/package.json
📚 Learning: 2024-10-08T15:33:38.240Z
Learnt from: GTFalcao
Repo: PipedreamHQ/pipedream PR: 12731
File: components/hackerone/actions/get-members/get-members.mjs:3-28
Timestamp: 2024-10-08T15:33:38.240Z
Learning: When exporting a summary message in the `run` method of an action, ensure the message is correctly formatted. For example, in the `hackerone-get-members` action, the correct format is `Successfully retrieved ${response.data.length} members`.

Applied to files:

  • components/linkupapi/actions/send-message/send-message.mjs
  • components/linkupapi/actions/get-conversation-messages/get-conversation-messages.mjs
  • components/linkupapi/actions/get-invitations-status/get-invitations-status.mjs
📚 Learning: 2025-10-20T01:01:02.970Z
Learnt from: js07
Repo: PipedreamHQ/pipedream PR: 18744
File: components/slack_v2/actions/send-large-message/send-large-message.mjs:49-64
Timestamp: 2025-10-20T01:01:02.970Z
Learning: In components/slack_v2/actions/send-large-message/send-large-message.mjs, the metadata_event_payload prop is typed as string, so the code only needs to handle string-to-JSON parsing and does not need to handle object inputs.

Applied to files:

  • components/linkupapi/actions/send-message/send-message.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/linkupapi/linkupapi.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/linkupapi/linkupapi.app.mjs
🧬 Code graph analysis (10)
components/linkupapi/actions/login/login.mjs (1)
components/linkupapi/actions/verify-code/verify-code.mjs (1)
  • response (44-51)
components/linkupapi/actions/get-profile-info/get-profile-info.mjs (6)
components/linkupapi/actions/connect-to-profile/connect-to-profile.mjs (1)
  • response (51-59)
components/linkupapi/actions/get-company-info/get-company-info.mjs (1)
  • response (44-51)
components/linkupapi/actions/get-conversation-messages/get-conversation-messages.mjs (1)
  • response (81-90)
components/linkupapi/actions/get-invitations-status/get-invitations-status.mjs (1)
  • response (44-51)
components/linkupapi/actions/search-profiles/search-profiles.mjs (1)
  • response (123-139)
components/linkupapi/actions/send-message/send-message.mjs (1)
  • response (51-59)
components/linkupapi/actions/search-companies/search-companies.mjs (2)
components/linkupapi/actions/get-conversation-messages/get-conversation-messages.mjs (1)
  • response (81-90)
components/linkupapi/actions/search-profiles/search-profiles.mjs (1)
  • response (123-139)
components/linkupapi/actions/connect-to-profile/connect-to-profile.mjs (4)
components/linkupapi/actions/get-company-info/get-company-info.mjs (1)
  • response (44-51)
components/linkupapi/actions/get-invitations-status/get-invitations-status.mjs (1)
  • response (44-51)
components/linkupapi/actions/get-profile-info/get-profile-info.mjs (1)
  • response (44-51)
components/linkupapi/actions/send-message/send-message.mjs (1)
  • response (51-59)
components/linkupapi/actions/get-company-info/get-company-info.mjs (3)
components/linkupapi/actions/get-profile-info/get-profile-info.mjs (1)
  • response (44-51)
components/linkupapi/actions/search-companies/search-companies.mjs (1)
  • response (83-94)
components/linkupapi/actions/search-profiles/search-profiles.mjs (1)
  • response (123-139)
components/linkupapi/actions/send-message/send-message.mjs (1)
components/linkupapi/actions/connect-to-profile/connect-to-profile.mjs (1)
  • response (51-59)
components/linkupapi/actions/get-conversation-messages/get-conversation-messages.mjs (1)
components/linkupapi/actions/search-companies/search-companies.mjs (1)
  • response (83-94)
components/linkupapi/actions/get-invitations-status/get-invitations-status.mjs (3)
components/linkupapi/actions/connect-to-profile/connect-to-profile.mjs (1)
  • response (51-59)
components/linkupapi/actions/get-profile-info/get-profile-info.mjs (1)
  • response (44-51)
components/linkupapi/actions/send-message/send-message.mjs (1)
  • response (51-59)
components/linkupapi/actions/verify-code/verify-code.mjs (1)
components/linkupapi/actions/login/login.mjs (1)
  • response (43-50)
components/linkupapi/actions/search-profiles/search-profiles.mjs (1)
components/linkupapi/actions/search-companies/search-companies.mjs (1)
  • response (83-94)
⏰ 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: Publish TypeScript components
  • GitHub Check: Verify TypeScript components
  • GitHub Check: Lint Code Base
  • GitHub Check: pnpm publish
🔇 Additional comments (16)
components/linkupapi/package.json (1)

3-16: LGTM!

The version bump to 0.1.0 and the addition of the @pipedream/platform dependency are appropriate for this new integration.

components/linkupapi/common/utils.mjs (1)

1-9: LGTM!

The utility function correctly handles optional array properties by joining non-empty arrays with a separator or returning undefined. This aligns with the API payload requirements for actions like search-profiles and search-companies.

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

108-196: LGTM!

The HTTP helper methods and API endpoint wrappers follow Pipedream conventions. The consistent pattern of delegating to post with appropriate paths makes the code maintainable and easy to extend.

components/linkupapi/actions/login/login.mjs (1)

1-56: LGTM!

The login action correctly maps props to the API payload and follows Pipedream action conventions. The annotations appropriately reflect that this is a non-destructive, outbound operation.

components/linkupapi/actions/get-profile-info/get-profile-info.mjs (1)

1-57: LGTM!

The action correctly retrieves profile information with proper field mapping to the API's snake_case convention. The annotations appropriately indicate this is a read-only, idempotent operation.

components/linkupapi/actions/get-conversation-messages/get-conversation-messages.mjs (1)

77-79: LGTM!

The validation correctly ensures at least one identifier (LinkedIn URL or Conversation ID) is provided, using the appropriate ConfigurationError from the platform.

components/linkupapi/actions/get-company-info/get-company-info.mjs (1)

11-16: Verify if companyUrl should be required.

The companyUrl prop is marked as optional: true, but the API likely requires it to retrieve company information. Without validation, users may encounter cryptic API errors.

Compare with similar actions (e.g., get-profile-info requires linkedinUrl) and verify the API documentation. If required, apply this diff:

     companyUrl: {
       type: "string",
       label: "Company URL",
       description: "LinkedIn company URLs. Eg. `https://www.linkedin.com/company/stripe/`",
-      optional: true,
     },

Alternatively, add validation in the run method if it truly is optional.

components/linkupapi/actions/verify-code/verify-code.mjs (1)

1-57: LGTM!

The verify-code action correctly implements the verification flow with appropriate props and annotations. The idempotentHint: false correctly indicates that code verification may have side effects.

components/linkupapi/actions/send-message/send-message.mjs (2)

3-35: LGTM!

The action metadata and prop definitions are well-structured and consistent with Pipedream patterns. All props correctly reference propDefinitions from the app module.


42-64: LGTM!

The run method correctly maps input props to the API payload format and returns the response. The implementation is clean and follows the established pattern.

components/linkupapi/actions/search-companies/search-companies.mjs (2)

4-71: LGTM!

The action metadata is well-structured with clear prop definitions. The companySize options are well-defined and match the LinkedIn company size ranges.


83-94: Verify the sector parameter separator against LinkUp API documentation.

The inconsistency identified is real: network in search-profiles uses utils.getOptionalProp(network, ",") with a comma separator, while sector in search-companies uses utils.getOptionalProp(sector) with the default semicolon separator. Both are string[] types.

Check the LinkUp API documentation for the /companies/search endpoint to confirm whether the sector parameter expects comma-separated values (matching network) or semicolon-separated values (current implementation).

components/linkupapi/actions/connect-to-profile/connect-to-profile.mjs (1)

3-64: LGTM!

The action is well-structured with appropriate annotations for a connection request operation (destructive, non-idempotent). The optional message prop is correctly mapped to message_text in the API payload.

components/linkupapi/actions/search-profiles/search-profiles.mjs (2)

10-99: LGTM!

The props are well-defined with clear descriptions. The network prop options are particularly well-structured with descriptive labels for LinkedIn connection levels.


106-143: LGTM!

The run method correctly maps all search parameters to the API payload format. The use of utils.getOptionalProp for array parameters is appropriate, with the network parameter specifically using a comma separator as required by the API.

components/linkupapi/actions/get-invitations-status/get-invitations-status.mjs (1)

3-56: LGTM!

The action is well-structured with appropriate annotations for a read-only status check operation. The annotations correctly indicate this is a non-destructive, idempotent operation.

@jcortes jcortes force-pushed the linkupapi-new-components branch from d719bcf to 3e68d23 Compare November 11, 2025 21:01
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 2

♻️ Duplicate comments (1)
components/linkupapi/linkupapi.app.mjs (1)

63-85: Harden conversation dropdown against missing fields

last_message and participant aren’t guaranteed to be present on every conversation (e.g., newly created threads or system items). The current destructuring will throw when either object is missing, which breaks the prop options loader. The docs show next_cursor may be null and conversations can be paginated, so we should default and guard against absent metadata.

-        const {
-          data: {
-            conversations,
-            next_cursor,
-          },
-        } = await this.getConversations({
+        const {
+          data: {
+            conversations = [],
+            next_cursor = null,
+          } = {},
+        } = await this.getConversations({
           data: {
             login_token: loginToken,
             next_cursor: prevContext?.nextCursor,
           },
         });
-        return {
-          options: conversations.map(({
-            conversation_id: value,
-            last_message: { text },
-            participant: { name },
-          }) => ({
-            label: `${name || "Unknown"} - ${text?.substring(0, 50) || "No message"}`,
-            value,
-          })),
-          context: {
-            nextCursor: next_cursor,
-          },
-        };
+        return {
+          options: conversations
+            .map((conversation = {}) => {
+              const value = conversation.conversation_id;
+              if (!value) return null;
+
+              const text = conversation.last_message?.text ?? "";
+              const name = conversation.participant?.name ?? "Unknown";
+
+              return {
+                label: `${name} - ${text ? text.substring(0, 50) : "No message"}`,
+                value,
+              };
+            })
+            .filter(Boolean),
+          context: {
+            nextCursor: next_cursor,
+          },
+        };
📜 Review details

Configuration used: CodeRabbit UI

Review profile: ASSERTIVE

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between d719bcf and 3e68d23.

⛔ Files ignored due to path filters (1)
  • pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml
📒 Files selected for processing (13)
  • components/linkupapi/actions/connect-to-profile/connect-to-profile.mjs (1 hunks)
  • components/linkupapi/actions/get-company-info/get-company-info.mjs (1 hunks)
  • components/linkupapi/actions/get-conversation-messages/get-conversation-messages.mjs (1 hunks)
  • components/linkupapi/actions/get-invitations-status/get-invitations-status.mjs (1 hunks)
  • components/linkupapi/actions/get-profile-info/get-profile-info.mjs (1 hunks)
  • components/linkupapi/actions/login/login.mjs (1 hunks)
  • components/linkupapi/actions/search-companies/search-companies.mjs (1 hunks)
  • components/linkupapi/actions/search-profiles/search-profiles.mjs (1 hunks)
  • components/linkupapi/actions/send-message/send-message.mjs (1 hunks)
  • components/linkupapi/actions/verify-code/verify-code.mjs (1 hunks)
  • components/linkupapi/common/utils.mjs (1 hunks)
  • components/linkupapi/linkupapi.app.mjs (1 hunks)
  • components/linkupapi/package.json (2 hunks)
🧰 Additional context used
🧠 Learnings (6)
📚 Learning: 2024-07-04T18:11:59.822Z
Learnt from: GTFalcao
Repo: PipedreamHQ/pipedream PR: 12731
File: components/hackerone/actions/get-members/get-members.mjs:3-28
Timestamp: 2024-07-04T18:11:59.822Z
Learning: When exporting a summary message in the `run` method of an action, ensure the message is correctly formatted. For example, in the `hackerone-get-members` action, the correct format is `Successfully retrieved ${response.data.length} members`.

Applied to files:

  • components/linkupapi/actions/send-message/send-message.mjs
  • components/linkupapi/actions/get-invitations-status/get-invitations-status.mjs
  • components/linkupapi/actions/get-conversation-messages/get-conversation-messages.mjs
📚 Learning: 2025-10-20T01:01:02.970Z
Learnt from: js07
Repo: PipedreamHQ/pipedream PR: 18744
File: components/slack_v2/actions/send-large-message/send-large-message.mjs:49-64
Timestamp: 2025-10-20T01:01:02.970Z
Learning: In components/slack_v2/actions/send-large-message/send-large-message.mjs, the metadata_event_payload prop is typed as string, so the code only needs to handle string-to-JSON parsing and does not need to handle object inputs.

Applied to files:

  • components/linkupapi/actions/send-message/send-message.mjs
📚 Learning: 2024-12-12T19:23:09.039Z
Learnt from: jcortes
Repo: PipedreamHQ/pipedream PR: 14935
File: components/sailpoint/package.json:15-18
Timestamp: 2024-12-12T19:23:09.039Z
Learning: When developing Pipedream components, do not add built-in Node.js modules like `fs` to `package.json` dependencies, as they are native modules provided by the Node.js runtime.

Applied to files:

  • components/linkupapi/package.json
📚 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/linkupapi/linkupapi.app.mjs
📚 Learning: 2025-09-12T07:49:36.125Z
Learnt from: matyascimbulka
Repo: PipedreamHQ/pipedream PR: 18308
File: components/apify/actions/run-task-synchronously/run-task-synchronously.mjs:70-0
Timestamp: 2025-09-12T07:49:36.125Z
Learning: The Apify Task object always contains the `options` field according to the official API documentation, making nested destructuring like `options: { build }` safe to use without additional checks.

Applied to files:

  • components/linkupapi/linkupapi.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/linkupapi/linkupapi.app.mjs
🧬 Code graph analysis (10)
components/linkupapi/actions/search-profiles/search-profiles.mjs (2)
components/linkupapi/actions/get-conversation-messages/get-conversation-messages.mjs (1)
  • response (69-78)
components/linkupapi/actions/search-companies/search-companies.mjs (1)
  • response (83-94)
components/linkupapi/actions/send-message/send-message.mjs (2)
components/linkupapi/actions/connect-to-profile/connect-to-profile.mjs (1)
  • response (51-59)
components/linkupapi/actions/get-profile-info/get-profile-info.mjs (1)
  • response (44-51)
components/linkupapi/actions/verify-code/verify-code.mjs (3)
components/linkupapi/actions/connect-to-profile/connect-to-profile.mjs (1)
  • response (51-59)
components/linkupapi/actions/get-company-info/get-company-info.mjs (1)
  • response (44-51)
components/linkupapi/actions/login/login.mjs (1)
  • response (43-50)
components/linkupapi/actions/get-company-info/get-company-info.mjs (4)
components/linkupapi/actions/connect-to-profile/connect-to-profile.mjs (1)
  • response (51-59)
components/linkupapi/actions/get-profile-info/get-profile-info.mjs (1)
  • response (44-51)
components/linkupapi/actions/search-companies/search-companies.mjs (1)
  • response (83-94)
components/linkupapi/actions/search-profiles/search-profiles.mjs (1)
  • response (123-139)
components/linkupapi/actions/search-companies/search-companies.mjs (3)
components/linkupapi/actions/get-conversation-messages/get-conversation-messages.mjs (1)
  • response (69-78)
components/linkupapi/actions/search-profiles/search-profiles.mjs (1)
  • response (123-139)
components/linkupapi/linkupapi.app.mjs (1)
  • loginToken (63-73)
components/linkupapi/actions/connect-to-profile/connect-to-profile.mjs (4)
components/linkupapi/actions/get-conversation-messages/get-conversation-messages.mjs (1)
  • response (69-78)
components/linkupapi/actions/get-invitations-status/get-invitations-status.mjs (1)
  • response (44-51)
components/linkupapi/actions/get-profile-info/get-profile-info.mjs (1)
  • response (44-51)
components/linkupapi/actions/send-message/send-message.mjs (1)
  • response (51-59)
components/linkupapi/actions/login/login.mjs (2)
components/linkupapi/actions/connect-to-profile/connect-to-profile.mjs (1)
  • response (51-59)
components/linkupapi/actions/verify-code/verify-code.mjs (1)
  • response (44-51)
components/linkupapi/actions/get-invitations-status/get-invitations-status.mjs (5)
components/linkupapi/actions/connect-to-profile/connect-to-profile.mjs (1)
  • response (51-59)
components/linkupapi/actions/get-company-info/get-company-info.mjs (1)
  • response (44-51)
components/linkupapi/actions/get-profile-info/get-profile-info.mjs (1)
  • response (44-51)
components/linkupapi/actions/search-profiles/search-profiles.mjs (1)
  • response (123-139)
components/linkupapi/actions/send-message/send-message.mjs (1)
  • response (51-59)
components/linkupapi/actions/get-conversation-messages/get-conversation-messages.mjs (4)
components/linkupapi/actions/connect-to-profile/connect-to-profile.mjs (1)
  • response (51-59)
components/linkupapi/actions/search-companies/search-companies.mjs (1)
  • response (83-94)
components/linkupapi/actions/send-message/send-message.mjs (1)
  • response (51-59)
components/linkupapi/linkupapi.app.mjs (1)
  • loginToken (63-73)
components/linkupapi/actions/get-profile-info/get-profile-info.mjs (3)
components/linkupapi/actions/connect-to-profile/connect-to-profile.mjs (1)
  • response (51-59)
components/linkupapi/actions/get-company-info/get-company-info.mjs (1)
  • response (44-51)
components/linkupapi/actions/get-invitations-status/get-invitations-status.mjs (1)
  • response (44-51)
⏰ 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: Publish TypeScript components
  • GitHub Check: Lint Code Base
  • GitHub Check: Verify TypeScript components
🔇 Additional comments (7)
components/linkupapi/package.json (1)

3-3: LGTM!

The version bump to 0.1.0 and the addition of the @pipedream/platform dependency are appropriate for the new LinkUp API actions being introduced in this PR.

Also applies to: 15-16

components/linkupapi/common/utils.mjs (1)

1-5: LGTM!

The utility function correctly handles optional array props by joining them into a string when present, or returning undefined when absent. The logic is sound and the implementation is clean.

components/linkupapi/actions/get-profile-info/get-profile-info.mjs (1)

3-57: LGTM!

The action follows standard Pipedream conventions with appropriate annotations for a read-only profile retrieval operation. The prop wiring, data mapping, and summary export are all correctly implemented.

components/linkupapi/actions/verify-code/verify-code.mjs (1)

3-57: LGTM!

The verify code action is correctly structured with appropriate annotations. The idempotentHint: false is correct since verification codes are typically consumed upon use, and the summary message appropriately avoids including sensitive information.

components/linkupapi/actions/get-company-info/get-company-info.mjs (1)

3-56: LGTM!

The action is well-structured with appropriate annotations for a read-only company information retrieval. The inline definition of companyUrl with an example is helpful for users.

components/linkupapi/actions/send-message/send-message.mjs (1)

3-65: LGTM!

The send message action is correctly structured with appropriate annotations. The destructiveHint: true and idempotentHint: false correctly reflect the nature of sending messages, and the summary message appropriately avoids including sensitive content.

components/linkupapi/actions/search-profiles/search-profiles.mjs (1)

123-139: No action needed—separator choice is correct per LinkUp API specification.

The LinkUp API network field requires comma-separated values (example: "F,S,O"), while other multi-value parameters use semicolons. The code correctly implements this requirement by explicitly passing "," for the network parameter while using the default semicolon separator for company_url, location, and school_url.

luancazarine
luancazarine previously approved these changes Nov 12, 2025
Copy link
Collaborator

@luancazarine luancazarine left a comment

Choose a reason for hiding this comment

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

Hi @jcortes, LGTM! Ready for QA!

@vunguyenhung
Copy link
Collaborator

Hello everyone, I have tested this PR and there're some test cases failed or needed improvement.

Please check test reports below for more information:

@jcortes
Copy link
Collaborator Author

jcortes commented Nov 13, 2025

Hi @vunguyenhung I've just pushed a UX fix for the user when it comes to send a message. The idea is to only be able to send those messages to connected accounts. Please test with latest change. Thanks!

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 5

♻️ Duplicate comments (3)
components/linkupapi/linkupapi.app.mjs (1)

53-87: Harden conversationId options against missing fields (deep destructuring can throw)

The options loader assumes data.conversations always exists and that each item has last_message and participant. If the API schema changes or a field is missing, this will throw at destructuring time and break the prop UI.

You can make this defensive by defaulting data / conversations and the nested fields:

-        const {
-          data: {
-            conversations,
-            next_cursor,
-          },
-        } = await this.getConversations({
+        const {
+          data: {
+            conversations = [],
+            next_cursor,
+          } = {},
+        } = await this.getConversations({
           data: {
             login_token: loginToken,
             next_cursor: prevContext?.nextCursor,
           },
         });
         return {
-          options: conversations.map(({
-            conversation_id: value,
-            last_message: { text },
-            participant: { name },
-          }) => ({
-            label: `${name || "Unknown"} - ${text?.substring(0, 50) || "No message"}`,
-            value,
-          })),
+          options: conversations.map(({
+            conversation_id: value,
+            last_message: { text } = {},
+            participant: { name } = {},
+          }) => ({
+            label: `${name || "Unknown"} - ${text?.substring(0, 50) || "No message"}`,
+            value,
+          })),
           context: {
             nextCursor: next_cursor,
           },
         };

This prevents runtime errors when any of these fields are absent while still producing sensible labels.

components/linkupapi/actions/login/login.mjs (1)

30-34: Add missing idempotentHint annotation.

The annotations block is missing the idempotentHint property. Login operations generate new session tokens on each call, so this should be set to false.

Apply this diff:

   annotations: {
     readOnlyHint: false,
     destructiveHint: false,
     openWorldHint: true,
+    idempotentHint: false,
   },
components/linkupapi/actions/connect-to-profile/connect-to-profile.mjs (1)

51-59: Fix payload key for optional message.

The connection request endpoint expects the optional note under the message field, not message_text. Using the wrong key causes the message to be silently dropped.

Apply this diff:

     const response = await app.connectToProfile({
       $,
       data: {
         linkedin_url: linkedinUrl,
         login_token: loginToken,
-        message_text: message,
+        ...(message && { message }),
         country,
       },
     });
📜 Review details

Configuration used: CodeRabbit UI

Review profile: ASSERTIVE

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 3e68d23 and a56f125.

⛔ Files ignored due to path filters (1)
  • pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml
📒 Files selected for processing (13)
  • components/linkupapi/actions/connect-to-profile/connect-to-profile.mjs (1 hunks)
  • components/linkupapi/actions/get-company-info/get-company-info.mjs (1 hunks)
  • components/linkupapi/actions/get-conversation-messages/get-conversation-messages.mjs (1 hunks)
  • components/linkupapi/actions/get-invitations-status/get-invitations-status.mjs (1 hunks)
  • components/linkupapi/actions/get-profile-info/get-profile-info.mjs (1 hunks)
  • components/linkupapi/actions/login/login.mjs (1 hunks)
  • components/linkupapi/actions/search-companies/search-companies.mjs (1 hunks)
  • components/linkupapi/actions/search-profiles/search-profiles.mjs (1 hunks)
  • components/linkupapi/actions/send-message/send-message.mjs (1 hunks)
  • components/linkupapi/actions/verify-code/verify-code.mjs (1 hunks)
  • components/linkupapi/common/utils.mjs (1 hunks)
  • components/linkupapi/linkupapi.app.mjs (1 hunks)
  • components/linkupapi/package.json (2 hunks)
🧰 Additional context used
🧠 Learnings (6)
📚 Learning: 2024-10-08T15:33:38.240Z
Learnt from: GTFalcao
Repo: PipedreamHQ/pipedream PR: 12731
File: components/hackerone/actions/get-members/get-members.mjs:3-28
Timestamp: 2024-10-08T15:33:38.240Z
Learning: When exporting a summary message in the `run` method of an action, ensure the message is correctly formatted. For example, in the `hackerone-get-members` action, the correct format is `Successfully retrieved ${response.data.length} members`.

Applied to files:

  • components/linkupapi/actions/get-conversation-messages/get-conversation-messages.mjs
  • components/linkupapi/actions/send-message/send-message.mjs
📚 Learning: 2024-12-12T19:23:09.039Z
Learnt from: jcortes
Repo: PipedreamHQ/pipedream PR: 14935
File: components/sailpoint/package.json:15-18
Timestamp: 2024-12-12T19:23:09.039Z
Learning: When developing Pipedream components, do not add built-in Node.js modules like `fs` to `package.json` dependencies, as they are native modules provided by the Node.js runtime.

Applied to files:

  • components/linkupapi/package.json
📚 Learning: 2025-10-20T01:01:02.970Z
Learnt from: js07
Repo: PipedreamHQ/pipedream PR: 18744
File: components/slack_v2/actions/send-large-message/send-large-message.mjs:49-64
Timestamp: 2025-10-20T01:01:02.970Z
Learning: In components/slack_v2/actions/send-large-message/send-large-message.mjs, the metadata_event_payload prop is typed as string, so the code only needs to handle string-to-JSON parsing and does not need to handle object inputs.

Applied to files:

  • components/linkupapi/actions/connect-to-profile/connect-to-profile.mjs
  • components/linkupapi/actions/send-message/send-message.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/linkupapi/linkupapi.app.mjs
📚 Learning: 2025-09-12T07:49:36.125Z
Learnt from: matyascimbulka
Repo: PipedreamHQ/pipedream PR: 18308
File: components/apify/actions/run-task-synchronously/run-task-synchronously.mjs:70-0
Timestamp: 2025-09-12T07:49:36.125Z
Learning: The Apify Task object always contains the `options` field according to the official API documentation, making nested destructuring like `options: { build }` safe to use without additional checks.

Applied to files:

  • components/linkupapi/linkupapi.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/linkupapi/linkupapi.app.mjs
🧬 Code graph analysis (9)
components/linkupapi/actions/get-company-info/get-company-info.mjs (4)
components/linkupapi/actions/get-invitations-status/get-invitations-status.mjs (1)
  • response (44-51)
components/linkupapi/actions/get-profile-info/get-profile-info.mjs (1)
  • response (44-51)
components/linkupapi/actions/search-companies/search-companies.mjs (1)
  • response (83-94)
components/linkupapi/actions/search-profiles/search-profiles.mjs (1)
  • response (123-139)
components/linkupapi/actions/get-conversation-messages/get-conversation-messages.mjs (5)
components/linkupapi/actions/connect-to-profile/connect-to-profile.mjs (1)
  • response (51-59)
components/linkupapi/actions/get-profile-info/get-profile-info.mjs (1)
  • response (44-51)
components/linkupapi/actions/search-profiles/search-profiles.mjs (1)
  • response (123-139)
components/linkupapi/actions/send-message/send-message.mjs (1)
  • response (58-66)
components/linkupapi/linkupapi.app.mjs (1)
  • loginToken (63-73)
components/linkupapi/actions/login/login.mjs (3)
components/linkupapi/actions/connect-to-profile/connect-to-profile.mjs (1)
  • response (51-59)
components/linkupapi/actions/get-profile-info/get-profile-info.mjs (1)
  • response (44-51)
components/linkupapi/actions/verify-code/verify-code.mjs (1)
  • response (44-51)
components/linkupapi/actions/search-profiles/search-profiles.mjs (2)
components/linkupapi/actions/get-conversation-messages/get-conversation-messages.mjs (1)
  • response (69-78)
components/linkupapi/actions/search-companies/search-companies.mjs (1)
  • response (83-94)
components/linkupapi/actions/get-invitations-status/get-invitations-status.mjs (2)
components/linkupapi/actions/connect-to-profile/connect-to-profile.mjs (1)
  • response (51-59)
components/linkupapi/actions/get-profile-info/get-profile-info.mjs (1)
  • response (44-51)
components/linkupapi/actions/connect-to-profile/connect-to-profile.mjs (4)
components/linkupapi/actions/get-company-info/get-company-info.mjs (1)
  • response (44-51)
components/linkupapi/actions/get-invitations-status/get-invitations-status.mjs (1)
  • response (44-51)
components/linkupapi/actions/get-profile-info/get-profile-info.mjs (1)
  • response (44-51)
components/linkupapi/actions/send-message/send-message.mjs (1)
  • response (58-66)
components/linkupapi/actions/verify-code/verify-code.mjs (1)
components/linkupapi/actions/login/login.mjs (1)
  • response (43-50)
components/linkupapi/actions/send-message/send-message.mjs (3)
components/linkupapi/actions/connect-to-profile/connect-to-profile.mjs (1)
  • response (51-59)
components/linkupapi/actions/get-invitations-status/get-invitations-status.mjs (1)
  • response (44-51)
components/linkupapi/actions/get-profile-info/get-profile-info.mjs (1)
  • response (44-51)
components/linkupapi/actions/search-companies/search-companies.mjs (1)
components/linkupapi/actions/search-profiles/search-profiles.mjs (1)
  • response (123-139)
⏰ 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). (5)
  • GitHub Check: pnpm publish
  • GitHub Check: Publish TypeScript components
  • GitHub Check: Verify TypeScript components
  • GitHub Check: Lint Code Base
  • GitHub Check: Ensure component commits modify component versions
🔇 Additional comments (11)
components/linkupapi/package.json (1)

3-17: Package metadata bump looks consistent

Version 0.1.0 and the added dependency align with the new LinkUp app methods and actions; no issues from this change alone.

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

107-197: Shared HTTP wrapper and endpoint methods look coherent

getUrl, _getHeaders, _makeRequest, and the small POST helpers provide a clear, consistent surface for all LinkUp endpoints, and the path mappings match the action intents.

Based on learnings

components/linkupapi/actions/search-profiles/search-profiles.mjs (1)

106-143: Profile search payload wiring looks correct

The action cleanly maps props to the searchProfiles payload, and using utils.getOptionalProp for the array filters (company URL, location, school URL, network) is consistent and keeps the request shape compact.

Based on learnings

components/linkupapi/actions/search-companies/search-companies.mjs (1)

1-99: LGTM!

The action is well-structured with complete annotations, proper use of utils.getOptionalProp for optional array props, and all props correctly mapped to the API payload.

components/linkupapi/actions/get-company-info/get-company-info.mjs (1)

1-56: LGTM!

The action correctly handles the optional companyUrl parameter and has complete annotations. The implementation aligns with other actions in this PR.

components/linkupapi/actions/send-message/send-message.mjs (1)

1-78: LGTM!

The action includes helpful user guidance via the info alert and provides good error handling with a user-friendly message for the invalid parameter case.

components/linkupapi/actions/get-profile-info/get-profile-info.mjs (1)

1-57: LGTM!

The action follows the standard pattern with complete annotations and correct prop mapping to the API payload.

components/linkupapi/actions/get-invitations-status/get-invitations-status.mjs (1)

1-57: LGTM!

The action follows the standard pattern with complete annotations and correct prop mapping to the API payload.

components/linkupapi/actions/get-conversation-messages/get-conversation-messages.mjs (3)

1-2: LGTM!

The imports are correct and both are used appropriately in the action.


4-9: LGTM!

The action metadata is well-structured and follows Pipedream conventions.


50-55: LGTM!

The annotations accurately describe the action's behavior: read-only, non-destructive, makes external calls, and is idempotent.

@vunguyenhung
Copy link
Collaborator

Hi everyone, all test cases are passed! Ready for release!

Test reports

@jcortes jcortes force-pushed the linkupapi-new-components branch from a56f125 to 2523b14 Compare November 14, 2025 15:43
@jcortes
Copy link
Collaborator Author

jcortes commented Nov 14, 2025

/approve

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 2

♻️ Duplicate comments (7)
components/linkupapi/common/utils.mjs (1)

1-5: Past review comment applies.

A previous review suggested making getOptionalProp handle both arrays and scalar values defensively for future-proofing. The current implementation is correct for existing usage.

components/linkupapi/actions/verify-code/verify-code.mjs (1)

53-53: Past review comment applies.

The summary message "Successfully verified code for email" was flagged in a previous review as incomplete. Consider either removing "for email" or interpolating the actual email address.

components/linkupapi/actions/search-profiles/search-profiles.mjs (1)

81-86: Past review comment applies.

A previous review noted that the totalResults prop description claims a default of 10, but no explicit default value is set on the prop. Consider adding default: 10 or removing the default mention from the description.

components/linkupapi/actions/login/login.mjs (1)

30-34: Past review comment applies.

A previous review noted that the idempotentHint property is missing from the annotations block. Since login operations generate new session tokens on each call, this should be set to false.

components/linkupapi/actions/connect-to-profile/connect-to-profile.mjs (1)

51-58: Fix payload key for optional message

The LinkUp "Send Connection Request" endpoint expects the optional note under the message field, not message_text. Sending the wrong key causes the message to be dropped even though the request succeeds.

Apply this diff to fix the payload key:

     const response = await app.connectToProfile({
       $,
       data: {
         linkedin_url: linkedinUrl,
         login_token: loginToken,
-        message_text: message,
         country,
+        ...(message && { message }),
       },
     });
components/linkupapi/actions/get-conversation-messages/get-conversation-messages.mjs (1)

37-42: Clarify or set the default value for totalResults.

The description mentions "(default: 10)" but no default value is set in the prop definition. If the API defaults to 10 when the parameter is omitted, this is fine but the description is misleading. If you intend for this prop to default to 10 on the client side, add default: 10.

Apply this diff if the default should be 10:

     totalResults: {
       type: "integer",
       label: "Total Results",
       description: "Number of messages to retrieve when not in pagination mode (default: 10)",
       optional: true,
+      default: 10,
     },

Otherwise, remove the "(default: 10)" text from the description.

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

63-86: Add safe property access for nested destructuring.

The code destructures deeply nested properties without safeguards. If the API response structure differs from expectations (e.g., missing conversations, last_message, or participant fields), this will cause runtime errors.

Apply this diff to add safe property access:

     const {
       data: {
-        conversations,
-        next_cursor,
-      },
+        conversations = [],
+        next_cursor = null,
+      } = {},
     } = await this.getConversations({
       data: {
         login_token: loginToken,
         next_cursor: prevContext?.nextCursor,
       },
     });
     return {
       options: conversations.map(({
         conversation_id: value,
-        last_message: { text },
-        participant: { name },
+        last_message: { text } = {},
+        participant: { name } = {},
       }) => ({
         label: `${name || "Unknown"} - ${text?.substring(0, 50) || "No message"}`,
         value,
       })),
📜 Review details

Configuration used: CodeRabbit UI

Review profile: ASSERTIVE

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between a56f125 and 2523b14.

📒 Files selected for processing (13)
  • components/linkupapi/actions/connect-to-profile/connect-to-profile.mjs (1 hunks)
  • components/linkupapi/actions/get-company-info/get-company-info.mjs (1 hunks)
  • components/linkupapi/actions/get-conversation-messages/get-conversation-messages.mjs (1 hunks)
  • components/linkupapi/actions/get-invitations-status/get-invitations-status.mjs (1 hunks)
  • components/linkupapi/actions/get-profile-info/get-profile-info.mjs (1 hunks)
  • components/linkupapi/actions/login/login.mjs (1 hunks)
  • components/linkupapi/actions/search-companies/search-companies.mjs (1 hunks)
  • components/linkupapi/actions/search-profiles/search-profiles.mjs (1 hunks)
  • components/linkupapi/actions/send-message/send-message.mjs (1 hunks)
  • components/linkupapi/actions/verify-code/verify-code.mjs (1 hunks)
  • components/linkupapi/common/utils.mjs (1 hunks)
  • components/linkupapi/linkupapi.app.mjs (1 hunks)
  • components/linkupapi/package.json (2 hunks)
🧰 Additional context used
🧠 Learnings (7)
📚 Learning: 2024-10-08T15:33:38.240Z
Learnt from: GTFalcao
Repo: PipedreamHQ/pipedream PR: 12731
File: components/hackerone/actions/get-members/get-members.mjs:3-28
Timestamp: 2024-10-08T15:33:38.240Z
Learning: When exporting a summary message in the `run` method of an action, ensure the message is correctly formatted. For example, in the `hackerone-get-members` action, the correct format is `Successfully retrieved ${response.data.length} members`.

Applied to files:

  • components/linkupapi/actions/verify-code/verify-code.mjs
  • components/linkupapi/actions/get-conversation-messages/get-conversation-messages.mjs
  • components/linkupapi/actions/send-message/send-message.mjs
  • components/linkupapi/actions/get-invitations-status/get-invitations-status.mjs
📚 Learning: 2024-12-12T19:23:09.039Z
Learnt from: jcortes
Repo: PipedreamHQ/pipedream PR: 14935
File: components/sailpoint/package.json:15-18
Timestamp: 2024-12-12T19:23:09.039Z
Learning: When developing Pipedream components, do not add built-in Node.js modules like `fs` to `package.json` dependencies, as they are native modules provided by the Node.js runtime.

Applied to files:

  • components/linkupapi/package.json
📚 Learning: 2025-07-01T17:07:48.193Z
Learnt from: js07
Repo: PipedreamHQ/pipedream PR: 17375
File: components/zerobounce/actions/get-validation-results-file/get-validation-results-file.mjs:23-27
Timestamp: 2025-07-01T17:07:48.193Z
Learning: For "dir" props in Pipedream components, whether to mark them as optional depends on the action's file I/O behavior - if an action always writes files as output, the "dir" prop should not be marked as optional.

Applied to files:

  • components/linkupapi/common/utils.mjs
📚 Learning: 2025-10-20T01:01:02.970Z
Learnt from: js07
Repo: PipedreamHQ/pipedream PR: 18744
File: components/slack_v2/actions/send-large-message/send-large-message.mjs:49-64
Timestamp: 2025-10-20T01:01:02.970Z
Learning: In components/slack_v2/actions/send-large-message/send-large-message.mjs, the metadata_event_payload prop is typed as string, so the code only needs to handle string-to-JSON parsing and does not need to handle object inputs.

Applied to files:

  • components/linkupapi/actions/send-message/send-message.mjs
  • components/linkupapi/actions/connect-to-profile/connect-to-profile.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/linkupapi/linkupapi.app.mjs
📚 Learning: 2025-09-12T07:49:36.125Z
Learnt from: matyascimbulka
Repo: PipedreamHQ/pipedream PR: 18308
File: components/apify/actions/run-task-synchronously/run-task-synchronously.mjs:70-0
Timestamp: 2025-09-12T07:49:36.125Z
Learning: The Apify Task object always contains the `options` field according to the official API documentation, making nested destructuring like `options: { build }` safe to use without additional checks.

Applied to files:

  • components/linkupapi/linkupapi.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/linkupapi/linkupapi.app.mjs
🧬 Code graph analysis (10)
components/linkupapi/actions/verify-code/verify-code.mjs (1)
components/linkupapi/actions/login/login.mjs (1)
  • response (43-50)
components/linkupapi/actions/login/login.mjs (3)
components/linkupapi/actions/connect-to-profile/connect-to-profile.mjs (1)
  • response (51-59)
components/linkupapi/actions/send-message/send-message.mjs (1)
  • response (58-66)
components/linkupapi/actions/verify-code/verify-code.mjs (1)
  • response (44-51)
components/linkupapi/actions/get-conversation-messages/get-conversation-messages.mjs (8)
components/linkupapi/actions/connect-to-profile/connect-to-profile.mjs (1)
  • response (51-59)
components/linkupapi/actions/get-company-info/get-company-info.mjs (1)
  • response (44-51)
components/linkupapi/actions/get-invitations-status/get-invitations-status.mjs (1)
  • response (44-51)
components/linkupapi/actions/get-profile-info/get-profile-info.mjs (1)
  • response (44-51)
components/linkupapi/actions/search-companies/search-companies.mjs (1)
  • response (83-94)
components/linkupapi/actions/search-profiles/search-profiles.mjs (1)
  • response (123-139)
components/linkupapi/actions/send-message/send-message.mjs (1)
  • response (58-66)
components/linkupapi/linkupapi.app.mjs (1)
  • loginToken (63-73)
components/linkupapi/actions/get-profile-info/get-profile-info.mjs (5)
components/linkupapi/actions/connect-to-profile/connect-to-profile.mjs (1)
  • response (51-59)
components/linkupapi/actions/get-company-info/get-company-info.mjs (1)
  • response (44-51)
components/linkupapi/actions/get-conversation-messages/get-conversation-messages.mjs (1)
  • response (69-78)
components/linkupapi/actions/get-invitations-status/get-invitations-status.mjs (1)
  • response (44-51)
components/linkupapi/actions/send-message/send-message.mjs (1)
  • response (58-66)
components/linkupapi/actions/send-message/send-message.mjs (3)
components/linkupapi/actions/connect-to-profile/connect-to-profile.mjs (1)
  • response (51-59)
components/linkupapi/actions/get-invitations-status/get-invitations-status.mjs (1)
  • response (44-51)
components/linkupapi/actions/get-profile-info/get-profile-info.mjs (1)
  • response (44-51)
components/linkupapi/actions/connect-to-profile/connect-to-profile.mjs (3)
components/linkupapi/actions/get-invitations-status/get-invitations-status.mjs (1)
  • response (44-51)
components/linkupapi/actions/get-profile-info/get-profile-info.mjs (1)
  • response (44-51)
components/linkupapi/actions/send-message/send-message.mjs (1)
  • response (58-66)
components/linkupapi/actions/get-company-info/get-company-info.mjs (3)
components/linkupapi/actions/connect-to-profile/connect-to-profile.mjs (1)
  • response (51-59)
components/linkupapi/actions/get-profile-info/get-profile-info.mjs (1)
  • response (44-51)
components/linkupapi/actions/search-profiles/search-profiles.mjs (1)
  • response (123-139)
components/linkupapi/actions/search-companies/search-companies.mjs (2)
components/linkupapi/actions/get-conversation-messages/get-conversation-messages.mjs (1)
  • response (69-78)
components/linkupapi/actions/search-profiles/search-profiles.mjs (1)
  • response (123-139)
components/linkupapi/actions/get-invitations-status/get-invitations-status.mjs (3)
components/linkupapi/actions/connect-to-profile/connect-to-profile.mjs (1)
  • response (51-59)
components/linkupapi/actions/get-company-info/get-company-info.mjs (1)
  • response (44-51)
components/linkupapi/actions/get-profile-info/get-profile-info.mjs (1)
  • response (44-51)
components/linkupapi/actions/search-profiles/search-profiles.mjs (1)
components/linkupapi/actions/search-companies/search-companies.mjs (1)
  • response (83-94)
⏰ 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: Lint Code Base
  • GitHub Check: Publish TypeScript components
🔇 Additional comments (6)
components/linkupapi/package.json (1)

3-3: LGTM!

The version bump to 0.1.0 and the addition of the @pipedream/platform dependency are appropriate for this new component integration.

Also applies to: 15-17

components/linkupapi/actions/get-company-info/get-company-info.mjs (1)

1-56: LGTM!

The action is well-structured with proper propDefinitions, appropriate annotations (including idempotentHint: true for this read operation), and follows the established pattern for LinkUp API actions.

components/linkupapi/actions/send-message/send-message.mjs (1)

11-16: LGTM!

The informational alert and enhanced error handling provide excellent user experience by clearly communicating prerequisites and providing helpful error messages when the connection requirement isn't met.

Also applies to: 57-76

components/linkupapi/actions/get-profile-info/get-profile-info.mjs (1)

1-57: LGTM!

The action follows the established pattern correctly. Props are wired appropriately, the payload mapping uses the correct snake_case keys, and the annotations accurately reflect a read-only, idempotent operation.

components/linkupapi/actions/get-invitations-status/get-invitations-status.mjs (1)

1-57: LGTM!

The action is well-structured and follows the established pattern. The payload mapping is correct, and the annotations appropriately reflect a read-only, idempotent operation.

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

108-197: HTTP wrapper and endpoint methods are well-structured.

The centralized HTTP request handling with _makeRequest and the endpoint-specific methods follow Pipedream's established patterns correctly. The header injection and URL construction are implemented properly.

Comment on lines +56 to +82
async run({ $ }) {
const {
loginToken,
linkedinUrl,
conversationId,
totalResults,
country,
} = this;

if (!linkedinUrl && !conversationId) {
throw new ConfigurationError("Either **LinkedIn URL** or **Conversation ID** is required");
}

const response = await this.app.getConversationMessages({
$,
data: {
login_token: loginToken,
linkedin_url: linkedinUrl,
conversation_id: conversationId,
country,
total_results: totalResults,
},
});

$.export("$summary", "Successfully retrieved conversation messages");
return response;
},
Copy link
Contributor

Choose a reason for hiding this comment

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

🧹 Nitpick | 🔵 Trivial

Good validation logic.

The either/or validation for linkedinUrl and conversationId is well-implemented and provides a clear error message.

Optionally, consider enhancing the summary message with the count of messages returned (e.g., Successfully retrieved ${response.messages?.length || 0} conversation message(s)) if the API response includes a message count. Based on learnings.

🤖 Prompt for AI Agents
In
components/linkupapi/actions/get-conversation-messages/get-conversation-messages.mjs
around lines 56 to 82, improve the exported summary to include the number of
messages returned by the API; after receiving response, compute a safe count
like const count = response?.messages?.length ?? 0 and change the
$.export("$summary", ...) call to use that count (e.g., "Successfully retrieved
X conversation message(s)"), ensuring optional chaining/nullish coalescing is
used so undefined responses don't throw.

Comment on lines +53 to +58
totalResults: {
type: "integer",
label: "Total Results",
description: "Number of companies to retrieve when not in pagination mode (default: 10)",
optional: true,
},
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

Align description with implementation for totalResults default.

The description states "(default: 10)" but the prop has no explicit default value, so the effective default depends on the API behavior. Either add default: 10 to the prop definition or remove the default mention from the description.

Apply this diff to add an explicit default:

     totalResults: {
       type: "integer",
       label: "Total Results",
-      description: "Number of companies to retrieve when not in pagination mode (default: 10)",
+      description: "Number of companies to retrieve when not in pagination mode",
       optional: true,
+      default: 10,
     },

Or remove the default mention:

     totalResults: {
       type: "integer",
       label: "Total Results",
-      description: "Number of companies to retrieve when not in pagination mode (default: 10)",
+      description: "Number of companies to retrieve when not in pagination mode",
       optional: true,
     },
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
totalResults: {
type: "integer",
label: "Total Results",
description: "Number of companies to retrieve when not in pagination mode (default: 10)",
optional: true,
},
totalResults: {
type: "integer",
label: "Total Results",
description: "Number of companies to retrieve when not in pagination mode",
optional: true,
default: 10,
},
🤖 Prompt for AI Agents
In components/linkupapi/actions/search-companies/search-companies.mjs around
lines 53 to 58, the prop `totalResults` description mentions a "(default: 10)"
but no explicit `default` is set; either add `default: 10` to the prop
definition or remove the default mention from the description. To fix, update
the prop block to include `default: 10` if you intend to enforce a client-side
default, or edit the description to remove "(default: 10)" so it matches
API-driven behavior.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

linkup api for linkedin

4 participants