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()
}
pub async fn send(
&self,
channel: &str, 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
}
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
}
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
}
}