aurabase 0.1.1

Official Rust SDK for Aurabase: high-performance open-source Backend-as-a-Service (BaaS)
Documentation
use crate::client::{AuraClient, RequestBody};
use crate::error::AuraError;
use crate::types::{AuraResponse, Notification, NotificationTemplate};
use serde::{Deserialize, Serialize};
use std::collections::HashMap;

pub struct NotificationsService {
    client: AuraClient,
}

#[derive(Debug, Clone, Default)]
pub struct SendNotificationOptions {
    pub subject: Option<String>,
    pub template_id: Option<String>,
    pub variables: Option<HashMap<String, serde_json::Value>>,
    pub metadata: Option<HashMap<String, serde_json::Value>>,
    pub idempotency_key: Option<String>,
}

#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct SendNotificationRequest {
    pub channel: String,
    pub recipient: String,
    pub body: Option<String>,
    pub subject: Option<String>,
    pub template_id: Option<String>,
    pub variables: Option<HashMap<String, serde_json::Value>>,
    pub metadata: Option<HashMap<String, serde_json::Value>>,
    pub idempotency_key: Option<String>,
}

#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct BatchSendItemResult {
    pub index: usize,
    pub status: String,
    pub notification: Option<Notification>,
    pub error: Option<String>,
}

#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct BatchSendResponse {
    pub items: Vec<BatchSendItemResult>,
}

#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct CreateNotificationTemplateRequest {
    pub name: String,
    pub channel: String,
    pub subject: Option<String>,
    pub body: String,
}

#[derive(Debug, Clone, Default, Serialize, Deserialize)]
pub struct UpdateNotificationTemplateRequest {
    pub subject: Option<String>,
    pub body: Option<String>,
}

impl NotificationsService {
    pub fn new(client: AuraClient) -> Self {
        Self { client }
    }

    fn prefix(&self) -> String {
        "/v1/notifications".to_string()
    }

    // -- Envoi ---------------------------------------------------------------

    pub async fn send(
        &self,
        channel: &str, // 'email', 'sms', 'push', 'webhook'
        recipient: &str,
        body: &str,
        options: Option<SendNotificationOptions>,
    ) -> Result<AuraResponse<Notification>, AuraError> {
        let opts = options.unwrap_or_default();
        let body_payload = serde_json::json!({
            "channel": channel,
            "recipient": recipient,
            "body": body,
            "subject": opts.subject,
            "template_id": opts.template_id,
            "variables": opts.variables,
            "metadata": opts.metadata,
            "idempotency_key": opts.idempotency_key,
        });

        self.client
            .request(
                reqwest::Method::POST,
                &format!("{}/send", self.prefix()),
                RequestBody::Json(body_payload),
            )
            .await
    }

    pub async fn send_batch(
        &self,
        items: Vec<SendNotificationRequest>,
    ) -> Result<AuraResponse<BatchSendResponse>, AuraError> {
        let body_payload = serde_json::json!({ "items": items });

        self.client
            .request(
                reqwest::Method::POST,
                &format!("{}/send/batch", self.prefix()),
                RequestBody::Json(body_payload),
            )
            .await
    }

    // -- Historique ----------------------------------------------------------

    pub async fn list(
        &self,
        limit: Option<u32>,
        offset: Option<u32>,
    ) -> Result<AuraResponse<Vec<Notification>>, AuraError> {
        let mut query = Vec::new();
        if let Some(l) = limit {
            query.push(format!("limit={}", l));
        }
        if let Some(o) = offset {
            query.push(format!("offset={}", o));
        }

        let qs = if query.is_empty() {
            "".to_string()
        } else {
            format!("?{}", query.join("&"))
        };

        self.client
            .request(
                reqwest::Method::GET,
                &format!("{}{}", self.prefix(), qs),
                RequestBody::None,
            )
            .await
    }

    pub async fn get(&self, id: &str) -> Result<AuraResponse<Notification>, AuraError> {
        self.client
            .request(
                reqwest::Method::GET,
                &format!("{}/{}", self.prefix(), id),
                RequestBody::None,
            )
            .await
    }

    pub async fn retry(&self, id: &str) -> Result<AuraResponse<Notification>, AuraError> {
        self.client
            .request(
                reqwest::Method::POST,
                &format!("{}/{}/retry", self.prefix(), id),
                RequestBody::Json(serde_json::json!({})),
            )
            .await
    }

    // -- Templates -----------------------------------------------------------

    pub async fn list_templates(
        &self,
    ) -> Result<AuraResponse<Vec<NotificationTemplate>>, AuraError> {
        self.client
            .request(
                reqwest::Method::GET,
                &format!("{}/templates", self.prefix()),
                RequestBody::None,
            )
            .await
    }

    pub async fn get_template(
        &self,
        id: &str,
    ) -> Result<AuraResponse<NotificationTemplate>, AuraError> {
        self.client
            .request(
                reqwest::Method::GET,
                &format!("{}/templates/{}", self.prefix(), id),
                RequestBody::None,
            )
            .await
    }

    pub async fn create_template(
        &self,
        template: CreateNotificationTemplateRequest,
    ) -> Result<AuraResponse<NotificationTemplate>, AuraError> {
        let body = serde_json::to_value(&template).unwrap_or_default();
        self.client
            .request(
                reqwest::Method::POST,
                &format!("{}/templates", self.prefix()),
                RequestBody::Json(body),
            )
            .await
    }

    pub async fn update_template(
        &self,
        id: &str,
        updates: UpdateNotificationTemplateRequest,
    ) -> Result<AuraResponse<NotificationTemplate>, AuraError> {
        let body = serde_json::to_value(&updates).unwrap_or_default();
        self.client
            .request(
                reqwest::Method::PATCH,
                &format!("{}/templates/{}", self.prefix(), id),
                RequestBody::Json(body),
            )
            .await
    }

    pub async fn delete_template(
        &self,
        id: &str,
    ) -> Result<AuraResponse<serde_json::Value>, AuraError> {
        self.client
            .request(
                reqwest::Method::DELETE,
                &format!("{}/templates/{}", self.prefix(), id),
                RequestBody::None,
            )
            .await
    }

    pub async fn preview_template(
        &self,
        id: &str,
        variables: serde_json::Value,
    ) -> Result<AuraResponse<serde_json::Value>, AuraError> {
        self.client
            .request(
                reqwest::Method::POST,
                &format!("{}/templates/{}/preview", self.prefix(), id),
                RequestBody::Json(variables),
            )
            .await
    }
}