apibrasil 1.0.0

SDK oficial Rust da plataforma APIBrasil: WhatsApp, SMS, consultas de CPF/CNPJ, veiculos, CEP, correios, pagamentos PIX/boleto e mais.
Documentation
use serde_json::json;

use crate::core::{IntoBody, Json, Result};

platform_service! {
    /// Gestão de devices (`/devices/*`).
    ///
    /// Devices são a credencial de consumo dos serviços device-based: crie
    /// um device com a SecretKey da API desejada e use o `device_token`
    /// retornado como header `DeviceToken`.
    ///
    /// ```no_run
    /// # use apibrasil::{ApiBrasil, RequestOptions};
    /// # use serde_json::json;
    /// # async fn exemplo(api: ApiBrasil) -> apibrasil::Result<()> {
    /// let device = api
    ///     .with_options(RequestOptions::new().secret_key("SUA_SECRET_KEY"))
    ///     .devices()
    ///     .store(json!({ "device_name": "meu-bot", "type": "server" }))
    ///     .await?;
    ///
    /// api.set_device_token(device["device_token"].as_str().unwrap_or_default());
    /// # Ok(())
    /// # }
    /// ```
    DevicesService
}

impl DevicesService {
    /// Lista os devices do usuário: `GET /devices`.
    pub async fn list(&self, query: impl IntoBody) -> Result<Json> {
        self.base.get_query("devices", query).await
    }

    /// Cria um device: `POST /devices/store`.
    ///
    /// `body` aceita `device_name`, `type`
    /// (`cellphone` | `tablet` | `computer` | `server`), `device_key`,
    /// `server_search` e os webhooks. A SecretKey da API (painel
    /// APIBrasil) vai no header — informe em
    /// [`RequestOptions::secret_key`](crate::RequestOptions::secret_key) ou configure `secret_key` no
    /// cliente.
    pub async fn store(&self, body: impl IntoBody) -> Result<Json> {
        let mut options = self.base.options().clone();
        if options.secret_key.is_none() {
            options.secret_key = self.base.http().secret_key();
        }
        self.base
            .with_options(options)
            .post("devices/store", body)
            .await
    }

    /// Detalha um device: `GET /devices/show?search={device_token}`.
    /// `None` usa o device configurado no cliente.
    pub async fn show(&self, device_token: Option<&str>) -> Result<Json> {
        let token = self.resolve_token(device_token);
        self.base
            .get_query("devices/show", json!({ "search": token }))
            .await
    }

    /// Remove um device: `DELETE /devices/destroy`.
    /// `None` usa o device configurado no cliente.
    pub async fn destroy(&self, device_token: Option<&str>) -> Result<Json> {
        let token = self.resolve_token(device_token);
        self.base
            .delete("devices/destroy", json!({ "search": token }))
            .await
    }

    fn resolve_token(&self, device_token: Option<&str>) -> String {
        device_token
            .filter(|token| !token.is_empty())
            .map(str::to_string)
            .or_else(|| self.base.http().device_token())
            .unwrap_or_default()
    }
}

json_body! {
    DevicesService {
        /// Atualiza um device: `POST /devices/update`
        /// (body com `device_token` + campos).
        update => post "devices/update",
        /// Histórico de requisições do device:
        /// `POST /devices/requests`.
        requests => post "devices/requests",
    }
}