mailchimp/
automations.rs

1//! Implement Mailchimp Automations Endpoint
2//!
3//! Mailchimp’s free Automation feature lets you build a series of
4//! emails that send to subscribers when triggered by a specific date, activity,
5//! or event. Use the API to manage Automation workflows, emails, and queues.
6//!
7//! ```
8//!     use mailchimp::MailchimpApi;
9//!     use mailchimp::{Automations, AutomationsFilter};
10//!     use std::collections::HashMap;
11//!
12//!     fn main() {
13//!         let api = MailchimpApi::new("<API_KEY>");
14//!
15//!         // Create Instance
16//!         let automations = Automations::new(api);
17//!
18//!         // Get information about all automations in the account.
19//!         for w in automations.iter(AutomationsFilter::default()) {
20//!             println!("Title             {:?}", settings.title);
21//!             println!("Emails Sent       {:?}", w.emails_sent);
22//!             println!("Report Summary    {:?}", w.report_summary);
23//!             println!("Start Time        {:?}", w.start_time);
24//!         }
25//!     }
26//! ```
27//!
28
29use super::api::{MailchimpApi, MailchimpApiUpdate};
30use super::internal::request::MailchimpResult;
31use super::iter::{BuildIter, MalchimpIter, ResourceFilter};
32use super::types::{
33    AutomationCampaignSettingsType, AutomationModifier, AutomationTriggerType,
34    AutomationWorkflowType, CollectionAutomation, RecipientType,
35};
36use log::error;
37use std::collections::HashMap;
38use std::rc::Rc;
39
40/// Automation Request Filter
41#[derive(Debug, Clone)]
42pub struct AutomationsFilter {
43    /// A comma-separated list of fields to return. Reference
44    /// parameters of sub-objects with dot notation.
45    pub fields: Option<String>,
46    /// A comma-separated list of fields to exclude. Reference
47    /// parameters of sub-objects with dot notation.
48    pub exclude_fields: Option<String>,
49    /// The number of records to return. Default value is 10.
50    pub count: Option<u64>,
51    /// The number of records from a collection to skip. Iterating over
52    /// large collections with this parameter can be slow. Default value is 0..
53    pub offset: Option<u64>,
54    /// The status of the campaign.
55    pub status: Option<String>,
56    /// Restrict the response to automations sent before the set time. We recommend
57    /// ISO 8601 time format: 2015-10-21T15:41:36+00:00.
58    pub before_send_time: Option<String>,
59    /// Restrict the response to automations sent after the set time. We recommend
60    /// ISO 8601 time format: 2015-10-21T15:41:36+00:00.
61    pub since_send_time: Option<String>,
62    /// Restrict the response to automations created before the set time. We recommend
63    /// ISO 8601 time format: 2015-10-21T15:41:36+00:00.
64    pub before_create_time: Option<String>,
65    /// Restrict the response to automations created after the set time. We recommend
66    /// ISO 8601 time format: 2015-10-21T15:41:36+00:00.
67    pub since_create_time: Option<String>,
68}
69
70impl Default for AutomationsFilter {
71    fn default() -> Self {
72        AutomationsFilter {
73            fields: None,
74            exclude_fields: None,
75            count: Some(50),
76            offset: Some(0),
77            status: None,
78            before_send_time: None,
79            since_send_time: None,
80            before_create_time: None,
81            since_create_time: None,
82        }
83    }
84}
85
86impl ResourceFilter for AutomationsFilter {
87    fn build_payload(&self) -> HashMap<String, String> {
88        let mut payload = HashMap::new();
89
90        if self.fields.is_some() {
91            payload.insert("fields".to_string(), self.fields.as_ref().unwrap().clone());
92        }
93        if self.exclude_fields.is_some() {
94            payload.insert(
95                "exclude_fields".to_string(),
96                self.exclude_fields.as_ref().unwrap().clone(),
97            );
98        }
99        if self.count.is_some() {
100            payload.insert(
101                "count".to_string(),
102                format!("{:}", self.count.as_ref().unwrap().clone()),
103            );
104        }
105        if self.offset.is_some() {
106            payload.insert(
107                "offset".to_string(),
108                format!("{:}", self.offset.as_ref().unwrap().clone()),
109            );
110        }
111        if self.status.is_some() {
112            payload.insert("status".to_string(), self.status.as_ref().unwrap().clone());
113        }
114        if self.before_send_time.is_some() {
115            payload.insert(
116                "before_send_time".to_string(),
117                self.before_send_time.as_ref().unwrap().clone(),
118            );
119        }
120        if self.since_send_time.is_some() {
121            payload.insert(
122                "since_send_time".to_string(),
123                self.since_send_time.as_ref().unwrap().clone(),
124            );
125        }
126        if self.before_create_time.is_some() {
127            payload.insert(
128                "before_create_time".to_string(),
129                self.before_create_time.as_ref().unwrap().clone(),
130            );
131        }
132        if self.since_create_time.is_some() {
133            payload.insert(
134                "since_create_time".to_string(),
135                self.since_create_time.as_ref().unwrap().clone(),
136            );
137        }
138        payload
139    }
140}
141
142///
143/// Implement Mailchimp Automations Endpoint
144///
145/// Mailchimp’s free Automation feature lets you build a series of
146/// emails that send to subscribers when triggered by a specific date, activity,
147/// or event. Use the API to manage Automation workflows, emails, and queues
148///
149#[derive(Debug, Clone)]
150pub struct Automations {
151    api: Rc<MailchimpApi>,
152}
153
154#[derive(Debug)]
155pub struct AutomationsBuilder {}
156
157impl BuildIter for AutomationsBuilder {
158    type Item = AutomationWorkflowType;
159    type FilterItem = AutomationsFilter;
160    type Collection = CollectionAutomation;
161
162    ///
163    /// Create new resource, with the api instance updated
164    ///
165    fn update_item(&self, data: &Self::Item, api: Rc<MailchimpApi>) -> Self::Item {
166        let mut in_data = data.clone();
167        in_data.set_api(api);
168        in_data
169    }
170    ///
171    /// Update filter params
172    ///
173    fn update_filter_offset(&self, filter: &Self::FilterItem) -> Self::FilterItem {
174        let mut f = filter.clone();
175        f.offset = Some(f.count.unwrap() + f.offset.unwrap());
176        f
177    }
178}
179
180impl Automations {
181    ///
182    /// Argumentos:
183    ///     api: MailchimpApi
184    ///
185    pub fn new(api: MailchimpApi) -> Self {
186        Automations { api: Rc::new(api) }
187    }
188
189    ///
190    /// Devuelve información de las listas creadas
191    ///
192    /// Argumentos:
193    ///     filters: Filtros que se requieran aplicar a la hora de obtener las automatizaciones
194    ///         Estos filtros se deben pasar en forma de llave, valor donde las llaves puede ser
195    ///         cualquiera de los siguientes:
196    ///         fields: listado de campos deseados, separados por coma
197    ///         exclude_fields: listado de campos excluidos, separados por coma
198    ///         count: Número de registros a devolver
199    ///         offset: El número de registros de una colección a saltar
200    ///         before_date_created: Restrict response to lists created before the set date.
201    ///         since_date_created: Restrict results to lists created after the set date.
202    ///         before_campaign_last_sent: Restrict results to lists created before the last campaign send date.
203    ///         since_campaign_last_sent: Restrict results to lists created after the last campaign send date.
204    ///         email: Restrict results to lists that include a specific subscriber’s email address.
205    ///         sort_field: Returns files sorted by the specified field.
206    ///         sort_dir: Determines the order direction for sorted results.
207    ///         folder_id: The unique folder id.
208    ///         list_id: The unique id for the list.
209    ///
210    pub fn get_automations_from_remote(
211        &self,
212        filters: Option<&AutomationsFilter>,
213    ) -> Option<CollectionAutomation> {
214        let mut payload = HashMap::new();
215        if filters.is_some() {
216            payload = filters.as_ref().unwrap().build_payload();
217        }
218        let response = self.api.get::<CollectionAutomation>("automations", payload);
219        match response {
220            Ok(value) => Some(value),
221            Err(e) => {
222                error!( target: "mailchimp",  "Load Campaigns from remote: Response Error details: {:?}", e);
223                None
224            }
225        }
226    }
227
228    ///
229    /// Devuelve la informacion de la automatizacion especificada
230    ///
231    /// Argumentos:
232    ///     workflow_id: Identificador único de la automatización
233    ///     filters: Filtros requeridos a la hora de obtener las automatizaciones
234    ///         Estos filtros se deben pasar en forma de llave, valor donde las llaves puede ser
235    ///         cualquiera de los siguientes:
236    ///         fields: Una lista de campos separados por comas para devolver.
237    ///             Parámetros de referencia de subobjetos con notación de puntos.
238    ///         exclude_fields: Una lista de campos separados por comas para excluir.
239    ///            Parámetros de referencia de subobjetos con notación de puntos.
240    ///
241    pub fn get_automation_workflow_info<'a>(
242        &self,
243        workflow_id: &'a str,
244        filters: HashMap<String, String>,
245    ) -> MailchimpResult<AutomationWorkflowType> {
246        let endpoint = String::from("automations/") + workflow_id;
247        let response = self
248            .api
249            .get::<AutomationWorkflowType>(endpoint.as_str(), filters);
250
251        match response {
252            Ok(automation) => {
253                let mut au = automation;
254                au.set_api(self.api.clone());
255                Ok(au)
256            }
257            Err(e) => Err(e),
258        }
259    }
260    ///
261    ///  Crea una automatización
262    ///
263    /// Argumentos:
264    ///     recipients: Contenedores para esta automatización
265    ///     trigger_settings: Configuracion de los disparadores
266    ///     settings: Configuracion de la automatización a crear
267    ///
268    pub fn create_automation<'a>(
269        &self,
270        recipients: RecipientType,
271        trigger_settings: AutomationTriggerType,
272        settings: Option<AutomationCampaignSettingsType>,
273    ) -> MailchimpResult<AutomationWorkflowType> {
274        let modifier = AutomationModifier {
275            settings: settings,
276            delay: None,
277            recipients: Some(recipients),
278            trigger_settings: Some(trigger_settings),
279        };
280        let response = self
281            .api
282            .post::<AutomationWorkflowType, AutomationModifier>("automations", modifier);
283        match response {
284            Ok(automation) => {
285                let mut au = automation;
286                au.set_api(self.api.clone());
287                Ok(au)
288            }
289            Err(e) => Err(e),
290        }
291    }
292
293    ///
294    /// Función para recorrer todas las campañas exitentes. A diferencia de la
295    /// anterior esta función te devuelve un iterador
296    ///
297    pub fn iter(&self, filters: AutomationsFilter) -> MalchimpIter<AutomationsBuilder> {
298        if let Some(remote) = self.get_automations_from_remote(Some(&filters)) {
299            return MalchimpIter {
300                builder: AutomationsBuilder {},
301                data: remote.automations,
302                cur_filters: filters.clone(),
303                cur_it: 0,
304                total_items: remote.total_items,
305                api: self.api.clone(),
306                endpoint: "automations".to_string(),
307            };
308        }
309        MalchimpIter {
310            builder: AutomationsBuilder {},
311            data: Vec::new(),
312            cur_filters: filters.clone(),
313            cur_it: 0,
314            total_items: 0,
315            api: self.api.clone(),
316            endpoint: "automations".to_string(),
317        }
318    }
319}