Skip to content

Commit 69d8266

Browse files
Add network sync: sync_network, poll_network, network.* webhooks
1 parent e0ba190 commit 69d8266

9 files changed

Lines changed: 115 additions & 2 deletions

File tree

linkedapi/__init__.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,7 @@
6868
SendMessage,
6969
SyncConversation,
7070
SyncInbox,
71+
SyncNetwork,
7172
WithdrawConnectionRequest,
7273
)
7374
from linkedapi.types import * # noqa: F403
@@ -142,6 +143,7 @@
142143
"SimpleWorkflowMapper",
143144
"SyncConversation",
144145
"SyncInbox",
146+
"SyncNetwork",
145147
"ThenWorkflowMapper",
146148
"VoidWorkflowMapper",
147149
"WithdrawConnectionRequest",

linkedapi/client.py

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@
4141
SendMessage,
4242
SyncConversation,
4343
SyncInbox,
44+
SyncNetwork,
4445
WithdrawConnectionRequest,
4546
)
4647
from linkedapi.types import AccountInfo, LinkedApiActionError, serialize_value
@@ -50,6 +51,7 @@
5051
InboxMessage,
5152
InboxPollRequest,
5253
)
54+
from linkedapi.types.network import NetworkEvent, NetworkPollRequest
5355
from linkedapi.types.statistics import ApiUsageAction, ApiUsageParams
5456

5557

@@ -67,6 +69,7 @@ def __init__(self, config: LinkedApiConfig | HttpClient[Any]) -> None:
6769
self.send_message = SendMessage(self.http_client)
6870
self.sync_conversation = SyncConversation(self.http_client)
6971
self.sync_inbox = SyncInbox(self.http_client)
72+
self.sync_network = SyncNetwork(self.http_client)
7073
self.manage_conversation = ManageConversation(self.http_client)
7174
self.check_connection_status = CheckConnectionStatus(self.http_client)
7275
self.send_connection_request = SendConnectionRequest(self.http_client)
@@ -103,6 +106,7 @@ def __init__(self, config: LinkedApiConfig | HttpClient[Any]) -> None:
103106
self.send_message,
104107
self.sync_conversation,
105108
self.sync_inbox,
109+
self.sync_network,
106110
self.manage_conversation,
107111
self.check_connection_status,
108112
self.send_connection_request,
@@ -189,6 +193,30 @@ def poll_inbox(
189193
],
190194
)
191195

196+
def poll_network(
197+
self,
198+
request: NetworkPollRequest | None = None,
199+
) -> MappedResponse[list[NetworkEvent]]:
200+
"""Read the monitored network connection events, newest events first."""
201+
202+
payload = serialize_value(request) if request is not None else {}
203+
response = self.http_client.post("/network/poll", payload)
204+
if response.success and response.result is not None:
205+
events = response.result.get("events", [])
206+
return MappedResponse(
207+
data=[NetworkEvent.model_validate(item) for item in events],
208+
errors=[],
209+
)
210+
return MappedResponse(
211+
data=None,
212+
errors=[
213+
LinkedApiActionError(
214+
type=response.error.type if response.error else "",
215+
message=response.error.message if response.error else "",
216+
),
217+
],
218+
)
219+
192220
def get_account_info(self) -> MappedResponse[AccountInfo]:
193221
"""Retrieve basic information about the current LinkedIn account."""
194222

linkedapi/operations/__init__.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@
3131
from linkedapi.operations.send_message import SendMessage
3232
from linkedapi.operations.sync_conversation import SyncConversation
3333
from linkedapi.operations.sync_inbox import SyncInbox
34+
from linkedapi.operations.sync_network import SyncNetwork
3435
from linkedapi.operations.withdraw_connection_request import WithdrawConnectionRequest
3536

3637
__all__ = [
@@ -73,5 +74,6 @@
7374
"SendMessage",
7475
"SyncConversation",
7576
"SyncInbox",
77+
"SyncNetwork",
7678
"WithdrawConnectionRequest",
7779
]
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
from __future__ import annotations
2+
3+
from linkedapi.core import Operation
4+
from linkedapi.mappers import VoidWorkflowMapper
5+
from linkedapi.types import SyncNetworkParams
6+
7+
8+
class SyncNetwork(Operation[SyncNetworkParams, None]):
9+
"""Enable whole-network monitoring for standard LinkedIn connections."""
10+
11+
operation_name = "syncNetwork"
12+
mapper = VoidWorkflowMapper[SyncNetworkParams]("st.syncNetwork")

