universal-mcp-applications 0.1.32__py3-none-any.whl → 0.1.36rc2__py3-none-any.whl
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.
- universal_mcp/applications/ahrefs/app.py +52 -198
- universal_mcp/applications/airtable/app.py +23 -122
- universal_mcp/applications/apollo/app.py +111 -464
- universal_mcp/applications/asana/app.py +417 -1567
- universal_mcp/applications/aws_s3/app.py +36 -103
- universal_mcp/applications/bill/app.py +546 -1957
- universal_mcp/applications/box/app.py +1068 -3981
- universal_mcp/applications/braze/app.py +364 -1430
- universal_mcp/applications/browser_use/app.py +2 -8
- universal_mcp/applications/cal_com_v2/app.py +207 -625
- universal_mcp/applications/calendly/app.py +61 -200
- universal_mcp/applications/canva/app.py +45 -110
- universal_mcp/applications/clickup/app.py +207 -674
- universal_mcp/applications/coda/app.py +146 -426
- universal_mcp/applications/confluence/app.py +310 -1098
- universal_mcp/applications/contentful/app.py +36 -151
- universal_mcp/applications/crustdata/app.py +28 -107
- universal_mcp/applications/dialpad/app.py +283 -756
- universal_mcp/applications/digitalocean/app.py +1766 -5777
- universal_mcp/applications/domain_checker/app.py +3 -54
- universal_mcp/applications/e2b/app.py +14 -64
- universal_mcp/applications/elevenlabs/app.py +9 -47
- universal_mcp/applications/exa/app.py +6 -17
- universal_mcp/applications/falai/app.py +24 -101
- universal_mcp/applications/figma/app.py +53 -137
- universal_mcp/applications/file_system/app.py +2 -13
- universal_mcp/applications/firecrawl/app.py +51 -152
- universal_mcp/applications/fireflies/app.py +59 -281
- universal_mcp/applications/fpl/app.py +91 -528
- universal_mcp/applications/fpl/utils/fixtures.py +15 -49
- universal_mcp/applications/fpl/utils/helper.py +25 -89
- universal_mcp/applications/fpl/utils/league_utils.py +20 -64
- universal_mcp/applications/ghost_content/app.py +52 -161
- universal_mcp/applications/github/app.py +19 -56
- universal_mcp/applications/gong/app.py +88 -248
- universal_mcp/applications/google_calendar/app.py +16 -68
- universal_mcp/applications/google_docs/app.py +85 -189
- universal_mcp/applications/google_drive/app.py +141 -463
- universal_mcp/applications/google_gemini/app.py +12 -64
- universal_mcp/applications/google_mail/app.py +28 -157
- universal_mcp/applications/google_searchconsole/app.py +15 -48
- universal_mcp/applications/google_sheet/app.py +100 -581
- universal_mcp/applications/google_sheet/helper.py +10 -37
- universal_mcp/applications/hashnode/app.py +57 -269
- universal_mcp/applications/heygen/app.py +44 -122
- universal_mcp/applications/http_tools/app.py +10 -32
- universal_mcp/applications/hubspot/api_segments/crm_api.py +460 -1573
- universal_mcp/applications/hubspot/api_segments/marketing_api.py +74 -262
- universal_mcp/applications/hubspot/app.py +23 -87
- universal_mcp/applications/jira/app.py +2071 -7986
- universal_mcp/applications/klaviyo/app.py +494 -1376
- universal_mcp/applications/linkedin/README.md +9 -2
- universal_mcp/applications/linkedin/app.py +240 -181
- universal_mcp/applications/mailchimp/app.py +450 -1605
- universal_mcp/applications/markitdown/app.py +8 -20
- universal_mcp/applications/miro/app.py +217 -699
- universal_mcp/applications/ms_teams/app.py +64 -186
- universal_mcp/applications/neon/app.py +86 -192
- universal_mcp/applications/notion/app.py +21 -36
- universal_mcp/applications/onedrive/app.py +16 -38
- universal_mcp/applications/openai/app.py +42 -165
- universal_mcp/applications/outlook/app.py +24 -84
- universal_mcp/applications/perplexity/app.py +4 -19
- universal_mcp/applications/pipedrive/app.py +832 -3142
- universal_mcp/applications/posthog/app.py +163 -432
- universal_mcp/applications/reddit/app.py +40 -139
- universal_mcp/applications/resend/app.py +41 -107
- universal_mcp/applications/retell/app.py +14 -41
- universal_mcp/applications/rocketlane/app.py +221 -934
- universal_mcp/applications/scraper/README.md +7 -4
- universal_mcp/applications/scraper/app.py +50 -109
- universal_mcp/applications/semanticscholar/app.py +22 -64
- universal_mcp/applications/semrush/app.py +43 -77
- universal_mcp/applications/sendgrid/app.py +512 -1262
- universal_mcp/applications/sentry/app.py +271 -906
- universal_mcp/applications/serpapi/app.py +40 -143
- universal_mcp/applications/sharepoint/app.py +17 -39
- universal_mcp/applications/shopify/app.py +1551 -4287
- universal_mcp/applications/shortcut/app.py +155 -417
- universal_mcp/applications/slack/app.py +33 -115
- universal_mcp/applications/spotify/app.py +126 -325
- universal_mcp/applications/supabase/app.py +104 -213
- universal_mcp/applications/tavily/app.py +1 -1
- universal_mcp/applications/trello/app.py +693 -2656
- universal_mcp/applications/twilio/app.py +14 -50
- universal_mcp/applications/twitter/api_segments/compliance_api.py +4 -14
- universal_mcp/applications/twitter/api_segments/dm_conversations_api.py +6 -18
- universal_mcp/applications/twitter/api_segments/likes_api.py +1 -3
- universal_mcp/applications/twitter/api_segments/lists_api.py +5 -15
- universal_mcp/applications/twitter/api_segments/trends_api.py +1 -3
- universal_mcp/applications/twitter/api_segments/tweets_api.py +9 -31
- universal_mcp/applications/twitter/api_segments/usage_api.py +1 -5
- universal_mcp/applications/twitter/api_segments/users_api.py +14 -42
- universal_mcp/applications/whatsapp/app.py +35 -186
- universal_mcp/applications/whatsapp/audio.py +2 -6
- universal_mcp/applications/whatsapp/whatsapp.py +17 -51
- universal_mcp/applications/whatsapp_business/app.py +70 -283
- universal_mcp/applications/wrike/app.py +45 -118
- universal_mcp/applications/yahoo_finance/app.py +19 -65
- universal_mcp/applications/youtube/app.py +75 -261
- universal_mcp/applications/zenquotes/app.py +2 -2
- {universal_mcp_applications-0.1.32.dist-info → universal_mcp_applications-0.1.36rc2.dist-info}/METADATA +2 -2
- {universal_mcp_applications-0.1.32.dist-info → universal_mcp_applications-0.1.36rc2.dist-info}/RECORD +105 -105
- {universal_mcp_applications-0.1.32.dist-info → universal_mcp_applications-0.1.36rc2.dist-info}/WHEEL +0 -0
- {universal_mcp_applications-0.1.32.dist-info → universal_mcp_applications-0.1.36rc2.dist-info}/licenses/LICENSE +0 -0
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import json
|
|
2
2
|
import os
|
|
3
3
|
from typing import Any, Callable, Literal
|
|
4
|
-
|
|
5
4
|
from loguru import logger
|
|
6
5
|
from universal_mcp.applications.application import APIApplication
|
|
7
6
|
from universal_mcp.integrations import Integration
|
|
@@ -23,7 +22,6 @@ class LinkedinApp(APIApplication):
|
|
|
23
22
|
`{"headers": {"x-api-key": "YOUR_API_KEY"}}`.
|
|
24
23
|
"""
|
|
25
24
|
super().__init__(name="linkedin", integration=integration)
|
|
26
|
-
|
|
27
25
|
self._base_url = None
|
|
28
26
|
self.account_id = None
|
|
29
27
|
if self.integration:
|
|
@@ -36,12 +34,8 @@ class LinkedinApp(APIApplication):
|
|
|
36
34
|
if not self._base_url:
|
|
37
35
|
unipile_dsn = os.getenv("UNIPILE_DSN")
|
|
38
36
|
if not unipile_dsn:
|
|
39
|
-
logger.error(
|
|
40
|
-
|
|
41
|
-
)
|
|
42
|
-
raise ValueError(
|
|
43
|
-
"UnipileApp: UNIPILE_DSN environment variable is required."
|
|
44
|
-
)
|
|
37
|
+
logger.error("UnipileApp: UNIPILE_DSN environment variable is not set.")
|
|
38
|
+
raise ValueError("UnipileApp: UNIPILE_DSN environment variable is required.")
|
|
45
39
|
self._base_url = f"https://{unipile_dsn}"
|
|
46
40
|
return self._base_url
|
|
47
41
|
|
|
@@ -56,27 +50,14 @@ class LinkedinApp(APIApplication):
|
|
|
56
50
|
Overrides the base class method to use X-Api-Key.
|
|
57
51
|
"""
|
|
58
52
|
if not self.integration:
|
|
59
|
-
logger.warning(
|
|
60
|
-
"UnipileApp: No integration configured, returning empty headers."
|
|
61
|
-
)
|
|
53
|
+
logger.warning("UnipileApp: No integration configured, returning empty headers.")
|
|
62
54
|
return {}
|
|
63
|
-
|
|
64
55
|
api_key = os.getenv("UNIPILE_API_KEY")
|
|
65
56
|
if not api_key:
|
|
66
|
-
logger.error(
|
|
67
|
-
|
|
68
|
-
)
|
|
69
|
-
return { # Or return minimal headers if some calls might not need auth (unlikely for Unipile)
|
|
70
|
-
"Content-Type": "application/json",
|
|
71
|
-
"Cache-Control": "no-cache",
|
|
72
|
-
}
|
|
73
|
-
|
|
57
|
+
logger.error("UnipileApp: API key not found in integration credentials for Unipile.")
|
|
58
|
+
return {"Content-Type": "application/json", "Cache-Control": "no-cache"}
|
|
74
59
|
logger.debug("UnipileApp: Using X-Api-Key for authentication.")
|
|
75
|
-
return {
|
|
76
|
-
"x-api-key": api_key,
|
|
77
|
-
"Content-Type": "application/json",
|
|
78
|
-
"Cache-Control": "no-cache", # Often good practice for APIs
|
|
79
|
-
}
|
|
60
|
+
return {"x-api-key": api_key, "Content-Type": "application/json", "Cache-Control": "no-cache"}
|
|
80
61
|
|
|
81
62
|
def _get_search_parameter_id(self, param_type: str, keywords: str) -> str:
|
|
82
63
|
"""
|
|
@@ -94,29 +75,21 @@ class LinkedinApp(APIApplication):
|
|
|
94
75
|
httpx.HTTPError: If the API request fails.
|
|
95
76
|
"""
|
|
96
77
|
url = f"{self.base_url}/api/v1/linkedin/search/parameters"
|
|
97
|
-
params = {
|
|
98
|
-
"account_id": self.account_id,
|
|
99
|
-
"keywords": keywords,
|
|
100
|
-
"type": param_type,
|
|
101
|
-
}
|
|
102
|
-
|
|
78
|
+
params = {"account_id": self.account_id, "keywords": keywords, "type": param_type}
|
|
103
79
|
response = self._get(url, params=params)
|
|
104
80
|
results = self._handle_response(response)
|
|
105
|
-
|
|
106
81
|
items = results.get("items", [])
|
|
107
82
|
if items:
|
|
108
|
-
# Return the ID of the first result, assuming it's the most relevant
|
|
109
83
|
return items[0]["id"]
|
|
110
|
-
|
|
111
84
|
raise ValueError(f'Could not find a matching ID for {param_type}: "{keywords}"')
|
|
112
85
|
|
|
113
|
-
def list_all_chats(
|
|
86
|
+
async def list_all_chats(
|
|
114
87
|
self,
|
|
115
88
|
unread: bool | None = None,
|
|
116
89
|
cursor: str | None = None,
|
|
117
|
-
before: str | None = None,
|
|
118
|
-
after: str | None = None,
|
|
119
|
-
limit: int | None = None,
|
|
90
|
+
before: str | None = None,
|
|
91
|
+
after: str | None = None,
|
|
92
|
+
limit: int | None = None,
|
|
120
93
|
account_type: str | None = None,
|
|
121
94
|
) -> dict[str, Any]:
|
|
122
95
|
"""
|
|
@@ -141,9 +114,7 @@ class LinkedinApp(APIApplication):
|
|
|
141
114
|
"""
|
|
142
115
|
url = f"{self.base_url}/api/v1/chats"
|
|
143
116
|
params: dict[str, Any] = {}
|
|
144
|
-
|
|
145
117
|
params["account_id"] = self.account_id
|
|
146
|
-
|
|
147
118
|
if unread is not None:
|
|
148
119
|
params["unread"] = unread
|
|
149
120
|
if cursor:
|
|
@@ -156,18 +127,16 @@ class LinkedinApp(APIApplication):
|
|
|
156
127
|
params["limit"] = limit
|
|
157
128
|
if account_type:
|
|
158
129
|
params["account_type"] = account_type
|
|
159
|
-
|
|
160
|
-
|
|
161
130
|
response = self._get(url, params=params)
|
|
162
131
|
return response.json()
|
|
163
132
|
|
|
164
|
-
def list_chat_messages(
|
|
133
|
+
async def list_chat_messages(
|
|
165
134
|
self,
|
|
166
135
|
chat_id: str,
|
|
167
136
|
cursor: str | None = None,
|
|
168
|
-
before: str | None = None,
|
|
169
|
-
after: str | None = None,
|
|
170
|
-
limit: int | None = None,
|
|
137
|
+
before: str | None = None,
|
|
138
|
+
after: str | None = None,
|
|
139
|
+
limit: int | None = None,
|
|
171
140
|
sender_id: str | None = None,
|
|
172
141
|
) -> dict[str, Any]:
|
|
173
142
|
"""
|
|
@@ -202,15 +171,10 @@ class LinkedinApp(APIApplication):
|
|
|
202
171
|
params["limit"] = limit
|
|
203
172
|
if sender_id:
|
|
204
173
|
params["sender_id"] = sender_id
|
|
205
|
-
|
|
206
174
|
response = self._get(url, params=params)
|
|
207
175
|
return response.json()
|
|
208
176
|
|
|
209
|
-
def send_chat_message(
|
|
210
|
-
self,
|
|
211
|
-
chat_id: str,
|
|
212
|
-
text: str,
|
|
213
|
-
) -> dict[str, Any]:
|
|
177
|
+
async def send_chat_message(self, chat_id: str, text: str) -> dict[str, Any]:
|
|
214
178
|
"""
|
|
215
179
|
Sends a text message to a specific chat conversation using its `chat_id`. This function creates a new message via a POST request, distinguishing it from read-only functions like `list_chat_messages`. It returns the API's response, which typically confirms the successful creation of the message.
|
|
216
180
|
|
|
@@ -230,11 +194,10 @@ class LinkedinApp(APIApplication):
|
|
|
230
194
|
"""
|
|
231
195
|
url = f"{self.base_url}/api/v1/chats/{chat_id}/messages"
|
|
232
196
|
payload: dict[str, Any] = {"text": text}
|
|
233
|
-
|
|
234
197
|
response = self._post(url, data=payload)
|
|
235
198
|
return response.json()
|
|
236
199
|
|
|
237
|
-
def retrieve_chat(self, chat_id: str) -> dict[str, Any]:
|
|
200
|
+
async def retrieve_chat(self, chat_id: str) -> dict[str, Any]:
|
|
238
201
|
"""
|
|
239
202
|
Retrieves a single chat's details using its Unipile or provider-specific ID. This function is distinct from `list_all_chats`, which returns a collection, by targeting one specific conversation.
|
|
240
203
|
|
|
@@ -254,16 +217,15 @@ class LinkedinApp(APIApplication):
|
|
|
254
217
|
params: dict[str, Any] = {}
|
|
255
218
|
if self.account_id:
|
|
256
219
|
params["account_id"] = self.account_id
|
|
257
|
-
|
|
258
220
|
response = self._get(url, params=params)
|
|
259
221
|
return response.json()
|
|
260
222
|
|
|
261
|
-
def list_all_messages(
|
|
223
|
+
async def list_all_messages(
|
|
262
224
|
self,
|
|
263
225
|
cursor: str | None = None,
|
|
264
|
-
before: str | None = None,
|
|
265
|
-
after: str | None = None,
|
|
266
|
-
limit: int | None = None,
|
|
226
|
+
before: str | None = None,
|
|
227
|
+
after: str | None = None,
|
|
228
|
+
limit: int | None = None,
|
|
267
229
|
sender_id: str | None = None,
|
|
268
230
|
) -> dict[str, Any]:
|
|
269
231
|
"""
|
|
@@ -299,16 +261,11 @@ class LinkedinApp(APIApplication):
|
|
|
299
261
|
params["sender_id"] = sender_id
|
|
300
262
|
if self.account_id:
|
|
301
263
|
params["account_id"] = self.account_id
|
|
302
|
-
|
|
303
264
|
response = self._get(url, params=params)
|
|
304
265
|
return response.json()
|
|
305
266
|
|
|
306
|
-
def list_profile_posts(
|
|
307
|
-
self,
|
|
308
|
-
identifier: str, # User or Company provider internal ID
|
|
309
|
-
cursor: str | None = None,
|
|
310
|
-
limit: int | None = None, # 1-100 (spec says max 250)
|
|
311
|
-
is_company: bool | None = None,
|
|
267
|
+
async def list_profile_posts(
|
|
268
|
+
self, identifier: str, cursor: str | None = None, limit: int | None = None, is_company: bool | None = None
|
|
312
269
|
) -> dict[str, Any]:
|
|
313
270
|
"""
|
|
314
271
|
Retrieves a paginated list of posts from a specific user or company profile using their provider ID. An authorizing `account_id` is required, and the `is_company` flag must specify the entity type, distinguishing this from `retrieve_post` which fetches a single post by its own ID.
|
|
@@ -336,11 +293,10 @@ class LinkedinApp(APIApplication):
|
|
|
336
293
|
params["limit"] = limit
|
|
337
294
|
if is_company is not None:
|
|
338
295
|
params["is_company"] = is_company
|
|
339
|
-
|
|
340
296
|
response = self._get(url, params=params)
|
|
341
297
|
return response.json()
|
|
342
298
|
|
|
343
|
-
def retrieve_own_profile(self) -> dict[str, Any]:
|
|
299
|
+
async def retrieve_own_profile(self) -> dict[str, Any]:
|
|
344
300
|
"""
|
|
345
301
|
Retrieves the profile details for the user associated with the Unipile account. This function targets the API's 'me' endpoint to fetch the authenticated user's profile, distinct from `retrieve_user_profile` which fetches profiles of other users by their public identifier.
|
|
346
302
|
|
|
@@ -358,7 +314,7 @@ class LinkedinApp(APIApplication):
|
|
|
358
314
|
response = self._get(url, params=params)
|
|
359
315
|
return response.json()
|
|
360
316
|
|
|
361
|
-
def retrieve_post(self, post_id: str) -> dict[str, Any]:
|
|
317
|
+
async def retrieve_post(self, post_id: str) -> dict[str, Any]:
|
|
362
318
|
"""
|
|
363
319
|
Fetches a specific post's details by its unique ID. Unlike `list_profile_posts`, which retrieves a collection of posts from a user or company profile, this function targets one specific post and returns its full object.
|
|
364
320
|
|
|
@@ -379,18 +335,14 @@ class LinkedinApp(APIApplication):
|
|
|
379
335
|
response = self._get(url, params=params)
|
|
380
336
|
return response.json()
|
|
381
337
|
|
|
382
|
-
def list_post_comments(
|
|
383
|
-
self,
|
|
384
|
-
post_id: str,
|
|
385
|
-
comment_id: str | None = None,
|
|
386
|
-
cursor: str | None = None,
|
|
387
|
-
limit: int | None = None,
|
|
338
|
+
async def list_post_comments(
|
|
339
|
+
self, post_id: str, comment_id: str | None = None, cursor: str | None = None, limit: int | None = None
|
|
388
340
|
) -> dict[str, Any]:
|
|
389
341
|
"""
|
|
390
|
-
Fetches comments for a specific post. Providing an optional `comment_id` retrieves threaded replies instead of top-level comments.
|
|
342
|
+
Fetches comments for a specific post. Providing an optional `comment_id` retrieves threaded replies instead of top-level comments. `retrieve_post` or `list_profile_posts` can be used to obtain the `post_id` which is the social_id in their response.
|
|
391
343
|
|
|
392
344
|
Args:
|
|
393
|
-
post_id: The social ID of the post.
|
|
345
|
+
post_id: The social ID of the post which you get from using `retrieve_post` or `list_profile_posts` tools.
|
|
394
346
|
comment_id: If provided, retrieves replies to this comment ID instead of top-level comments.
|
|
395
347
|
cursor: Pagination cursor.
|
|
396
348
|
limit: Number of comments to return. (OpenAPI spec shows type string, passed as string if provided).
|
|
@@ -412,15 +364,11 @@ class LinkedinApp(APIApplication):
|
|
|
412
364
|
params["limit"] = str(limit)
|
|
413
365
|
if comment_id:
|
|
414
366
|
params["comment_id"] = comment_id
|
|
415
|
-
|
|
416
367
|
response = self._get(url, params=params)
|
|
417
368
|
return response.json()
|
|
418
369
|
|
|
419
|
-
def create_post(
|
|
420
|
-
self,
|
|
421
|
-
text: str,
|
|
422
|
-
mentions: list[dict[str, Any]] | None = None,
|
|
423
|
-
external_link: str | None = None,
|
|
370
|
+
async def create_post(
|
|
371
|
+
self, text: str, mentions: list[dict[str, Any]] | None = None, external_link: str | None = None
|
|
424
372
|
) -> dict[str, Any]:
|
|
425
373
|
"""
|
|
426
374
|
Publishes a new top-level post from the account, including text, user mentions, and an external link. This function creates original content, distinguishing it from `create_post_comment` which adds replies to existing posts.
|
|
@@ -441,26 +389,16 @@ class LinkedinApp(APIApplication):
|
|
|
441
389
|
linkedin, post, create, share, content, api, important
|
|
442
390
|
"""
|
|
443
391
|
url = f"{self.base_url}/api/v1/posts"
|
|
444
|
-
|
|
445
|
-
params: dict[str, str] = {
|
|
446
|
-
"account_id": self.account_id,
|
|
447
|
-
"text": text,
|
|
448
|
-
}
|
|
449
|
-
|
|
392
|
+
params: dict[str, str] = {"account_id": self.account_id, "text": text}
|
|
450
393
|
if mentions:
|
|
451
394
|
params["mentions"] = mentions
|
|
452
395
|
if external_link:
|
|
453
396
|
params["external_link"] = external_link
|
|
454
|
-
|
|
455
397
|
response = self._post(url, data=params)
|
|
456
398
|
return response.json()
|
|
457
399
|
|
|
458
|
-
def list_content_reactions(
|
|
459
|
-
self,
|
|
460
|
-
post_id: str,
|
|
461
|
-
comment_id: str | None = None,
|
|
462
|
-
cursor: str | None = None,
|
|
463
|
-
limit: int | None = None,
|
|
400
|
+
async def list_content_reactions(
|
|
401
|
+
self, post_id: str, comment_id: str | None = None, cursor: str | None = None, limit: int | None = None
|
|
464
402
|
) -> dict[str, Any]:
|
|
465
403
|
"""
|
|
466
404
|
Retrieves a paginated list of reactions for a given post or, optionally, a specific comment. This read-only operation uses the account for the request, distinguishing it from the `create_reaction` function which adds new reactions.
|
|
@@ -488,16 +426,11 @@ class LinkedinApp(APIApplication):
|
|
|
488
426
|
params["limit"] = limit
|
|
489
427
|
if comment_id:
|
|
490
428
|
params["comment_id"] = comment_id
|
|
491
|
-
|
|
492
429
|
response = self._get(url, params=params)
|
|
493
430
|
return response.json()
|
|
494
431
|
|
|
495
|
-
def create_post_comment(
|
|
496
|
-
self,
|
|
497
|
-
post_social_id: str,
|
|
498
|
-
text: str,
|
|
499
|
-
comment_id: str | None = None, # If provided, replies to a specific comment
|
|
500
|
-
mentions_body: list[dict[str, Any]] | None = None,
|
|
432
|
+
async def create_post_comment(
|
|
433
|
+
self, post_social_id: str, text: str, comment_id: str | None = None, mentions_body: list[dict[str, Any]] | None = None
|
|
501
434
|
) -> dict[str, Any]:
|
|
502
435
|
"""
|
|
503
436
|
Publishes a comment on a specified post. By providing an optional `comment_id`, it creates a threaded reply to an existing comment instead of a new top-level one. This function's dual capability distinguishes it from `list_post_comments`, which only retrieves comments and their replies.
|
|
@@ -519,33 +452,21 @@ class LinkedinApp(APIApplication):
|
|
|
519
452
|
linkedin, post, comment, create, content, api, important
|
|
520
453
|
"""
|
|
521
454
|
url = f"{self.base_url}/api/v1/posts/{post_social_id}/comments"
|
|
522
|
-
params: dict[str, Any] = {
|
|
523
|
-
"account_id": self.account_id,
|
|
524
|
-
"text": text,
|
|
525
|
-
}
|
|
526
|
-
|
|
455
|
+
params: dict[str, Any] = {"account_id": self.account_id, "text": text}
|
|
527
456
|
if comment_id:
|
|
528
457
|
params["comment_id"] = comment_id
|
|
529
|
-
|
|
530
458
|
if mentions_body:
|
|
531
459
|
params = {"mentions": mentions_body}
|
|
532
|
-
|
|
533
460
|
response = self._post(url, data=params)
|
|
534
|
-
|
|
535
461
|
try:
|
|
536
462
|
return response.json()
|
|
537
463
|
except json.JSONDecodeError:
|
|
538
|
-
return {
|
|
539
|
-
"status": response.status_code,
|
|
540
|
-
"message": "Comment action processed.",
|
|
541
|
-
}
|
|
464
|
+
return {"status": response.status_code, "message": "Comment action processed."}
|
|
542
465
|
|
|
543
|
-
def create_reaction(
|
|
466
|
+
async def create_reaction(
|
|
544
467
|
self,
|
|
545
468
|
post_social_id: str,
|
|
546
|
-
reaction_type: Literal[
|
|
547
|
-
"like", "celebrate", "love", "insightful", "funny", "support"
|
|
548
|
-
],
|
|
469
|
+
reaction_type: Literal["like", "celebrate", "love", "insightful", "funny", "support"],
|
|
549
470
|
comment_id: str | None = None,
|
|
550
471
|
) -> dict[str, Any]:
|
|
551
472
|
"""
|
|
@@ -566,32 +487,21 @@ class LinkedinApp(APIApplication):
|
|
|
566
487
|
linkedin, post, reaction, create, like, content, api, important
|
|
567
488
|
"""
|
|
568
489
|
url = f"{self.base_url}/api/v1/posts/reaction"
|
|
569
|
-
|
|
570
|
-
params: dict[str, str] = {
|
|
571
|
-
"account_id": self.account_id,
|
|
572
|
-
"post_id": post_social_id,
|
|
573
|
-
"reaction_type": reaction_type,
|
|
574
|
-
}
|
|
575
|
-
|
|
490
|
+
params: dict[str, str] = {"account_id": self.account_id, "post_id": post_social_id, "reaction_type": reaction_type}
|
|
576
491
|
if comment_id:
|
|
577
492
|
params["comment_id"] = comment_id
|
|
578
|
-
|
|
579
493
|
response = self._post(url, data=params)
|
|
580
|
-
|
|
581
494
|
try:
|
|
582
495
|
return response.json()
|
|
583
496
|
except json.JSONDecodeError:
|
|
584
|
-
return {
|
|
585
|
-
"status": response.status_code,
|
|
586
|
-
"message": "Reaction action processed.",
|
|
587
|
-
}
|
|
497
|
+
return {"status": response.status_code, "message": "Reaction action processed."}
|
|
588
498
|
|
|
589
|
-
def retrieve_user_profile(self,
|
|
499
|
+
async def retrieve_user_profile(self, public_identifier: str) -> dict[str, Any]:
|
|
590
500
|
"""
|
|
591
501
|
Retrieves a specific LinkedIn user's profile using their public or internal ID. Unlike `retrieve_own_profile`, which fetches the authenticated user's details, this function targets and returns data for any specified third-party user profile on the platform.
|
|
592
502
|
|
|
593
503
|
Args:
|
|
594
|
-
|
|
504
|
+
public_identifier: Extract this value from the response of `search_people` tool. The response contains a public_identifier field.For example, for https://www.linkedin.com/in/manojbajaj95/, the identifier is "manojbajaj95".
|
|
595
505
|
|
|
596
506
|
Returns:
|
|
597
507
|
A dictionary containing the user's profile details.
|
|
@@ -602,12 +512,12 @@ class LinkedinApp(APIApplication):
|
|
|
602
512
|
Tags:
|
|
603
513
|
linkedin, user, profile, retrieve, get, api, important
|
|
604
514
|
"""
|
|
605
|
-
url = f"{self.base_url}/api/v1/users/{
|
|
515
|
+
url = f"{self.base_url}/api/v1/users/{public_identifier}"
|
|
606
516
|
params: dict[str, Any] = {"account_id": self.account_id}
|
|
607
517
|
response = self._get(url, params=params)
|
|
608
518
|
return self._handle_response(response)
|
|
609
519
|
|
|
610
|
-
def search_people(
|
|
520
|
+
async def search_people(
|
|
611
521
|
self,
|
|
612
522
|
cursor: str | None = None,
|
|
613
523
|
limit: int | None = None,
|
|
@@ -618,47 +528,43 @@ class LinkedinApp(APIApplication):
|
|
|
618
528
|
) -> dict[str, Any]:
|
|
619
529
|
"""
|
|
620
530
|
Searches for LinkedIn user profiles using keywords, with optional filters for location, industry, and company. This function specifically targets the 'people' category, distinguishing it from other search methods like `search_companies` or `search_jobs` that query different entity types through the same API endpoint.
|
|
621
|
-
|
|
531
|
+
|
|
622
532
|
Args:
|
|
623
533
|
cursor: Pagination cursor for the next page of entries.
|
|
624
534
|
limit: Number of items to return (up to 50 for Classic search).
|
|
625
535
|
keywords: Keywords to search for.
|
|
626
|
-
|
|
536
|
+
location: The geographical location to filter people by (e.g., "United States").
|
|
537
|
+
industry: The industry to filter people by.(eg., "Information Technology and Services").
|
|
538
|
+
company: The company to filter people by.(e.g., "Google").
|
|
539
|
+
|
|
627
540
|
Returns:
|
|
628
541
|
A dictionary containing search results and pagination details.
|
|
629
|
-
|
|
542
|
+
|
|
630
543
|
Raises:
|
|
631
544
|
httpx.HTTPError: If the API request fails.
|
|
632
545
|
"""
|
|
633
546
|
url = f"{self.base_url}/api/v1/linkedin/search"
|
|
634
|
-
|
|
635
547
|
params: dict[str, Any] = {"account_id": self.account_id}
|
|
636
548
|
if cursor:
|
|
637
549
|
params["cursor"] = cursor
|
|
638
550
|
if limit is not None:
|
|
639
551
|
params["limit"] = limit
|
|
640
|
-
|
|
641
552
|
payload: dict[str, Any] = {"api": "classic", "category": "people"}
|
|
642
|
-
|
|
643
553
|
if keywords:
|
|
644
554
|
payload["keywords"] = keywords
|
|
645
|
-
|
|
646
555
|
if location:
|
|
647
556
|
location_id = self._get_search_parameter_id("LOCATION", location)
|
|
648
557
|
payload["location"] = [location_id]
|
|
649
|
-
|
|
650
558
|
if industry:
|
|
651
559
|
industry_id = self._get_search_parameter_id("INDUSTRY", industry)
|
|
652
560
|
payload["industry"] = [industry_id]
|
|
653
|
-
|
|
654
561
|
if company:
|
|
655
562
|
company_id = self._get_search_parameter_id("COMPANY", company)
|
|
656
563
|
payload["company"] = [company_id]
|
|
657
|
-
|
|
658
564
|
response = self._post(url, params=params, data=payload)
|
|
659
565
|
return self._handle_response(response)
|
|
660
566
|
|
|
661
|
-
def search_companies(
|
|
567
|
+
async def search_companies(
|
|
662
568
|
self,
|
|
663
569
|
cursor: str | None = None,
|
|
664
570
|
limit: int | None = None,
|
|
@@ -668,43 +574,39 @@ class LinkedinApp(APIApplication):
|
|
|
668
574
|
) -> dict[str, Any]:
|
|
669
575
|
"""
|
|
670
576
|
Performs a paginated search for companies on LinkedIn using keywords, with optional location and industry filters. Its specific 'companies' search category distinguishes it from other methods like `search_people` or `search_posts`, ensuring that only company profiles are returned.
|
|
671
|
-
|
|
577
|
+
|
|
672
578
|
Args:
|
|
673
579
|
cursor: Pagination cursor for the next page of entries.
|
|
674
580
|
limit: Number of items to return (up to 50 for Classic search).
|
|
675
581
|
keywords: Keywords to search for.
|
|
676
|
-
|
|
582
|
+
location: The geographical location to filter companies by (e.g., "United States").
|
|
583
|
+
industry: The industry to filter companies by.(e.g., "Information Technology and Services").
|
|
584
|
+
|
|
677
585
|
Returns:
|
|
678
586
|
A dictionary containing search results and pagination details.
|
|
679
|
-
|
|
587
|
+
|
|
680
588
|
Raises:
|
|
681
589
|
httpx.HTTPError: If the API request fails.
|
|
682
590
|
"""
|
|
683
591
|
url = f"{self.base_url}/api/v1/linkedin/search"
|
|
684
|
-
|
|
685
592
|
params: dict[str, Any] = {"account_id": self.account_id}
|
|
686
593
|
if cursor:
|
|
687
594
|
params["cursor"] = cursor
|
|
688
595
|
if limit is not None:
|
|
689
596
|
params["limit"] = limit
|
|
690
|
-
|
|
691
597
|
payload: dict[str, Any] = {"api": "classic", "category": "companies"}
|
|
692
|
-
|
|
693
598
|
if keywords:
|
|
694
599
|
payload["keywords"] = keywords
|
|
695
|
-
|
|
696
600
|
if location:
|
|
697
601
|
location_id = self._get_search_parameter_id("LOCATION", location)
|
|
698
602
|
payload["location"] = [location_id]
|
|
699
|
-
|
|
700
603
|
if industry:
|
|
701
604
|
industry_id = self._get_search_parameter_id("INDUSTRY", industry)
|
|
702
605
|
payload["industry"] = [industry_id]
|
|
703
|
-
|
|
704
606
|
response = self._post(url, params=params, data=payload)
|
|
705
607
|
return self._handle_response(response)
|
|
706
608
|
|
|
707
|
-
def search_posts(
|
|
609
|
+
async def search_posts(
|
|
708
610
|
self,
|
|
709
611
|
cursor: str | None = None,
|
|
710
612
|
limit: int | None = None,
|
|
@@ -714,41 +616,37 @@ class LinkedinApp(APIApplication):
|
|
|
714
616
|
) -> dict[str, Any]:
|
|
715
617
|
"""
|
|
716
618
|
Performs a keyword-based search for LinkedIn posts, allowing filters for date and sorting by relevance. This function executes a general, platform-wide content search, distinguishing it from other search functions that target people, companies, or jobs, and from `list_profile_posts` which retrieves from a specific profile.
|
|
717
|
-
|
|
619
|
+
|
|
718
620
|
Args:
|
|
719
621
|
cursor: Pagination cursor for the next page of entries.
|
|
720
622
|
limit: Number of items to return (up to 50 for Classic search).
|
|
721
623
|
keywords: Keywords to search for.
|
|
722
624
|
date_posted: Filter by when the post was posted.
|
|
723
625
|
sort_by: How to sort the results.
|
|
724
|
-
|
|
626
|
+
|
|
725
627
|
Returns:
|
|
726
628
|
A dictionary containing search results and pagination details.
|
|
727
|
-
|
|
629
|
+
|
|
728
630
|
Raises:
|
|
729
631
|
httpx.HTTPError: If the API request fails.
|
|
730
632
|
"""
|
|
731
633
|
url = f"{self.base_url}/api/v1/linkedin/search"
|
|
732
|
-
|
|
733
634
|
params: dict[str, Any] = {"account_id": self.account_id}
|
|
734
635
|
if cursor:
|
|
735
636
|
params["cursor"] = cursor
|
|
736
637
|
if limit is not None:
|
|
737
638
|
params["limit"] = limit
|
|
738
|
-
|
|
739
639
|
payload: dict[str, Any] = {"api": "classic", "category": "posts"}
|
|
740
|
-
|
|
741
640
|
if keywords:
|
|
742
641
|
payload["keywords"] = keywords
|
|
743
642
|
if date_posted:
|
|
744
643
|
payload["date_posted"] = date_posted
|
|
745
644
|
if sort_by:
|
|
746
645
|
payload["sort_by"] = sort_by
|
|
747
|
-
|
|
748
646
|
response = self._post(url, params=params, data=payload)
|
|
749
647
|
return self._handle_response(response)
|
|
750
648
|
|
|
751
|
-
def search_jobs(
|
|
649
|
+
async def search_jobs(
|
|
752
650
|
self,
|
|
753
651
|
cursor: str | None = None,
|
|
754
652
|
limit: int | None = None,
|
|
@@ -760,56 +658,212 @@ class LinkedinApp(APIApplication):
|
|
|
760
658
|
) -> dict[str, Any]:
|
|
761
659
|
"""
|
|
762
660
|
Performs a LinkedIn search for jobs, filtering results by keywords, region, industry, and minimum salary. Unlike other search functions (`search_people`, `search_companies`), this method is specifically configured to query the 'jobs' category, providing a paginated list of relevant employment opportunities.
|
|
763
|
-
|
|
661
|
+
|
|
764
662
|
Args:
|
|
765
663
|
cursor: Pagination cursor for the next page of entries.
|
|
766
664
|
limit: Number of items to return (up to 50 for Classic search).
|
|
767
665
|
keywords: Keywords to search for.
|
|
768
|
-
|
|
769
|
-
sort_by: How to sort the results.
|
|
666
|
+
region: The geographical region to filter jobs by (e.g., "United States").
|
|
667
|
+
sort_by: How to sort the results.(e.g., "relevance" or "date".)
|
|
770
668
|
minimum_salary_value: The minimum salary to filter for.
|
|
771
|
-
|
|
669
|
+
industry: The industry to filter jobs by.(e.g., "Software Development").
|
|
670
|
+
|
|
772
671
|
Returns:
|
|
773
672
|
A dictionary containing search results and pagination details.
|
|
774
|
-
|
|
673
|
+
|
|
775
674
|
Raises:
|
|
776
675
|
httpx.HTTPError: If the API request fails.
|
|
777
676
|
ValueError: If the specified location is not found.
|
|
778
677
|
"""
|
|
779
678
|
url = f"{self.base_url}/api/v1/linkedin/search"
|
|
780
|
-
|
|
781
679
|
params: dict[str, Any] = {"account_id": self.account_id}
|
|
782
680
|
if cursor:
|
|
783
681
|
params["cursor"] = cursor
|
|
784
682
|
if limit is not None:
|
|
785
683
|
params["limit"] = limit
|
|
786
|
-
|
|
787
684
|
payload: dict[str, Any] = {
|
|
788
685
|
"api": "classic",
|
|
789
686
|
"category": "jobs",
|
|
790
|
-
"minimum_salary": {
|
|
791
|
-
"currency": "USD",
|
|
792
|
-
"value": minimum_salary_value,
|
|
793
|
-
},
|
|
687
|
+
"minimum_salary": {"currency": "USD", "value": minimum_salary_value},
|
|
794
688
|
}
|
|
795
|
-
|
|
796
689
|
if keywords:
|
|
797
690
|
payload["keywords"] = keywords
|
|
798
691
|
if sort_by:
|
|
799
692
|
payload["sort_by"] = sort_by
|
|
800
|
-
|
|
801
|
-
# If location is provided, get its ID and add it to the payload
|
|
802
693
|
if region:
|
|
803
694
|
location_id = self._get_search_parameter_id("LOCATION", region)
|
|
804
695
|
payload["region"] = location_id
|
|
805
|
-
|
|
806
696
|
if industry:
|
|
807
697
|
industry_id = self._get_search_parameter_id("INDUSTRY", industry)
|
|
808
698
|
payload["industry"] = [industry_id]
|
|
809
|
-
|
|
810
699
|
response = self._post(url, params=params, data=payload)
|
|
811
700
|
return self._handle_response(response)
|
|
812
701
|
|
|
702
|
+
async def send_invitation(self, provider_id: str, user_email: str | None = None, message: str | None = None) -> dict[str, Any]:
|
|
703
|
+
"""
|
|
704
|
+
Sends a connection invitation to a LinkedIn user specified by their provider ID. An optional message and the user's email can be included.
|
|
705
|
+
|
|
706
|
+
Args:
|
|
707
|
+
provider_id: The LinkedIn provider ID of the user to invite. This is available in response of `retrieve_user_profile` tool.
|
|
708
|
+
user_email: Optional. The email address of the user, which may be required by LinkedIn.
|
|
709
|
+
message: Optional. A personalized message to include with the invitation (max 300 characters).
|
|
710
|
+
|
|
711
|
+
Returns:
|
|
712
|
+
A dictionary confirming the invitation was sent.
|
|
713
|
+
|
|
714
|
+
Raises:
|
|
715
|
+
httpx.HTTPError: If the API request fails.
|
|
716
|
+
ValueError: If the message exceeds 300 characters.
|
|
717
|
+
|
|
718
|
+
Tags:
|
|
719
|
+
linkedin, user, invite, connect, contact, api, important
|
|
720
|
+
"""
|
|
721
|
+
url = f"{self.base_url}/api/v1/users/invite"
|
|
722
|
+
payload: dict[str, Any] = {"account_id": self.account_id, "provider_id": provider_id}
|
|
723
|
+
if user_email:
|
|
724
|
+
payload["user_email"] = user_email
|
|
725
|
+
if message:
|
|
726
|
+
if len(message) > 300:
|
|
727
|
+
raise ValueError("Message cannot exceed 300 characters.")
|
|
728
|
+
payload["message"] = message
|
|
729
|
+
response = self._post(url, data=payload)
|
|
730
|
+
try:
|
|
731
|
+
return response.json()
|
|
732
|
+
except json.JSONDecodeError:
|
|
733
|
+
return {"status": response.status_code, "message": "Invitation action processed."}
|
|
734
|
+
|
|
735
|
+
async def list_sent_invitations(self, cursor: str | None = None, limit: int | None = None) -> dict[str, Any]:
|
|
736
|
+
"""
|
|
737
|
+
Retrieves a paginated list of all sent connection invitations that are currently pending. This function allows for iterating through the history of outstanding connection requests made from the specified account.
|
|
738
|
+
|
|
739
|
+
Args:
|
|
740
|
+
cursor: A pagination cursor for retrieving the next page of entries.
|
|
741
|
+
limit: The number of items to return, ranging from 1 to 100. Defaults to 10 if not specified.
|
|
742
|
+
|
|
743
|
+
Returns:
|
|
744
|
+
A dictionary containing a list of sent invitation objects and pagination details.
|
|
745
|
+
|
|
746
|
+
Raises:
|
|
747
|
+
httpx.HTTPError: If the API request fails.
|
|
748
|
+
|
|
749
|
+
Tags:
|
|
750
|
+
linkedin, user, invite, sent, list, contacts, api
|
|
751
|
+
"""
|
|
752
|
+
url = f"{self.base_url}/api/v1/users/invite/sent"
|
|
753
|
+
params: dict[str, Any] = {"account_id": self.account_id}
|
|
754
|
+
if cursor:
|
|
755
|
+
params["cursor"] = cursor
|
|
756
|
+
if limit is not None:
|
|
757
|
+
params["limit"] = limit
|
|
758
|
+
response = self._get(url, params=params)
|
|
759
|
+
return response.json()
|
|
760
|
+
|
|
761
|
+
async def list_received_invitations(self, cursor: str | None = None, limit: int | None = None) -> dict[str, Any]:
|
|
762
|
+
"""
|
|
763
|
+
Retrieves a paginated list of all received connection invitations. This function allows for reviewing and processing incoming connection requests to the specified account.
|
|
764
|
+
|
|
765
|
+
Args:
|
|
766
|
+
cursor: A pagination cursor for retrieving the next page of entries.
|
|
767
|
+
limit: The number of items to return, ranging from 1 to 100. Defaults to 10 if not specified.
|
|
768
|
+
|
|
769
|
+
Returns:
|
|
770
|
+
A dictionary containing a list of received invitation objects and pagination details.
|
|
771
|
+
|
|
772
|
+
Raises:
|
|
773
|
+
httpx.HTTPError: If the API request fails.
|
|
774
|
+
|
|
775
|
+
Tags:
|
|
776
|
+
linkedin, user, invite, received, list, contacts, api
|
|
777
|
+
"""
|
|
778
|
+
url = f"{self.base_url}/api/v1/users/invite/received"
|
|
779
|
+
params: dict[str, Any] = {"account_id": self.account_id}
|
|
780
|
+
if cursor:
|
|
781
|
+
params["cursor"] = cursor
|
|
782
|
+
if limit is not None:
|
|
783
|
+
params["limit"] = limit
|
|
784
|
+
response = self._get(url, params=params)
|
|
785
|
+
return response.json()
|
|
786
|
+
|
|
787
|
+
async def handle_received_invitation(
|
|
788
|
+
self, invitation_id: str, action: Literal["accept", "decline"], shared_secret: str
|
|
789
|
+
) -> dict[str, Any]:
|
|
790
|
+
"""
|
|
791
|
+
Accepts or declines a received LinkedIn connection invitation using its ID and a required shared secret. This function performs a POST request to update the invitation's status, distinguishing it from read-only functions like `list_received_invitations`.
|
|
792
|
+
|
|
793
|
+
Args:
|
|
794
|
+
invitation_id: The ID of the invitation to handle.Get this ID from the 'list_received_invitations' tool.
|
|
795
|
+
action: The action to perform, either "accept" or "decline".
|
|
796
|
+
shared_secret: The token provided by LinkedIn, retrieved from the 'list_received_invitations' tool, which is mandatory for this action.
|
|
797
|
+
|
|
798
|
+
Returns:
|
|
799
|
+
A dictionary confirming the action was processed.
|
|
800
|
+
|
|
801
|
+
Raises:
|
|
802
|
+
httpx.HTTPError: If the API request fails.
|
|
803
|
+
|
|
804
|
+
Tags:
|
|
805
|
+
linkedin, user, invite, received, handle, accept, decline, api
|
|
806
|
+
"""
|
|
807
|
+
url = f"{self.base_url}/api/v1/users/invite/received/{invitation_id}"
|
|
808
|
+
payload: dict[str, Any] = {"provider": "LINKEDIN", "action": action, "shared_secret": shared_secret, "account_id": self.account_id}
|
|
809
|
+
response = self._post(url, data=payload)
|
|
810
|
+
try:
|
|
811
|
+
return response.json()
|
|
812
|
+
except json.JSONDecodeError:
|
|
813
|
+
return {"status": response.status_code, "message": f"Invitation action '{action}' processed."}
|
|
814
|
+
|
|
815
|
+
async def list_followers(self, cursor: str | None = None, limit: int | None = None) -> dict[str, Any]:
|
|
816
|
+
"""
|
|
817
|
+
Retrieves a paginated list of all followers for the current user's account. This function is distinct from `list_following` as it shows who follows the user, not who the user follows.
|
|
818
|
+
|
|
819
|
+
Args:
|
|
820
|
+
cursor: A pagination cursor for retrieving the next page of entries.
|
|
821
|
+
limit: The number of items to return, ranging from 1 to 1000.
|
|
822
|
+
|
|
823
|
+
Returns:
|
|
824
|
+
A dictionary containing a list of follower objects and pagination details.
|
|
825
|
+
|
|
826
|
+
Raises:
|
|
827
|
+
httpx.HTTPError: If the API request fails.
|
|
828
|
+
|
|
829
|
+
Tags:
|
|
830
|
+
linkedin, user, followers, list, contacts, api
|
|
831
|
+
"""
|
|
832
|
+
url = f"{self.base_url}/api/v1/users/followers"
|
|
833
|
+
params: dict[str, Any] = {"account_id": self.account_id}
|
|
834
|
+
if cursor:
|
|
835
|
+
params["cursor"] = cursor
|
|
836
|
+
if limit is not None:
|
|
837
|
+
params["limit"] = limit
|
|
838
|
+
response = self._get(url, params=params)
|
|
839
|
+
return response.json()
|
|
840
|
+
|
|
841
|
+
def list_following(self, cursor: str | None = None, limit: int | None = None) -> dict[str, Any]:
|
|
842
|
+
"""
|
|
843
|
+
Retrieves a paginated list of all accounts that the current user is following. This function is the counterpart to `list_followers`, focusing on the user's outgoing connections rather than incoming ones.
|
|
844
|
+
|
|
845
|
+
Args:
|
|
846
|
+
cursor: A pagination cursor for retrieving the next page of entries.
|
|
847
|
+
limit: The number of items to return, ranging from 1 to 1000.
|
|
848
|
+
|
|
849
|
+
Returns:
|
|
850
|
+
A dictionary containing a list of followed account objects and pagination details.
|
|
851
|
+
|
|
852
|
+
Raises:
|
|
853
|
+
httpx.HTTPError: If the API request fails.
|
|
854
|
+
|
|
855
|
+
Tags:
|
|
856
|
+
linkedin, user, following, list, contacts, api
|
|
857
|
+
"""
|
|
858
|
+
url = f"{self.base_url}/api/v1/users/following"
|
|
859
|
+
params: dict[str, Any] = {"account_id": self.account_id}
|
|
860
|
+
if cursor:
|
|
861
|
+
params["cursor"] = cursor
|
|
862
|
+
if limit is not None:
|
|
863
|
+
params["limit"] = limit
|
|
864
|
+
response = self._get(url, params=params)
|
|
865
|
+
return response.json()
|
|
866
|
+
|
|
813
867
|
def list_tools(self) -> list[Callable]:
|
|
814
868
|
return [
|
|
815
869
|
self.list_all_chats,
|
|
@@ -830,4 +884,9 @@ class LinkedinApp(APIApplication):
|
|
|
830
884
|
self.search_jobs,
|
|
831
885
|
self.search_people,
|
|
832
886
|
self.search_posts,
|
|
887
|
+
self.send_invitation,
|
|
888
|
+
self.list_sent_invitations,
|
|
889
|
+
self.list_received_invitations,
|
|
890
|
+
self.handle_received_invitation,
|
|
891
|
+
self.list_followers,
|
|
833
892
|
]
|