diff --git a/src/lib.rs b/src/lib.rs index ab06283..ff43d95 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -11,6 +11,7 @@ pub mod layouts; pub mod messages; pub mod subscriber; pub mod utils; +pub mod workflows; use client::Client; use environments::{ApiKey, Environment, EnvironmentPayload}; @@ -21,6 +22,7 @@ use inbound_parse::InboundParse; use layouts::Layouts; use messages::Messages; use serde::{Deserialize, Serialize}; +use workflows::Workflows; #[derive(Debug, Serialize, Deserialize)] pub enum ChannelTypeEnum { @@ -42,6 +44,7 @@ pub struct Novu { pub feeds: Feeds, pub layouts: Layouts, pub messages: Messages, + pub workflows: Workflows, } impl Novu { @@ -50,12 +53,14 @@ impl Novu { let feeds = Feeds::new(client.clone_client()); let layouts = Layouts::new(client.clone_client()); let messages = Messages::new(client.clone_client()); + let workflows = Workflows::new(client.clone_client()); Ok(Self { client, feeds, layouts, messages, + workflows, }) } diff --git a/src/workflows.rs b/src/workflows.rs new file mode 100644 index 0000000..823bf1d --- /dev/null +++ b/src/workflows.rs @@ -0,0 +1,241 @@ +use std::collections::HashMap; + +use crate::{ + client::{Client, Response}, + error::NovuError, + utils::generate_query_string, +}; +use serde::{Deserialize, Serialize}; +use serde_json::Value; + +pub struct Workflows { + client: Client, +} + +#[derive(Debug, Serialize, Deserialize)] +#[serde(rename_all = "camelCase")] +pub struct PreferenceSettings { + pub email: bool, + pub sms: bool, + pub in_app: bool, + pub chat: bool, + pub push: bool, +} + +#[derive(Debug, Serialize, Deserialize)] +#[serde(rename_all = "camelCase")] +pub struct Child { + pub field: String, + pub value: String, + pub operator: String, + pub on: String, +} + +#[derive(Debug, Serialize, Deserialize)] +#[serde(rename_all = "camelCase")] +pub struct Filter { + pub is_negated: bool, + #[serde(rename = "type")] + pub filter_type: String, + pub value: String, + pub children: Vec, +} + +#[derive(Debug, Serialize, Deserialize)] +#[serde(rename_all = "camelCase")] +pub struct MetaData { + pub amount: i32, + pub unit: String, + pub digest_key: String, + #[serde(rename = "type")] + pub metadata_type: String, + pub backoff: bool, + pub backoff_amount: i32, + pub backoff_unit: String, + pub update_mode: bool, +} + +#[derive(Debug, Serialize, Deserialize)] +#[serde(rename_all = "camelCase")] +pub struct Step { + pub _id: String, + pub uuid: String, + pub name: String, + pub _template_id: String, + pub active: bool, + pub should_stop_on_fail: bool, + pub template: Option, + pub filters: Vec, + pub _parent_id: Option, + pub metadata: MetaData, + pub reply_callback: Option, +} + +#[derive(Debug, Serialize, Deserialize)] +#[serde(rename_all = "camelCase")] +pub struct Trigger { + #[serde(rename = "type")] + pub trigger_type: String, + pub identifier: String, + pub variables: Vec, + pub subscriber_variables: Vec, +} + +#[derive(Debug, Serialize, Deserialize)] +#[serde(rename_all = "camelCase")] +pub struct NotificationGroup { + pub _id: String, + pub name: String, + pub _environment_id: String, + pub _organization_id: String, + pub _parent_id: String, +} + +#[derive(Debug, Serialize, Deserialize)] +#[serde(rename_all = "camelCase")] +pub struct Workflow { + pub _id: Option, + pub name: String, + pub description: String, + pub active: bool, + pub draft: Option, + pub preference_settings: PreferenceSettings, + pub critical: bool, + pub tags: Vec, + pub steps: Vec, + pub _organization_id: Option, + pub _creator_id: Option, + pub _environment_id: Option, + pub triggers: Vec, + pub _notification_group_id: Option, + pub notification_group_id: Option, + pub _parent_id: Option, + pub deleted: Option, + pub deleted_at: Option, + pub deleted_by: Option, + pub notification_group: Option, + pub data: Option, + pub workflow_integration_status: Option, + pub blueprint_id: Option, +} + +#[derive(Debug, Serialize, Deserialize)] +#[serde(rename_all = "camelCase")] +pub struct WorkflowsResponse { + pub data: Vec, +} + +#[derive(Debug, Serialize, Deserialize)] +#[serde(rename_all = "camelCase")] +pub struct WorkflowDeleteResponse { + pub data: bool, +} + +#[derive(Debug, Serialize, Deserialize)] +#[serde(rename_all = "camelCase")] +pub struct WorkflowStatusResponse { + pub active: bool, +} + +impl Workflows { + pub fn new(client: Client) -> Self { + Self { client } + } + + pub async fn list( + &self, + page: Option, + page_size: Option, + ) -> Result { + let mut params: HashMap<&str, Option> = HashMap::new(); + params.insert("page", page.map(|p| p.to_string())); + params.insert("limit", page_size.map(|l| l.to_string())); + + let query = generate_query_string(¶ms); + let result = self + .client + .get(format!("/workflows/?{}", generate_query_string(¶ms))) + .await?; + + match result { + Response::Success(data) => Ok(data.data), + Response::Error(err) => match err.status_code { + 401 => Err(NovuError::UnauthorizedError("/workflows".to_string())), + 400 => Err(NovuError::InvalidValues( + "page size".to_string(), + "page size limit".to_string(), + )), + code => todo!("{}", code), + }, + Response::Messages(err) => todo!("{:?}", err), + } + } + + pub async fn create(&self, data: Workflow) -> Result { + let result = self.client.post("/workflows", Some(&data)).await?; + + match result { + Response::Success(data) => Ok(data.data), + Response::Error(err) => match err.status_code { + 401 => Err(NovuError::UnauthorizedError("/workflows".to_string())), + code => todo!("{}", code), + }, + Response::Messages(err) => todo!("{:?}", err), + } + } + + pub async fn update(&self, id: String, data: Workflow) -> Result { + let result = self.client.put(format!("/workflows/{}", id), &data).await?; + + match result { + Response::Success(data) => Ok(data.data), + Response::Error(err) => match err.status_code { + 401 => Err(NovuError::UnauthorizedError("/workflows".to_string())), + code => todo!("{}", code), + }, + Response::Messages(err) => todo!("{:?}", err), + } + } + + pub async fn delete(&self, id: String) -> Result { + let result = self.client.delete(format!("/workflows/{}", id)).await?; + + match result { + Response::Success(data) => Ok(data.data), + Response::Error(err) => match err.status_code { + 401 => Err(NovuError::UnauthorizedError("/workflows".to_string())), + code => todo!("{}", code), + }, + Response::Messages(err) => todo!("{:?}", err), + } + } + + pub async fn get(&self, id: String) -> Result { + let result = self.client.get(format!("/workflows/{}", id)).await?; + + match result { + Response::Success(data) => Ok(data.data), + Response::Error(err) => match err.status_code { + 401 => Err(NovuError::UnauthorizedError("/workflows".to_string())), + code => todo!("{}", code), + }, + Response::Messages(err) => todo!("{:?}", err), + } + } + + pub async fn update_status(&self, id: String) -> Result { + let result = self + .client + .put(format!("/workflows/{}/status", id), &None::<()>) + .await?; + + match result { + Response::Success(data) => Ok(data.data), + Response::Error(err) => match err.status_code { + 401 => Err(NovuError::UnauthorizedError("/workflows".to_string())), + code => todo!("{}", code), + }, + Response::Messages(err) => todo!("{:?}", err), + } + } +}