highlevel-api 0.2.0

Unofficial Rust SDK for the GoHighLevel (HighLevel) API
Documentation
use super::types::*;
use crate::{error::Result, http::HttpClient};
use serde::Serialize;
use std::sync::Arc;

pub struct ContactsApi {
    http: Arc<HttpClient>,
}

impl ContactsApi {
    pub fn new(http: Arc<HttpClient>) -> Self {
        Self { http }
    }

    pub async fn search(&self, params: &SearchContactsParams) -> Result<SearchContactsResponse> {
        self.http.get_with_query("/contacts/search", params).await
    }

    pub async fn get(&self, contact_id: &str) -> Result<GetContactResponse> {
        self.http.get(&format!("/contacts/{contact_id}")).await
    }

    pub async fn create(&self, params: &CreateContactParams) -> Result<GetContactResponse> {
        self.http.post("/contacts", params).await
    }

    pub async fn update(
        &self,
        contact_id: &str,
        params: &UpdateContactParams,
    ) -> Result<GetContactResponse> {
        self.http
            .put(&format!("/contacts/{contact_id}"), params)
            .await
    }

    pub async fn delete(&self, contact_id: &str) -> Result<DeleteContactResponse> {
        self.http.delete(&format!("/contacts/{contact_id}")).await
    }

    /// Create or update a contact by email / phone (upsert).
    pub async fn upsert(&self, params: &CreateContactParams) -> Result<UpsertContactResponse> {
        self.http.post("/contacts/upsert", params).await
    }

    // ── Tags ─────────────────────────────────────────────────────────────────

    pub async fn add_tags(&self, contact_id: &str, params: &AddTagsParams) -> Result<TagsResponse> {
        self.http
            .post(&format!("/contacts/{contact_id}/tags"), params)
            .await
    }

    pub async fn remove_tags(
        &self,
        contact_id: &str,
        params: &AddTagsParams,
    ) -> Result<TagsResponse> {
        self.http
            .delete_with_body(&format!("/contacts/{contact_id}/tags"), params)
            .await
    }

    // ── Notes ────────────────────────────────────────────────────────────────

    pub async fn get_notes(&self, contact_id: &str) -> Result<NotesResponse> {
        self.http
            .get(&format!("/contacts/{contact_id}/notes"))
            .await
    }

    pub async fn create_note(
        &self,
        contact_id: &str,
        params: &CreateNoteParams,
    ) -> Result<NoteResponse> {
        self.http
            .post(&format!("/contacts/{contact_id}/notes"), params)
            .await
    }

    pub async fn update_note(
        &self,
        contact_id: &str,
        note_id: &str,
        params: &CreateNoteParams,
    ) -> Result<NoteResponse> {
        self.http
            .put(&format!("/contacts/{contact_id}/notes/{note_id}"), params)
            .await
    }

    pub async fn delete_note(&self, contact_id: &str, note_id: &str) -> Result<NoteResponse> {
        self.http
            .delete(&format!("/contacts/{contact_id}/notes/{note_id}"))
            .await
    }

    // ── Tasks ────────────────────────────────────────────────────────────────

    pub async fn get_tasks(&self, contact_id: &str) -> Result<TasksResponse> {
        self.http
            .get(&format!("/contacts/{contact_id}/tasks"))
            .await
    }

    pub async fn create_task(
        &self,
        contact_id: &str,
        params: &CreateTaskParams,
    ) -> Result<TaskResponse> {
        self.http
            .post(&format!("/contacts/{contact_id}/tasks"), params)
            .await
    }

    pub async fn update_task(
        &self,
        contact_id: &str,
        task_id: &str,
        params: &CreateTaskParams,
    ) -> Result<TaskResponse> {
        self.http
            .put(&format!("/contacts/{contact_id}/tasks/{task_id}"), params)
            .await
    }

    pub async fn delete_task(&self, contact_id: &str, task_id: &str) -> Result<TaskResponse> {
        self.http
            .delete(&format!("/contacts/{contact_id}/tasks/{task_id}"))
            .await
    }

    pub async fn complete_task(
        &self,
        contact_id: &str,
        task_id: &str,
        completed: bool,
    ) -> Result<TaskResponse> {
        #[derive(Serialize)]
        struct Body {
            completed: bool,
        }
        self.http
            .put(
                &format!("/contacts/{contact_id}/tasks/{task_id}/completed"),
                &Body { completed },
            )
            .await
    }
}