@pipedream/linkupapi 0.2.0 → 1.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,57 +1,62 @@
1
+ import { ConfigurationError } from "@pipedream/platform";
1
2
  import app from "../../linkupapi.app.mjs";
2
3
 
3
4
  export default {
4
5
  type: "action",
6
+ ai: "optimized",
5
7
  key: "linkupapi-get-profile-info",
6
8
  name: "Get Profile Info",
7
- description: "Extract information from a LinkedIn profile. [See the documentation](https://docs.linkupapi.com/api-reference/linkup/Profile/profile-info)",
8
- version: "0.0.2",
9
+ description: "Fetch details for a LinkedIn profile. Identify the target by profile URL, public identifier, or profile URN. [See the documentation](https://docs.linkupapi.com/api-reference/v2/profiles/get-profile)",
10
+ version: "1.0.1",
11
+ annotations: {
12
+ readOnlyHint: true,
13
+ destructiveHint: false,
14
+ openWorldHint: true,
15
+ },
9
16
  props: {
10
17
  app,
18
+ accountId: {
19
+ propDefinition: [
20
+ app,
21
+ "accountId",
22
+ ],
23
+ },
11
24
  linkedinUrl: {
12
25
  propDefinition: [
13
26
  app,
14
27
  "linkedinUrl",
15
28
  ],
29
+ description: "LinkedIn profile URL. Eg. `https://www.linkedin.com/in/john-doe/`. Provide this, an **Identifier**, or a **Profile URN**.",
30
+ optional: true,
16
31
  },
17
- loginToken: {
32
+ identifier: {
18
33
  propDefinition: [
19
34
  app,
20
- "loginToken",
35
+ "identifier",
21
36
  ],
22
37
  },
23
- country: {
38
+ profileUrn: {
24
39
  propDefinition: [
25
40
  app,
26
- "country",
41
+ "profileUrn",
27
42
  ],
28
43
  },
29
44
  },
30
- annotations: {
31
- readOnlyHint: true,
32
- destructiveHint: false,
33
- openWorldHint: true,
34
- idempotentHint: true,
35
- },
36
45
  async run({ $ }) {
37
- const {
38
- app,
39
- linkedinUrl,
40
- loginToken,
41
- country,
42
- } = this;
43
-
44
- const response = await app.getProfileInfo({
46
+ if (!this.linkedinUrl && !this.identifier && !this.profileUrn) {
47
+ throw new ConfigurationError("Provide a **LinkedIn URL**, an **Identifier**, or a **Profile URN** to identify the profile.");
48
+ }
49
+ const response = await this.app.getProfileInfo({
45
50
  $,
46
- data: {
47
- linkedin_url: linkedinUrl,
48
- login_token: loginToken,
49
- country,
51
+ accountId: this.accountId,
52
+ params: {
53
+ profile_url: this.linkedinUrl,
54
+ identifier: this.identifier,
55
+ profile_urn: this.profileUrn,
50
56
  },
51
57
  });
52
58
 
53
- $.export("$summary", "Successfully retrieved profile information");
54
-
59
+ $.export("$summary", `Successfully retrieved profile information for ${this.linkedinUrl || this.identifier || this.profileUrn}`);
55
60
  return response;
56
61
  },
57
62
  };
@@ -0,0 +1,51 @@
1
+ import app from "../../linkupapi.app.mjs";
2
+ import { ACCOUNTS_MAX_PAGE_SIZE } from "../../common/constants.mjs";
3
+
4
+ export default {
5
+ key: "linkupapi-list-accounts",
6
+ name: "List Accounts",
7
+ description: "List the LinkupAPI accounts connected to your API key, each with its persistent `account_id` to use in other actions. [See the documentation](https://docs.linkupapi.com/api-reference/v2/accounts/list-accounts)",
8
+ version: "0.0.1",
9
+ type: "action",
10
+ annotations: {
11
+ readOnlyHint: true,
12
+ destructiveHint: false,
13
+ openWorldHint: true,
14
+ },
15
+ props: {
16
+ app,
17
+ totalResults: {
18
+ propDefinition: [
19
+ app,
20
+ "totalResults",
21
+ ],
22
+ },
23
+ },
24
+ async run({ $ }) {
25
+ const accounts = await this.app._paginate({
26
+ max: this.totalResults,
27
+ requestPage: ({
28
+ next, count,
29
+ }) => this.app.listAccounts({
30
+ $,
31
+ params: {
32
+ limit: Math.min(ACCOUNTS_MAX_PAGE_SIZE, count),
33
+ offset: next || 0,
34
+ },
35
+ }),
36
+ getItems: (res) => res.data?.items,
37
+ getNext: (res) => {
38
+ const data = res.data || {};
39
+ const nextOffset = (data.offset || 0) + (data.items?.length || 0);
40
+ return nextOffset < (data.total || 0)
41
+ ? nextOffset
42
+ : null;
43
+ },
44
+ });
45
+
46
+ $.export("$summary", `Successfully retrieved ${accounts.length} account${accounts.length === 1
47
+ ? ""
48
+ : "s"}`);
49
+ return accounts;
50
+ },
51
+ };
@@ -0,0 +1,67 @@
1
+ import app from "../../linkupapi.app.mjs";
2
+
3
+ export default {
4
+ key: "linkupapi-list-inbox",
5
+ name: "List Inbox",
6
+ description: "List conversations from the LinkedIn inbox, each with its `conversation_id` to use with **Get Conversation Messages**. [See the documentation](https://docs.linkupapi.com/api-reference/v2/messages/list-inbox)",
7
+ version: "0.0.2",
8
+ type: "action",
9
+ ai: "optimized",
10
+ annotations: {
11
+ readOnlyHint: true,
12
+ destructiveHint: false,
13
+ openWorldHint: true,
14
+ },
15
+ props: {
16
+ app,
17
+ accountId: {
18
+ propDefinition: [
19
+ app,
20
+ "accountId",
21
+ ],
22
+ },
23
+ totalResults: {
24
+ propDefinition: [
25
+ app,
26
+ "totalResults",
27
+ ],
28
+ },
29
+ category: {
30
+ type: "string",
31
+ label: "Category",
32
+ description: "Filter conversations by category.",
33
+ optional: true,
34
+ options: [
35
+ "INBOX",
36
+ "UNREAD",
37
+ "MY_CONNECTIONS",
38
+ "INMAIL",
39
+ "STARRED",
40
+ ],
41
+ default: "INBOX",
42
+ },
43
+ },
44
+ async run({ $ }) {
45
+ const conversations = await this.app._paginate({
46
+ max: this.totalResults,
47
+ requestPage: ({
48
+ next, count,
49
+ }) => this.app.listInbox({
50
+ $,
51
+ accountId: this.accountId,
52
+ params: {
53
+ count,
54
+ cursor: next,
55
+ category: this.category,
56
+ },
57
+ }),
58
+ getItems: (res) => res.data?.conversations,
59
+ getNext: (res) => res.data?.next_cursor,
60
+ });
61
+
62
+ $.export("$summary", `Successfully retrieved ${conversations.length} conversation${conversations.length === 1
63
+ ? ""
64
+ : "s"}`);
65
+ return conversations;
66
+ },
67
+ };
@@ -1,28 +1,32 @@
1
1
  import app from "../../linkupapi.app.mjs";
2
- import utils from "../../common/utils.mjs";
3
2
 
4
3
  export default {
5
4
  type: "action",
6
5
  key: "linkupapi-search-companies",
7
6
  name: "Search Companies",
8
- description: "Search for companies on LinkedIn based on criteria. [See the documentation](https://docs.linkupapi.com/api-reference/linkup/Companies/search)",
9
- version: "0.0.2",
7
+ description: "Search for LinkedIn companies. [See the documentation](https://docs.linkupapi.com/api-reference/v2/profiles/search-companies)",
8
+ version: "1.0.0",
9
+ annotations: {
10
+ readOnlyHint: true,
11
+ destructiveHint: false,
12
+ openWorldHint: true,
13
+ },
10
14
  props: {
11
15
  app,
12
- loginToken: {
16
+ accountId: {
13
17
  propDefinition: [
14
18
  app,
15
- "loginToken",
19
+ "accountId",
16
20
  ],
17
21
  },
18
22
  keyword: {
19
- type: "string",
20
- label: "Keyword",
21
- description: "Search keyword for company filtering",
22
- optional: true,
23
+ propDefinition: [
24
+ app,
25
+ "keyword",
26
+ ],
27
+ description: "Free-text keyword to search companies by (e.g. company name or industry).",
23
28
  },
24
29
  location: {
25
- description: "Geographic locations to filter companies",
26
30
  propDefinition: [
27
31
  app,
28
32
  "location",
@@ -31,69 +35,39 @@ export default {
31
35
  sector: {
32
36
  type: "string[]",
33
37
  label: "Sector",
34
- description: "Industry sector you can [find the label here](https://learn.microsoft.com/en-us/linkedin/shared/references/reference-tables/industry-codes-v2)",
38
+ description: "Industry sectors to filter by, passed as an array of strings.",
35
39
  optional: true,
36
40
  },
37
41
  companySize: {
38
- type: "string",
42
+ type: "string[]",
39
43
  label: "Company Size",
40
- description: "Employee count range: 1-10 employees 11-50 employees 51-200 employees 201-500 employees 501-1000 employees 1001-5000 employees 5001-10000 employees 10001+ employees",
44
+ description: "Company size ranges to filter by, passed as an array of strings, e.g. `[\"11-50\", \"51-200\"]`.",
41
45
  optional: true,
42
- options: [
43
- "1-10",
44
- "11-50",
45
- "51-200",
46
- "201-500",
47
- "501-1000",
48
- "1001-5000",
49
- "5001-10000",
50
- "10001+",
51
- ],
52
46
  },
53
47
  totalResults: {
54
- type: "integer",
55
- label: "Total Results",
56
- description: "Number of companies to retrieve when not in pagination mode (default: 10)",
57
- optional: true,
58
- },
59
- country: {
60
48
  propDefinition: [
61
49
  app,
62
- "country",
50
+ "totalResults",
63
51
  ],
64
52
  },
65
53
  },
66
- annotations: {
67
- readOnlyHint: true,
68
- destructiveHint: false,
69
- openWorldHint: true,
70
- idempotentHint: true,
71
- },
72
54
  async run({ $ }) {
73
- const {
74
- loginToken,
75
- country,
76
- keyword,
77
- location,
78
- sector,
79
- companySize,
80
- totalResults,
81
- } = this;
82
-
83
55
  const response = await this.app.searchCompanies({
84
56
  $,
85
- data: {
86
- login_token: loginToken,
87
- country,
88
- keyword,
89
- location: utils.getOptionalProp(location),
90
- sector: utils.getOptionalProp(sector),
91
- company_size: companySize,
92
- total_results: totalResults,
57
+ accountId: this.accountId,
58
+ params: {
59
+ keyword: this.keyword,
60
+ location: this.location,
61
+ sector: this.sector,
62
+ company_size: this.companySize,
63
+ total_results: this.totalResults,
93
64
  },
94
65
  });
95
66
 
96
- $.export("$summary", "Successfully retrieved companies");
67
+ const count = response.data?.companies?.length || 0;
68
+ $.export("$summary", `Successfully retrieved ${count} compan${count === 1
69
+ ? "y"
70
+ : "ies"}`);
97
71
  return response;
98
72
  },
99
73
  };
@@ -1,144 +1,143 @@
1
1
  import app from "../../linkupapi.app.mjs";
2
- import utils from "../../common/utils.mjs";
3
2
 
4
3
  export default {
5
4
  type: "action",
6
5
  key: "linkupapi-search-profiles",
7
6
  name: "Search Profiles",
8
- description: "Search for LinkedIn profiles based on criteria. [See the documentation](https://docs.linkupapi.com/api-reference/linkup/Profile/search)",
9
- version: "0.0.2",
7
+ description: "Search for LinkedIn people. [See the documentation](https://docs.linkupapi.com/api-reference/v2/profiles/search-people)",
8
+ version: "1.0.0",
9
+ annotations: {
10
+ readOnlyHint: true,
11
+ destructiveHint: false,
12
+ openWorldHint: true,
13
+ },
10
14
  props: {
11
15
  app,
12
- loginToken: {
16
+ accountId: {
13
17
  propDefinition: [
14
18
  app,
15
- "loginToken",
19
+ "accountId",
16
20
  ],
17
21
  },
18
22
  keyword: {
19
- type: "string",
20
- label: "Keyword",
21
- description: "Search keyword to find relevant profiles",
22
- optional: true,
23
+ propDefinition: [
24
+ app,
25
+ "keyword",
26
+ ],
27
+ description: "Free-text keyword to search people by (e.g. name, title, or company).",
23
28
  },
24
29
  firstName: {
25
30
  type: "string",
26
31
  label: "First Name",
27
- description: "First name parameter for advanced keyword search",
32
+ description: "Filter by first name.",
28
33
  optional: true,
29
34
  },
30
35
  lastName: {
31
36
  type: "string",
32
37
  label: "Last Name",
33
- description: "Last name parameter for advanced keyword search",
38
+ description: "Filter by last name.",
34
39
  optional: true,
35
40
  },
36
41
  title: {
37
42
  type: "string",
38
- label: "Job Title",
39
- description: "Job title parameter for advanced keyword search",
43
+ label: "Title",
44
+ description: "Filter by current job title.",
40
45
  optional: true,
41
46
  },
42
- companyUrl: {
47
+ companyName: {
48
+ type: "string",
49
+ label: "Company Name",
50
+ description: "Filter by current company name.",
51
+ optional: true,
52
+ },
53
+ location: {
43
54
  propDefinition: [
44
55
  app,
45
- "companyUrl",
56
+ "location",
46
57
  ],
47
58
  },
48
- location: {
49
- description: "Geographic locations to filter profiles",
59
+ companyUrl: {
50
60
  propDefinition: [
51
61
  app,
52
- "location",
62
+ "companyUrl",
53
63
  ],
54
64
  },
65
+ pastCompany: {
66
+ type: "string[]",
67
+ label: "Past Companies",
68
+ description: "Filter by past companies, passed as an array of LinkedIn company URLs.",
69
+ optional: true,
70
+ },
55
71
  schoolUrl: {
56
72
  type: "string[]",
57
73
  label: "School URLs",
58
- description: "LinkedIn school URLs",
74
+ description: "Filter by schools, passed as an array of LinkedIn school URLs.",
75
+ optional: true,
76
+ },
77
+ industry: {
78
+ type: "string[]",
79
+ label: "Industries",
80
+ description: "Filter by industries, passed as an array of strings.",
59
81
  optional: true,
60
82
  },
61
83
  network: {
62
84
  type: "string[]",
63
- label: "Network Connection Level",
64
- description: "Filter by connection level",
65
- options: [
66
- {
67
- value: "F",
68
- label: "First-degree connections (1st)",
69
- },
70
- {
71
- value: "S",
72
- label: "Second-degree connections (2nd)",
73
- },
74
- {
75
- value: "O",
76
- label: "Out-of-network connections (3rd+)",
77
- },
78
- ],
85
+ label: "Network",
86
+ description: "Filter by network degree, passed as an array (e.g. `[\"F\"]` for 1st, `[\"S\"]` for 2nd, `[\"O\"]` for 3rd+).",
79
87
  optional: true,
80
88
  },
81
- totalResults: {
82
- type: "integer",
83
- label: "Total Results",
84
- description: "Number of profiles to retrieve (default: `10`)",
89
+ connectionOf: {
90
+ type: "string",
91
+ label: "Connection Of",
92
+ description: "Return people who are connections of this profile (LinkedIn profile URN or public identifier).",
93
+ optional: true,
94
+ },
95
+ followerOf: {
96
+ type: "string",
97
+ label: "Follower Of",
98
+ description: "Return people who are followers of this profile (LinkedIn profile URN or public identifier).",
85
99
  optional: true,
86
100
  },
87
101
  fetchInvitationState: {
88
102
  type: "boolean",
89
103
  label: "Fetch Invitation State",
90
- description: "Whether to fetch the invitation/connection status for each profile",
104
+ description: "Whether to include each result's connection/invitation state.",
91
105
  optional: true,
92
106
  },
93
- country: {
107
+ totalResults: {
94
108
  propDefinition: [
95
109
  app,
96
- "country",
110
+ "totalResults",
97
111
  ],
98
112
  },
99
113
  },
100
- annotations: {
101
- readOnlyHint: true,
102
- destructiveHint: false,
103
- openWorldHint: true,
104
- idempotentHint: true,
105
- },
106
114
  async run({ $ }) {
107
- const {
108
- app,
109
- loginToken,
110
- country,
111
- keyword,
112
- firstName,
113
- lastName,
114
- title,
115
- companyUrl,
116
- location,
117
- schoolUrl,
118
- network,
119
- totalResults,
120
- fetchInvitationState,
121
- } = this;
122
-
123
- const response = await app.searchProfiles({
115
+ const response = await this.app.searchProfiles({
124
116
  $,
125
- data: {
126
- login_token: loginToken,
127
- country,
128
- keyword,
129
- first_name: firstName,
130
- last_name: lastName,
131
- title,
132
- company_url: utils.getOptionalProp(companyUrl),
133
- location: utils.getOptionalProp(location),
134
- school_url: utils.getOptionalProp(schoolUrl),
135
- network: utils.getOptionalProp(network, ","),
136
- fetch_invitation_state: fetchInvitationState,
137
- total_results: totalResults,
117
+ accountId: this.accountId,
118
+ params: {
119
+ keyword: this.keyword,
120
+ first_name: this.firstName,
121
+ last_name: this.lastName,
122
+ title: this.title,
123
+ company_name: this.companyName,
124
+ location: this.location,
125
+ company_url: this.companyUrl,
126
+ past_company: this.pastCompany,
127
+ school_url: this.schoolUrl,
128
+ industry: this.industry,
129
+ network: this.network,
130
+ connection_of: this.connectionOf,
131
+ follower_of: this.followerOf,
132
+ fetch_invitation_state: this.fetchInvitationState,
133
+ total_results: this.totalResults,
138
134
  },
139
135
  });
140
136
 
141
- $.export("$summary", "Successfully retrieved profiles");
137
+ const count = response.data?.results?.length || 0;
138
+ $.export("$summary", `Successfully retrieved ${count} profile${count === 1
139
+ ? ""
140
+ : "s"}`);
142
141
  return response;
143
142
  },
144
143
  };
@@ -2,22 +2,22 @@ import app from "../../linkupapi.app.mjs";
2
2
 
3
3
  export default {
4
4
  type: "action",
5
+ ai: "optimized",
5
6
  key: "linkupapi-send-message",
6
7
  name: "Send Message",
7
- description: "Send a message to a LinkedIn profile. [See the documentation](https://docs.linkupapi.com/api-reference/linkup/Messages/send)",
8
- version: "0.0.2",
8
+ description: "Send a message to a LinkedIn profile. Make sure you are already connected to the recipient. [See the documentation](https://docs.linkupapi.com/api-reference/v2/messages/send)",
9
+ version: "1.0.1",
10
+ annotations: {
11
+ readOnlyHint: false,
12
+ destructiveHint: false,
13
+ openWorldHint: true,
14
+ },
9
15
  props: {
10
16
  app,
11
- // eslint-disable-next-line pipedream/props-label, pipedream/props-description
12
- info: {
13
- type: "alert",
14
- alertType: "info",
15
- content: "Make sure you previously connected to the LinkedIn profile you want to send a message to.",
16
- },
17
- loginToken: {
17
+ accountId: {
18
18
  propDefinition: [
19
19
  app,
20
- "loginToken",
20
+ "accountId",
21
21
  ],
22
22
  },
23
23
  linkedinUrl: {
@@ -25,6 +25,7 @@ export default {
25
25
  app,
26
26
  "linkedinUrl",
27
27
  ],
28
+ description: "LinkedIn profile URL of the recipient. Eg. `https://www.linkedin.com/in/john-doe/`.",
28
29
  },
29
30
  messageText: {
30
31
  propDefinition: [
@@ -32,47 +33,25 @@ export default {
32
33
  "messageText",
33
34
  ],
34
35
  },
35
- country: {
36
- propDefinition: [
37
- app,
38
- "country",
39
- ],
36
+ mediaLink: {
37
+ type: "string",
38
+ label: "Media Link",
39
+ description: "URL of a media attachment (image, document, etc.) to include with the message.",
40
+ optional: true,
40
41
  },
41
42
  },
42
- annotations: {
43
- readOnlyHint: false,
44
- destructiveHint: true,
45
- openWorldHint: true,
46
- idempotentHint: false,
47
- },
48
43
  async run({ $ }) {
49
- const {
50
- app,
51
- linkedinUrl,
52
- messageText,
53
- loginToken,
54
- country,
55
- } = this;
56
-
57
- try {
58
- const response = await app.sendMessage({
59
- $,
60
- data: {
61
- linkedin_url: linkedinUrl,
62
- message_text: messageText,
63
- login_token: loginToken,
64
- country,
65
- },
66
- });
67
-
68
- $.export("$summary", "Successfully sent message request");
44
+ const response = await this.app.sendMessage({
45
+ $,
46
+ accountId: this.accountId,
47
+ params: {
48
+ profile_url: this.linkedinUrl,
49
+ message_text: this.messageText,
50
+ media_link: this.mediaLink,
51
+ },
52
+ });
69
53
 
70
- return response;
71
- } catch (error) {
72
- if (error.response?.data?.data === "Invalid parameter") {
73
- throw new Error("Invalid parameter. Make sure you previously connected to the LinkedIn profile you want to send a message to.");
74
- }
75
- throw error;
76
- }
54
+ $.export("$summary", `Successfully sent message to ${this.linkedinUrl}`);
55
+ return response;
77
56
  },
78
57
  };