1use serde_json::Value;
25use std::collections::HashMap;
26
27pub use crate::error::LinkedinError;
28use crate::types::SearchPeopleParams;
29use crate::{
30 linkedin::LinkedinInner,
31 types::{
32 Company, Connection, ContactInfo, Conversation, ConversationDetails, Identity, Invitation,
33 MemberBadges, NetworkInfo, PersonSearchResult, Profile, School, Skill, UniformResourceName,
34 },
35};
36
37pub mod client;
38pub mod error;
39pub mod linkedin;
40pub mod types;
41pub mod utils;
42
43#[derive(Clone)]
45pub struct Linkedin {
46 inner: LinkedinInner,
47}
48
49impl UniformResourceName {
50 pub fn parse(urn: &str) -> Result<Self, LinkedinError> {
51 let parts: Vec<&str> = urn.split(':').collect();
52 if parts.len() < 4 {
53 return Err(LinkedinError::InvalidInput(format!(
54 "Not enough components in URN: {urn}"
55 )));
56 }
57
58 let namespace = parts[2].to_string();
61 let id = parts[3].to_string();
62
63 Ok(Self { namespace, id })
64 }
65
66 pub fn id_str(&self) -> &str {
68 &self.id
69 }
70
71 pub fn as_str(&self) -> String {
73 format!("urn:li:{}:{}", self.namespace, self.id)
74 }
75}
76
77impl AsRef<str> for UniformResourceName {
78 fn as_ref(&self) -> &str {
79 &self.id
80 }
81}
82
83impl Linkedin {
84 pub async fn new(identity: &Identity, refresh_cookies: bool) -> Result<Self, LinkedinError> {
86 let inner = LinkedinInner::new(identity, refresh_cookies).await?;
87 Ok(Self { inner })
88 }
89
90 pub async fn get_profile(&self, public_id: &str) -> Result<Profile, LinkedinError> {
92 self.inner.get_profile(Some(public_id), None).await
93 }
94
95 pub async fn get_profile_by_urn(
97 &self,
98 urn: &UniformResourceName,
99 ) -> Result<Profile, LinkedinError> {
100 self.inner.get_profile(None, Some(urn)).await
101 }
102
103 pub async fn get_profile_connections(
105 &self,
106 urn_id: &str,
107 ) -> Result<Vec<Connection>, LinkedinError> {
108 self.inner.get_profile_connections(urn_id).await
109 }
110
111 pub async fn get_profile_contact_info(
113 &self,
114 public_id: &str,
115 ) -> Result<ContactInfo, LinkedinError> {
116 self.inner
117 .get_profile_contact_info(Some(public_id), None)
118 .await
119 }
120
121 pub async fn get_profile_contact_info_by_urn(
123 &self,
124 urn_id: &UniformResourceName,
125 ) -> Result<ContactInfo, LinkedinError> {
126 self.inner
127 .get_profile_contact_info(None, Some(urn_id))
128 .await
129 }
130
131 pub async fn get_profile_skills(&self, public_id: &str) -> Result<Vec<Skill>, LinkedinError> {
133 self.inner.get_profile_skills(Some(public_id), None).await
134 }
135
136 pub async fn get_profile_skills_by_urn(
138 &self,
139 urn: UniformResourceName,
140 ) -> Result<Vec<Skill>, LinkedinError> {
141 self.inner.get_profile_skills(None, Some(&urn)).await
142 }
143
144 pub async fn get_profile_privacy_settings(
146 &self,
147 public_id: &str,
148 ) -> Result<HashMap<String, Value>, LinkedinError> {
149 self.inner.get_profile_privacy_settings(public_id).await
150 }
151
152 pub async fn get_profile_member_badges(
154 &self,
155 public_id: &str,
156 ) -> Result<MemberBadges, LinkedinError> {
157 self.inner.get_profile_member_badges(public_id).await
158 }
159
160 pub async fn get_profile_network_info(
162 &self,
163 public_id: &str,
164 ) -> Result<NetworkInfo, LinkedinError> {
165 self.inner.get_profile_network_info(public_id).await
166 }
167
168 pub async fn remove_connection(&self, public_id: &str) -> Result<bool, LinkedinError> {
170 self.inner.remove_connection(public_id).await
171 }
172
173 pub async fn get_conversations(&self) -> Result<Vec<Conversation>, LinkedinError> {
175 self.inner.get_conversations().await
176 }
177
178 pub async fn get_conversation_details(
180 &self,
181 profile_urn_id: &str,
182 ) -> Result<ConversationDetails, LinkedinError> {
183 self.inner.get_conversation_details(profile_urn_id).await
184 }
185
186 pub async fn get_conversation(
188 &self,
189 conversation_urn_id: &str,
190 ) -> Result<Conversation, LinkedinError> {
191 self.inner.get_conversation(conversation_urn_id).await
192 }
193
194 pub async fn send_message(
196 &self,
197 conversation_urn_id: Option<&str>,
198 recipients: Option<Vec<String>>,
199 message_body: &str,
200 ) -> Result<bool, LinkedinError> {
201 self.inner
202 .send_message(conversation_urn_id, recipients, message_body)
203 .await
204 }
205
206 pub async fn mark_conversation_as_seen(
208 &self,
209 conversation_urn_id: &str,
210 ) -> Result<bool, LinkedinError> {
211 self.inner
212 .mark_conversation_as_seen(conversation_urn_id)
213 .await
214 }
215
216 pub async fn get_current_profile_views(&self) -> Result<u64, LinkedinError> {
218 self.inner.get_current_profile_views().await
219 }
220
221 pub async fn get_school(&self, public_id: &str) -> Result<School, LinkedinError> {
223 self.inner.get_school(public_id).await
224 }
225
226 pub async fn get_company(&self, public_id: &str) -> Result<Company, LinkedinError> {
228 self.inner.get_company(public_id).await
229 }
230
231 pub async fn search(
233 &self,
234 params: HashMap<String, String>,
235 limit: Option<usize>,
236 ) -> Result<Vec<Value>, LinkedinError> {
237 self.inner.search(params, limit).await
238 }
239
240 pub async fn search_people(
242 &self,
243 params: SearchPeopleParams,
244 ) -> Result<Vec<PersonSearchResult>, LinkedinError> {
245 self.inner.search_people(params).await
246 }
247
248 pub async fn get_company_updates(
250 &self,
251 public_id: Option<&str>,
252 urn_id: Option<&str>,
253 max_results: Option<usize>,
254 ) -> Result<Vec<Value>, LinkedinError> {
255 self.inner
256 .get_company_updates(public_id, urn_id, max_results)
257 .await
258 }
259
260 pub async fn get_profile_updates(
262 &self,
263 public_id: Option<&str>,
264 urn_id: Option<&str>,
265 max_results: Option<usize>,
266 ) -> Result<Vec<Value>, LinkedinError> {
267 self.inner
268 .get_profile_updates(public_id, urn_id, max_results)
269 .await
270 }
271
272 pub async fn get_invitations(
274 &self,
275 start: usize,
276 limit: usize,
277 ) -> Result<Vec<Invitation>, LinkedinError> {
278 self.inner.get_invitations(start, limit).await
279 }
280
281 pub async fn reply_invitation(
283 &self,
284 invitation_entity_urn: &str,
285 invitation_shared_secret: &str,
286 action: &str,
287 ) -> Result<bool, LinkedinError> {
288 self.inner
289 .reply_invitation(invitation_entity_urn, invitation_shared_secret, action)
290 .await
291 }
292
293 pub async fn get_user_profile(&self) -> Result<Value, LinkedinError> {
295 self.inner.get_user_profile().await
296 }
297
298 pub async fn stub_people_search(
300 &self,
301 query: &str,
302 count: usize,
303 start: usize,
304 ) -> Result<Value, LinkedinError> {
305 self.inner.stub_people_search(query, count, start).await
306 }
307}