Skip to main content

highlevel_api/apis/contacts/
client.rs

1use std::sync::Arc;
2use serde::Serialize;
3use crate::{error::Result, http::HttpClient};
4use super::types::*;
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.put(&format!("/contacts/{contact_id}"), params).await
33    }
34
35    pub async fn delete(&self, contact_id: &str) -> Result<DeleteContactResponse> {
36        self.http.delete(&format!("/contacts/{contact_id}")).await
37    }
38
39    /// Create or update a contact by email / phone (upsert).
40    pub async fn upsert(&self, params: &CreateContactParams) -> Result<UpsertContactResponse> {
41        self.http.post("/contacts/upsert", params).await
42    }
43
44    // ── Tags ─────────────────────────────────────────────────────────────────
45
46    pub async fn add_tags(
47        &self,
48        contact_id: &str,
49        params: &AddTagsParams,
50    ) -> Result<TagsResponse> {
51        self.http.post(&format!("/contacts/{contact_id}/tags"), params).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.get(&format!("/contacts/{contact_id}/notes")).await
68    }
69
70    pub async fn create_note(
71        &self,
72        contact_id: &str,
73        params: &CreateNoteParams,
74    ) -> Result<NoteResponse> {
75        self.http.post(&format!("/contacts/{contact_id}/notes"), params).await
76    }
77
78    pub async fn update_note(
79        &self,
80        contact_id: &str,
81        note_id: &str,
82        params: &CreateNoteParams,
83    ) -> Result<NoteResponse> {
84        self.http
85            .put(&format!("/contacts/{contact_id}/notes/{note_id}"), params)
86            .await
87    }
88
89    pub async fn delete_note(&self, contact_id: &str, note_id: &str) -> Result<NoteResponse> {
90        self.http
91            .delete(&format!("/contacts/{contact_id}/notes/{note_id}"))
92            .await
93    }
94
95    // ── Tasks ────────────────────────────────────────────────────────────────
96
97    pub async fn get_tasks(&self, contact_id: &str) -> Result<TasksResponse> {
98        self.http.get(&format!("/contacts/{contact_id}/tasks")).await
99    }
100
101    pub async fn create_task(
102        &self,
103        contact_id: &str,
104        params: &CreateTaskParams,
105    ) -> Result<TaskResponse> {
106        self.http.post(&format!("/contacts/{contact_id}/tasks"), params).await
107    }
108
109    pub async fn update_task(
110        &self,
111        contact_id: &str,
112        task_id: &str,
113        params: &CreateTaskParams,
114    ) -> Result<TaskResponse> {
115        self.http
116            .put(&format!("/contacts/{contact_id}/tasks/{task_id}"), params)
117            .await
118    }
119
120    pub async fn delete_task(
121        &self,
122        contact_id: &str,
123        task_id: &str,
124    ) -> Result<TaskResponse> {
125        self.http
126            .delete(&format!("/contacts/{contact_id}/tasks/{task_id}"))
127            .await
128    }
129
130    pub async fn complete_task(
131        &self,
132        contact_id: &str,
133        task_id: &str,
134        completed: bool,
135    ) -> Result<TaskResponse> {
136        #[derive(Serialize)]
137        struct Body {
138            completed: bool,
139        }
140        self.http
141            .put(
142                &format!("/contacts/{contact_id}/tasks/{task_id}/completed"),
143                &Body { completed },
144            )
145            .await
146    }
147}