Skip to main content

highlevel_api/apis/contacts/
client.rs

1use super::types::*;
2use crate::{error::Result, http::HttpClient};
3use serde::Serialize;
4use std::sync::Arc;
5
6pub struct ContactsApi {
7    http: Arc<HttpClient>,
8}
9
10impl ContactsApi {
11    pub fn new(http: Arc<HttpClient>) -> Self {
12        Self { http }
13    }
14
15    pub async fn search(&self, params: &SearchContactsParams) -> Result<SearchContactsResponse> {
16        self.http.get_with_query("/contacts/search", params).await
17    }
18
19    pub async fn get(&self, contact_id: &str) -> Result<GetContactResponse> {
20        self.http.get(&format!("/contacts/{contact_id}")).await
21    }
22
23    pub async fn create(&self, params: &CreateContactParams) -> Result<GetContactResponse> {
24        self.http.post("/contacts", params).await
25    }
26
27    pub async fn update(
28        &self,
29        contact_id: &str,
30        params: &UpdateContactParams,
31    ) -> Result<GetContactResponse> {
32        self.http
33            .put(&format!("/contacts/{contact_id}"), params)
34            .await
35    }
36
37    pub async fn delete(&self, contact_id: &str) -> Result<DeleteContactResponse> {
38        self.http.delete(&format!("/contacts/{contact_id}")).await
39    }
40
41    /// Create or update a contact by email / phone (upsert).
42    pub async fn upsert(&self, params: &CreateContactParams) -> Result<UpsertContactResponse> {
43        self.http.post("/contacts/upsert", params).await
44    }
45
46    // ── Tags ─────────────────────────────────────────────────────────────────
47
48    pub async fn add_tags(&self, contact_id: &str, params: &AddTagsParams) -> Result<TagsResponse> {
49        self.http
50            .post(&format!("/contacts/{contact_id}/tags"), params)
51            .await
52    }
53
54    pub async fn remove_tags(
55        &self,
56        contact_id: &str,
57        params: &AddTagsParams,
58    ) -> Result<TagsResponse> {
59        self.http
60            .delete_with_body(&format!("/contacts/{contact_id}/tags"), params)
61            .await
62    }
63
64    // ── Notes ────────────────────────────────────────────────────────────────
65
66    pub async fn get_notes(&self, contact_id: &str) -> Result<NotesResponse> {
67        self.http
68            .get(&format!("/contacts/{contact_id}/notes"))
69            .await
70    }
71
72    pub async fn create_note(
73        &self,
74        contact_id: &str,
75        params: &CreateNoteParams,
76    ) -> Result<NoteResponse> {
77        self.http
78            .post(&format!("/contacts/{contact_id}/notes"), params)
79            .await
80    }
81
82    pub async fn update_note(
83        &self,
84        contact_id: &str,
85        note_id: &str,
86        params: &CreateNoteParams,
87    ) -> Result<NoteResponse> {
88        self.http
89            .put(&format!("/contacts/{contact_id}/notes/{note_id}"), params)
90            .await
91    }
92
93    pub async fn delete_note(&self, contact_id: &str, note_id: &str) -> Result<NoteResponse> {
94        self.http
95            .delete(&format!("/contacts/{contact_id}/notes/{note_id}"))
96            .await
97    }
98
99    // ── Tasks ────────────────────────────────────────────────────────────────
100
101    pub async fn get_tasks(&self, contact_id: &str) -> Result<TasksResponse> {
102        self.http
103            .get(&format!("/contacts/{contact_id}/tasks"))
104            .await
105    }
106
107    pub async fn create_task(
108        &self,
109        contact_id: &str,
110        params: &CreateTaskParams,
111    ) -> Result<TaskResponse> {
112        self.http
113            .post(&format!("/contacts/{contact_id}/tasks"), params)
114            .await
115    }
116
117    pub async fn update_task(
118        &self,
119        contact_id: &str,
120        task_id: &str,
121        params: &CreateTaskParams,
122    ) -> Result<TaskResponse> {
123        self.http
124            .put(&format!("/contacts/{contact_id}/tasks/{task_id}"), params)
125            .await
126    }
127
128    pub async fn delete_task(&self, contact_id: &str, task_id: &str) -> Result<TaskResponse> {
129        self.http
130            .delete(&format!("/contacts/{contact_id}/tasks/{task_id}"))
131            .await
132    }
133
134    pub async fn complete_task(
135        &self,
136        contact_id: &str,
137        task_id: &str,
138        completed: bool,
139    ) -> Result<TaskResponse> {
140        #[derive(Serialize)]
141        struct Body {
142            completed: bool,
143        }
144        self.http
145            .put(
146                &format!("/contacts/{contact_id}/tasks/{task_id}/completed"),
147                &Body { completed },
148            )
149            .await
150    }
151}