linkedapi/types/__init__.py

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -118,6 +118,12 @@
118118
SyncConversationParams,
119119
SyncInboxParams,
120120
)
121+
from linkedapi.types.network import (
122+
NetworkEvent,
123+
NetworkEventType,
124+
NetworkPollRequest,
125+
SyncNetworkParams,
126+
)
121127
from linkedapi.types.params import BaseActionParams, LimitParams, LimitSinceParams
122128
from linkedapi.types.person import (
123129
BaseFetchPersonParams,
@@ -195,6 +201,8 @@
195201
DeleteWebhookParams,
196202
MessageWebhookEvent,
197203
MessageWebhookEventData,
204+
NetworkWebhookEvent,
205+
NetworkWebhookEventData,
198206
ReplayWebhookDeliveryParams,
199207
SetWebhookParams,
200208
SetWebhookPayloadModeParams,
@@ -313,6 +321,11 @@
313321
"MessageWebhookEvent",
314322
"MessageWebhookEventData",
315323
"MinAnnualRevenue",
324+
"NetworkEvent",
325+
"NetworkEventType",
326+
"NetworkPollRequest",
327+
"NetworkWebhookEvent",
328+
"NetworkWebhookEventData",
316329
"NvBaseFetchCompanyParams",
317330
"NvBaseFetchCompanyParamsWide",
318331
"NvCompany",
@@ -401,6 +414,7 @@
401414
"SubscriptionStatusValue",
402415
"SyncConversationParams",
403416
"SyncInboxParams",
417+
"SyncNetworkParams",
404418
"WebhookDelivery",
405419
"WebhookDeliveryStatus",
406420
"WebhookEvent",

linkedapi/types/network.py

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
from __future__ import annotations
2+
3+
from typing import Literal
4+
5+
from linkedapi.types.base import LinkedApiModel
6+
from linkedapi.types.params import BaseActionParams
7+
8+
NetworkEventType = Literal[
9+
"connectionAccepted",
10+
"connectionAdded",
11+
"connectionRequestReceived",
12+
]
13+
14+
15+
class SyncNetworkParams(BaseActionParams):
16+
pass
17+
18+
19+
class NetworkPollRequest(LinkedApiModel):
20+
since: str | None = None
21+
type: NetworkEventType | None = None
22+
23+
24+
class NetworkEvent(LinkedApiModel):
25+
id: str | None = None
26+
type: NetworkEventType | None = None
27+
person_url: str | None = None
28+
detected_at: str | None = None

linkedapi/types/webhooks.py

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,9 @@
1616
"account.deleted",
1717
"inbox.messageReceived",
1818
"inbox.messageSent",
19+
"network.connectionAccepted",
20+
"network.connectionAdded",
21+
"network.connectionRequestReceived",
1922
"webhook.test",
2023
]
2124
WebhookDeliveryStatus = Literal["pending", "delivering", "success", "failed"]
@@ -112,6 +115,23 @@ class MessageWebhookEvent(LinkedApiModel):
112115
data: MessageWebhookEventData
113116

114117

118+
class NetworkWebhookEventData(LinkedApiModel):
119+
account_id: str | None = None
120+
person_url: str | None = None
121+
detected_at: str | None = None
122+
123+
124+
class NetworkWebhookEvent(LinkedApiModel):
125+
id: str
126+
type: Literal[
127+
"network.connectionAccepted",
128+
"network.connectionAdded",
129+
"network.connectionRequestReceived",
130+
]
131+
created_at: str | None = None
132+
data: NetworkWebhookEventData
133+
134+
115135
class WebhookTestEventData(LinkedApiModel):
116136
message: str | None = None
117137

@@ -124,5 +144,9 @@ class WebhookTestEvent(LinkedApiModel):
124144

125145

126146
WebhookEvent = (
127-
WorkflowWebhookEvent | AccountWebhookEvent | MessageWebhookEvent | WebhookTestEvent
147+
WorkflowWebhookEvent
148+
| AccountWebhookEvent
149+
| MessageWebhookEvent
150+
| NetworkWebhookEvent
151+
| WebhookTestEvent
128152
)

linkedapi/webhooks/parse.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
from linkedapi.types.webhooks import (
66
AccountWebhookEvent,
77
MessageWebhookEvent,
8+
NetworkWebhookEvent,
89
WebhookEvent,
910
WebhookTestEvent,
1011
WorkflowWebhookEvent,
@@ -44,6 +45,8 @@ def parse_webhook_event(raw_body: str | bytes) -> WebhookEvent:
4445
return AccountWebhookEvent.model_validate(parsed)
4546
if event_type.startswith("inbox."):
4647
return MessageWebhookEvent.model_validate(parsed)
48+
if event_type.startswith("network."):
49+
return NetworkWebhookEvent.model_validate(parsed)
4750
if event_type == "webhook.test":
4851
return WebhookTestEvent.model_validate(parsed)
4952

pyproject.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
44

55
[project]
66
name = "linkedapi"
7-
version = "1.2.1"
7+
version = "1.3.0"
88
description = "Official synchronous Python SDK for Linked API."
99
readme = "README.md"
1010
requires-python = ">=3.10"

0 commit comments

Comments
 (0)