ghl-sdk 0.5.0

Unofficial async Rust SDK for the GoHighLevel (HighLevel) API 2.0 — OAuth 2.0, Private Integration Tokens, rate-limit-aware retries, paginated streams
Documentation
// @generated by xtask/generate_services.py — do not edit by hand.
//! `chat-widget` — typed methods for all 8 API v3 operations
//! in this module.
//!
//! Access via [`Ghl::v3`](crate::Ghl::v3)`().chat_widget()`. These endpoints send `Version: v3`.
//!
//! Request and response types come from [`ghl_models::v3::chat_widget`](https://docs.rs/ghl-models/latest/ghl_models/v3/chat_widget/); every endpoint is also documented in the
//! [`chat-widget` API reference](https://github.com/Shahroz/ghl-rs/blob/main/docs/api/chat-widget.md).
//!
//! Enable with `features = ["chat-widget"]`.

#![allow(clippy::too_many_arguments)]

use crate::client::Ghl;
use crate::error::Result;
use ghl_models::v3::chat_widget as models;

/// Typed access to the `chat-widget` API v3 surface (8 operations). Obtained via
/// [`Ghl::v3`](crate::Ghl::v3)`().chat_widget()`.
#[derive(Debug, Clone)]
pub struct ChatWidgetService {
    pub(crate) client: Ghl,
}

impl ChatWidgetService {
    pub(crate) fn new(client: Ghl) -> Self {
        Self { client }
    }
}

/// Query parameters for [`ChatWidgetService::list_chat_widgets`].
#[derive(Debug, Clone, Default)]
pub struct ListChatWidgetsParams {
    /// The location ID
    /// Required by the API.
    pub location_id: String,
    /// Offset
    /// Required by the API.
    pub offset: String,
    /// Limit
    /// Required by the API.
    pub limit: String,
    /// The type of chat widget. Supports normal ChatType values, plus the virtual umbrella
    /// "webChat" (maps to facebookChat/emailChat/instagramChat/waChat).
    /// Allowed values: `liveChat`, `waChat`, `emailChat`, `allInOneChat`, `voiceAiChat`,
    /// `facebookChat`, `instagramChat`, `webChat`.
    pub chat_type: Option<String>,
    /// The type of chat widget
    /// Allowed values: `liveChat`, `waChat`, `emailChat`, `allInOneChat`, `voiceAiChat`,
    /// `facebookChat`, `instagramChat`.
    pub exclude_chat_type: Option<String>,
    /// The voice AI agent ID
    pub voice_ai_agent_id: Option<String>,
    /// All-in-one chat type to filter by. Only applies when chatType is "allInOneChat".
    /// Supports normal ChatType values plus the virtual umbrella "webChat" (maps to
    /// facebookChat/emailChat/instagramChat/waChat).
    /// Allowed values: `liveChat`, `waChat`, `emailChat`, `allInOneChat`, `voiceAiChat`,
    /// `facebookChat`, `instagramChat`, `webChat`.
    pub all_in_one_chat_types: Option<String>,
}

impl ListChatWidgetsParams {
    /// Start from the parameters the API requires.
    pub fn new(
        location_id: impl Into<String>,
        offset: impl Into<String>,
        limit: impl Into<String>,
    ) -> Self {
        Self {
            location_id: location_id.into(),
            offset: offset.into(),
            limit: limit.into(),
            ..Default::default()
        }
    }

    /// The type of chat widget. Supports normal ChatType values, plus the virtual umbrella
    /// "webChat" (maps to facebookChat/emailChat/instagramChat/waChat).
    pub fn chat_type(mut self, v: impl Into<String>) -> Self {
        self.chat_type = Some(v.into());
        self
    }

    /// The type of chat widget
    pub fn exclude_chat_type(mut self, v: impl Into<String>) -> Self {
        self.exclude_chat_type = Some(v.into());
        self
    }

    /// The voice AI agent ID
    pub fn voice_ai_agent_id(mut self, v: impl Into<String>) -> Self {
        self.voice_ai_agent_id = Some(v.into());
        self
    }

    /// All-in-one chat type to filter by. Only applies when chatType is "allInOneChat".
    /// Supports normal ChatType values plus the virtual umbrella "webChat" (maps to
    /// facebookChat/emailChat/instagramChat/waChat).
    pub fn all_in_one_chat_types(mut self, v: impl Into<String>) -> Self {
        self.all_in_one_chat_types = Some(v.into());
        self
    }

    fn to_query(&self) -> Vec<(String, String)> {
        let mut q: Vec<(String, String)> = vec![
            ("locationId".into(), self.location_id.clone()),
            ("offset".into(), self.offset.clone()),
            ("limit".into(), self.limit.clone()),
        ];
        if let Some(v) = &self.chat_type {
            q.push(("chatType".into(), v.to_string()));
        }
        if let Some(v) = &self.exclude_chat_type {
            q.push(("excludeChatType".into(), v.to_string()));
        }
        if let Some(v) = &self.voice_ai_agent_id {
            q.push(("voiceAiAgentId".into(), v.to_string()));
        }
        if let Some(v) = &self.all_in_one_chat_types {
            q.push(("allInOneChatTypes".into(), v.to_string()));
        }
        q
    }
}

/// Query parameters for [`ChatWidgetService::get_widget_config`].
#[derive(Debug, Clone, Default)]
pub struct GetWidgetConfigParams {
    /// `version` query parameter.
    pub version: Option<String>,
}

impl GetWidgetConfigParams {
    /// Start from the parameters the API requires.
    pub fn new() -> Self {
        Self {
            ..Default::default()
        }
    }

    /// Set the `version` query parameter.
    pub fn version(mut self, v: impl Into<String>) -> Self {
        self.version = Some(v.into());
        self
    }

    fn to_query(&self) -> Vec<(String, String)> {
        let mut q: Vec<(String, String)> = Vec::new();
        if let Some(v) = &self.version {
            q.push(("version".into(), v.to_string()));
        }
        q
    }
}

impl ChatWidgetService {
    /// Create Chat Widget
    ///
    /// Creates a new chat widget for the given sub-account.
    ///
    /// `POST /chat-widget/`
    ///
    /// Requires scope: `chat-widget.write`.
    pub async fn create_chat_widget(
        &self,
        body: &models::CreateWidgetDTO,
    ) -> Result<serde_json::Value> {
        let query = Vec::new();
        self.client
            .send_versioned(
                reqwest::Method::POST,
                "/chat-widget/",
                &query,
                Some(body),
                Some("v3"),
            )
            .await
    }

    /// Clone Chat Widget
    ///
    /// Creates a copy of an existing chat widget in the same sub-account.
    ///
    /// `POST /chat-widget/clone`
    ///
    /// Requires scope: `chat-widget.write`.
    pub async fn clone_chat_widget(
        &self,
        body: &models::CloneChatWidgetDTO,
    ) -> Result<serde_json::Value> {
        let query = Vec::new();
        self.client
            .send_versioned(
                reqwest::Method::POST,
                "/chat-widget/clone",
                &query,
                Some(body),
                Some("v3"),
            )
            .await
    }

    /// Get Chat Widget
    ///
    /// Returns a single chat widget by ID.
    ///
    /// `GET /chat-widget/data/{locationId}/{id}`
    ///
    /// Requires scope: `chat-widget.readonly`.
    pub async fn get_chat_widget(&self, location_id: &str, id: &str) -> Result<serde_json::Value> {
        let path = format!(
            "/chat-widget/data/{}/{}",
            crate::services::encode(location_id),
            crate::services::encode(id)
        );
        let query = Vec::new();
        self.client
            .send_versioned(reqwest::Method::GET, &path, &query, None::<&()>, Some("v3"))
            .await
    }

    /// Patch Chat Widget
    ///
    /// Partial update of a chat widget resource.
    ///
    /// `PATCH /chat-widget/data/{locationId}/{id}`
    ///
    /// Requires scope: `chat-widget.write`.
    pub async fn patch_chat_widget(
        &self,
        location_id: &str,
        id: &str,
        body: &models::UpdateWidgetDTO,
    ) -> Result<serde_json::Value> {
        let path = format!(
            "/chat-widget/data/{}/{}",
            crate::services::encode(location_id),
            crate::services::encode(id)
        );
        let query = Vec::new();
        self.client
            .send_versioned(
                reqwest::Method::PATCH,
                &path,
                &query,
                Some(body),
                Some("v3"),
            )
            .await
    }

    /// Update Chat Widget
    ///
    /// Full update of a chat widget resource.
    ///
    /// `PUT /chat-widget/data/{locationId}/{id}`
    ///
    /// Requires scope: `chat-widget.write`.
    pub async fn update_chat_widget(
        &self,
        location_id: &str,
        id: &str,
        body: &models::UpdateWidgetDTO,
    ) -> Result<serde_json::Value> {
        let path = format!(
            "/chat-widget/data/{}/{}",
            crate::services::encode(location_id),
            crate::services::encode(id)
        );
        let query = Vec::new();
        self.client
            .send_versioned(reqwest::Method::PUT, &path, &query, Some(body), Some("v3"))
            .await
    }

    /// List Chat Widgets
    ///
    /// Returns chat widgets for the sub-account with pagination and optional filters.
    ///
    /// `GET /chat-widget/list`
    ///
    /// Requires scope: `chat-widget.readonly`.
    pub async fn list_chat_widgets(
        &self,
        params: &ListChatWidgetsParams,
    ) -> Result<serde_json::Value> {
        let query = params.to_query();
        self.client
            .send_versioned(
                reqwest::Method::GET,
                "/chat-widget/list",
                &query,
                None::<&()>,
                Some("v3"),
            )
            .await
    }

    /// Get Widget Config
    ///
    /// Returns widget configuration by ID.
    ///
    /// `GET /chat-widget/public/config/{id}`
    pub async fn get_widget_config(
        &self,
        id: &str,
        params: &GetWidgetConfigParams,
    ) -> Result<serde_json::Value> {
        let path = format!("/chat-widget/public/config/{}", crate::services::encode(id));
        let query = params.to_query();
        self.client
            .send_versioned(reqwest::Method::GET, &path, &query, None::<&()>, Some("v3"))
            .await
    }

    /// Delete Chat Widget
    ///
    /// Soft-deletes a chat widget. If it was the default, another widget may be promoted.
    ///
    /// `DELETE /chat-widget/{locationId}/{id}`
    ///
    /// Requires scope: `chat-widget.write`.
    pub async fn delete_chat_widget(
        &self,
        location_id: &str,
        id: &str,
    ) -> Result<serde_json::Value> {
        let path = format!(
            "/chat-widget/{}/{}",
            crate::services::encode(location_id),
            crate::services::encode(id)
        );
        let query = Vec::new();
        self.client
            .send_versioned(
                reqwest::Method::DELETE,
                &path,
                &query,
                None::<&()>,
                Some("v3"),
            )
            .await
    }
}