1use super::automation_campaign::{
5 CampaignReportSummaryType, CampaignSettingsType, CampaignTrackingOptionsType, RecipientType,
6 SocialCardType,
7};
8use super::campaign_content::{CampaignContentParam, CampaignContentType};
9use super::campaign_feedback::{
10 CampaignFeedbackBuilder, CampaignFeedbackType, CollectionCampaignFeedback,
11};
12use super::campaign_send_checklist::SendChecklistType;
13use super::empty::EmptyType;
14use super::link::LinkType;
15use crate::api::{MailchimpApi, MailchimpApiUpdate};
16use crate::internal::request::MailchimpResult;
17use crate::iter::MailchimpCollection;
18use crate::iter::{MalchimpIter, ResourceFilter, SimpleFilter};
19use serde::{Deserialize, Serialize};
20use std::collections::HashMap;
21use std::rc::Rc;
22
23#[derive(Serialize, Deserialize, Debug, Clone)]
27pub struct CampaignDeliveryStatusType {
28 #[serde(default, skip_serializing_if = "Option::is_none")]
30 pub enabled: Option<bool>,
31 #[serde(default, skip_serializing_if = "Option::is_none")]
33 pub can_cancel: Option<bool>,
34 #[serde(default, skip_serializing_if = "Option::is_none")]
36 pub status: Option<String>,
37 #[serde(default, skip_serializing_if = "Option::is_none")]
39 pub emails_sent: Option<u64>,
40 #[serde(default, skip_serializing_if = "Option::is_none")]
42 pub emails_canceled: Option<u64>,
43}
44
45impl Default for CampaignDeliveryStatusType {
46 fn default() -> Self {
47 CampaignDeliveryStatusType {
48 enabled: None,
49 can_cancel: None,
50 status: None,
51 emails_sent: None,
52 emails_canceled: None,
53 }
54 }
55}
56
57#[derive(Serialize, Deserialize, Debug, Clone)]
61pub struct ABTestingOptionsType {
62 #[serde(default, skip_serializing_if = "Option::is_none")]
64 pub split_test: Option<String>,
65 #[serde(default, skip_serializing_if = "Option::is_none")]
67 pub pick_winner: Option<String>,
68 #[serde(default, skip_serializing_if = "Option::is_none")]
71 pub wait_units: Option<String>,
72 #[serde(default, skip_serializing_if = "Option::is_none")]
75 pub wait_time: Option<u64>,
76 #[serde(default, skip_serializing_if = "Option::is_none")]
79 pub split_size: Option<u64>,
80 #[serde(default, skip_serializing_if = "Option::is_none")]
82 pub from_name_a: Option<String>,
83 #[serde(default, skip_serializing_if = "Option::is_none")]
85 pub from_name_b: Option<String>,
86 #[serde(default, skip_serializing_if = "Option::is_none")]
88 pub reply_email_a: Option<String>,
89 #[serde(default, skip_serializing_if = "Option::is_none")]
91 pub reply_email_b: Option<String>,
92 #[serde(default, skip_serializing_if = "Option::is_none")]
94 pub subject_a: Option<String>,
95 #[serde(default, skip_serializing_if = "Option::is_none")]
97 pub subject_b: Option<String>,
98 #[serde(default, skip_serializing_if = "Option::is_none")]
100 pub send_time_a: Option<String>,
101 #[serde(default, skip_serializing_if = "Option::is_none")]
103 pub send_time_b: Option<String>,
104 #[serde(default, skip_serializing_if = "Option::is_none")]
106 pub send_time_winner: Option<String>,
107}
108
109impl Default for ABTestingOptionsType {
110 fn default() -> Self {
111 ABTestingOptionsType {
112 split_test: None,
113 pick_winner: None,
114 wait_units: None,
115 wait_time: None,
116 split_size: None,
117 from_name_a: None,
118 from_name_b: None,
119 reply_email_a: None,
120 reply_email_b: None,
121 subject_a: None,
122 subject_b: None,
123 send_time_a: None,
124 send_time_b: None,
125 send_time_winner: None,
126 }
127 }
128}
129
130#[derive(Serialize, Deserialize, Debug, Clone)]
134pub struct DailySendingDaysType {
135 #[serde(default, skip_serializing_if = "Option::is_none")]
137 pub sunday: Option<bool>,
138 #[serde(default, skip_serializing_if = "Option::is_none")]
140 pub monday: Option<bool>,
141 #[serde(default, skip_serializing_if = "Option::is_none")]
143 pub tuesday: Option<bool>,
144 #[serde(default, skip_serializing_if = "Option::is_none")]
146 pub wednesday: Option<bool>,
147 #[serde(default, skip_serializing_if = "Option::is_none")]
149 pub thursday: Option<bool>,
150 #[serde(default, skip_serializing_if = "Option::is_none")]
152 pub friday: Option<bool>,
153 #[serde(default, skip_serializing_if = "Option::is_none")]
155 pub saturday: Option<bool>,
156}
157
158impl Default for DailySendingDaysType {
159 fn default() -> Self {
160 DailySendingDaysType {
161 sunday: None,
162 monday: None,
163 tuesday: None,
164 wednesday: None,
165 thursday: None,
166 friday: None,
167 saturday: None,
168 }
169 }
170}
171
172#[derive(Serialize, Deserialize, Debug, Clone)]
176pub struct SendingScheduleType {
177 #[serde(default, skip_serializing_if = "Option::is_none")]
180 pub hour: Option<u64>,
181 #[serde(default, skip_serializing_if = "Option::is_none")]
183 pub daily_send: Option<DailySendingDaysType>,
184 #[serde(default, skip_serializing_if = "Option::is_none")]
186 pub weekly_send_day: Option<String>,
187 #[serde(default, skip_serializing_if = "Option::is_none")]
192 pub monthly_send_date: Option<f32>,
193}
194
195impl Default for SendingScheduleType {
196 fn default() -> Self {
197 SendingScheduleType {
198 hour: None,
199 daily_send: None,
200 weekly_send_day: None,
201 monthly_send_date: None,
202 }
203 }
204}
205
206#[derive(Serialize, Deserialize, Debug, Clone)]
210pub struct RSSOptionsType {
211 #[serde(default, skip_serializing_if = "Option::is_none")]
213 pub feed_url: Option<String>,
214 #[serde(default, skip_serializing_if = "Option::is_none")]
216 pub frequency: Option<String>,
217 #[serde(default, skip_serializing_if = "Option::is_none")]
219 pub schedule: Option<SendingScheduleType>,
220 #[serde(default, skip_serializing_if = "Option::is_none")]
222 pub last_sent: Option<String>,
223 #[serde(default, skip_serializing_if = "Option::is_none")]
225 pub constrain_rss_img: Option<bool>,
226}
227
228impl Default for RSSOptionsType {
229 fn default() -> Self {
230 RSSOptionsType {
231 feed_url: None,
232 frequency: None,
233 schedule: None,
234 last_sent: None,
235 constrain_rss_img: None,
236 }
237 }
238}
239
240#[derive(Serialize, Deserialize, Debug, Clone)]
244pub struct CombinationsType {
245 #[serde(default, skip_serializing_if = "Option::is_none")]
247 pub id: Option<String>,
248 #[serde(default, skip_serializing_if = "Option::is_none")]
250 pub subject_line: Option<u64>,
251 #[serde(default, skip_serializing_if = "Option::is_none")]
253 pub send_time: Option<u64>,
254 #[serde(default, skip_serializing_if = "Option::is_none")]
256 pub from_name: Option<u64>,
257 #[serde(default, skip_serializing_if = "Option::is_none")]
259 pub reply_to: Option<u64>,
260 #[serde(default, skip_serializing_if = "Option::is_none")]
262 pub content_description: Option<u64>,
263 #[serde(default, skip_serializing_if = "Option::is_none")]
265 pub recipients: Option<u64>,
266}
267
268impl Default for CombinationsType {
269 fn default() -> Self {
270 CombinationsType {
271 id: None,
272 subject_line: None,
273 send_time: None,
274 from_name: None,
275 reply_to: None,
276 content_description: None,
277 recipients: None,
278 }
279 }
280}
281
282#[derive(Serialize, Deserialize, Debug, Clone)]
286pub struct VariateSettingsType {
287 #[serde(default, skip_serializing_if = "Option::is_none")]
289 pub winning_combination_id: Option<String>,
290 #[serde(default, skip_serializing_if = "Option::is_none")]
293 pub winning_campaign_id: Option<String>,
294 #[serde(default, skip_serializing_if = "Option::is_none")]
302 pub winner_criteria: Option<String>,
303 #[serde(default, skip_serializing_if = "Option::is_none")]
307 pub wait_time: Option<u64>,
308 #[serde(default, skip_serializing_if = "Option::is_none")]
311 pub test_size: Option<u64>,
312 #[serde(default, skip_serializing_if = "Option::is_none")]
315 pub subject_lines: Option<Vec<String>>,
316 #[serde(default, skip_serializing_if = "Option::is_none")]
320 pub send_times: Option<Vec<String>>,
321 #[serde(default, skip_serializing_if = "Option::is_none")]
324 pub from_names: Option<Vec<String>>,
325 #[serde(default, skip_serializing_if = "Option::is_none")]
328 pub reply_to_addresses: Option<Vec<String>>,
329 #[serde(default, skip_serializing_if = "Option::is_none")]
332 pub contents: Option<Vec<String>>,
333 #[serde(default, skip_serializing_if = "Option::is_none")]
335 pub combinations: Option<Vec<CombinationsType>>,
336}
337
338impl Default for VariateSettingsType {
339 fn default() -> Self {
340 VariateSettingsType {
341 winning_combination_id: None,
342 winning_campaign_id: None,
343 winner_criteria: None,
344 wait_time: None,
345 test_size: None,
346 subject_lines: None,
347 send_times: None,
348 from_names: None,
349 reply_to_addresses: None,
350 contents: None,
351 combinations: None,
352 }
353 }
354}
355
356#[derive(Serialize, Deserialize, Debug, Clone)]
363pub struct CampaignType {
364 #[serde(default, skip_serializing_if = "Option::is_none")]
366 pub id: Option<String>,
367 #[serde(default, skip_serializing_if = "Option::is_none")]
370 pub web_id: Option<u64>,
371 #[serde(default, skip_serializing_if = "Option::is_none")]
374 pub parent_campaign_id: Option<String>,
375 #[serde(default, skip_serializing_if = "Option::is_none", rename = "type")]
378 pub campaign_type: Option<String>,
379 #[serde(default, skip_serializing_if = "Option::is_none")]
381 pub create_time: Option<String>,
382 #[serde(default, skip_serializing_if = "Option::is_none")]
384 pub archive_url: Option<String>,
385 #[serde(default, skip_serializing_if = "Option::is_none")]
387 pub long_archive_url: Option<String>,
388 #[serde(default, skip_serializing_if = "Option::is_none")]
390 pub status: Option<String>,
391 #[serde(default, skip_serializing_if = "Option::is_none")]
393 pub emails_sent: Option<u64>,
394 #[serde(default, skip_serializing_if = "Option::is_none")]
396 pub send_time: Option<String>,
397 #[serde(default, skip_serializing_if = "Option::is_none")]
399 pub content_type: Option<String>,
400 #[serde(default, skip_serializing_if = "Option::is_none")]
402 pub needs_block_refresh: Option<bool>,
403 #[serde(default, skip_serializing_if = "Option::is_none")]
405 pub has_logo_merge_tag: Option<bool>,
406 #[serde(default, skip_serializing_if = "Option::is_none")]
408 pub resendable: Option<bool>,
409 #[serde(default, skip_serializing_if = "Option::is_none")]
411 pub recipients: Option<RecipientType>,
412 #[serde(default, skip_serializing_if = "Option::is_none")]
415 pub settings: Option<CampaignSettingsType>,
416 #[serde(default, skip_serializing_if = "Option::is_none")]
418 pub variate_settings: Option<VariateSettingsType>,
419 #[serde(default, skip_serializing_if = "Option::is_none")]
421 pub tracking: Option<CampaignTrackingOptionsType>,
422 #[serde(default, skip_serializing_if = "Option::is_none")]
424 pub rss_opts: Option<RSSOptionsType>,
425 #[serde(default, skip_serializing_if = "Option::is_none")]
427 pub ab_split_opts: Option<ABTestingOptionsType>,
428 #[serde(default, skip_serializing_if = "Option::is_none")]
431 pub social_card: Option<SocialCardType>,
432 #[serde(default, skip_serializing_if = "Option::is_none")]
434 pub report_summary: Option<CampaignReportSummaryType>,
435 #[serde(default, skip_serializing_if = "Option::is_none")]
437 pub delivery_status: Option<CampaignDeliveryStatusType>,
438 #[serde(default, skip_serializing_if = "Option::is_none")]
440 pub _links: Option<Vec<LinkType>>,
441
442 #[serde(skip)]
444 _api: Rc<MailchimpApi>,
445}
446
447impl MailchimpApiUpdate for CampaignType {
448 fn set_api(&mut self, n_api: Rc<MailchimpApi>) {
452 self._api = n_api
453 }
454}
455
456#[derive(Serialize, Deserialize, Debug, Clone)]
463pub struct CampaignsType {
464 #[serde(default)]
466 pub campaigns: Vec<CampaignType>,
467 #[serde(default)]
469 pub total_items: u64,
470 #[serde(default)]
472 pub _links: Vec<LinkType>,
473}
474
475impl MailchimpCollection<CampaignType> for CampaignsType {
476 fn get_total_items(&self) -> u64 {
478 self.total_items
479 }
480 fn get_values(&self) -> Vec<CampaignType> {
482 self.campaigns.clone()
483 }
484}
485
486impl Default for CampaignsType {
487 fn default() -> Self {
488 CampaignsType {
489 campaigns: Vec::new(),
490 total_items: 0,
491 _links: Vec::new(),
492 }
493 }
494}
495
496#[derive(Serialize, Deserialize, Debug, Clone)]
500pub struct ScheduleBatchDelivery {
501 #[serde(default)]
503 pub batch_delay: u64,
504 #[serde(default)]
506 pub batch_count: u64,
507}
508
509impl Default for ScheduleBatchDelivery {
510 fn default() -> Self {
511 ScheduleBatchDelivery {
512 batch_delay: 0,
513 batch_count: 0,
514 }
515 }
516}
517
518#[derive(Serialize, Deserialize, Debug, Clone)]
522pub struct ScheduleParam {
523 #[serde(default)]
526 pub schedule_time: String,
527 #[serde(default)]
533 pub timewarp: bool,
534 #[serde(default)]
537 pub batch_delivery: Option<ScheduleBatchDelivery>,
538}
539
540#[derive(Serialize, Deserialize, Debug, Clone)]
544pub struct EmailParam {
545 #[serde(default)]
547 pub test_emails: Vec<String>,
548 #[serde(default)]
550 pub send_type: String,
551}
552
553impl EmailParam {
554 pub fn new(test_emails: Vec<String>, send_type: String) -> Self {
558 EmailParam {
559 test_emails: test_emails,
560 send_type: send_type,
561 }
562 }
563}
564
565#[derive(Serialize, Deserialize, Debug, Clone)]
569pub struct UpdateCampaignParam {
570 #[serde(default, skip_serializing_if = "Option::is_none")]
572 pub recipients: Option<RecipientType>,
573 #[serde(default, skip_serializing_if = "Option::is_none")]
576 pub settings: Option<CampaignSettingsType>,
577 #[serde(default, skip_serializing_if = "Option::is_none")]
579 pub variate_settings: Option<VariateSettingsType>,
580 #[serde(default, skip_serializing_if = "Option::is_none")]
582 pub tracking: Option<CampaignTrackingOptionsType>,
583 #[serde(default, skip_serializing_if = "Option::is_none")]
585 pub rss_opts: Option<RSSOptionsType>,
586 #[serde(default, skip_serializing_if = "Option::is_none")]
589 pub social_card: Option<SocialCardType>,
590}
591
592impl CampaignType {
593 pub fn cancel_campaign(&self) -> MailchimpResult<EmptyType> {
598 let endpoint = self.get_base_endpoint() + "/actions/cancel-send";
600 self._api
601 .post::<EmptyType, HashMap<String, String>>(&endpoint, HashMap::new())
602 }
603 pub fn resend_campaign(&self) -> MailchimpResult<CampaignType> {
607 let endpoint = self.get_base_endpoint() + "/actions/create-resend";
609 self._api
610 .post::<CampaignType, HashMap<String, String>>(&endpoint, HashMap::new())
611 }
612 pub fn pause_rss_driven_campaign(&self) -> MailchimpResult<EmptyType> {
616 let endpoint = self.get_base_endpoint() + "/actions/pause";
618 self._api
619 .post::<EmptyType, HashMap<String, String>>(&endpoint, HashMap::new())
620 }
621 pub fn replicate_campaign(&self) -> MailchimpResult<CampaignType> {
625 let endpoint = self.get_base_endpoint() + "/actions/replicate";
627 self._api
628 .post::<CampaignType, HashMap<String, String>>(&endpoint, HashMap::new())
629 }
630 pub fn resume_rss_driven_campaign(&self) -> MailchimpResult<EmptyType> {
634 let endpoint = self.get_base_endpoint() + "/actions/resume";
636 self._api
637 .post::<EmptyType, HashMap<String, String>>(&endpoint, HashMap::new())
638 }
639 pub fn schedule_campaign(&self, param: ScheduleParam) -> MailchimpResult<EmptyType> {
644 let endpoint = self.get_base_endpoint() + "/actions/schedule";
646 self._api.post::<EmptyType, ScheduleParam>(&endpoint, param)
647 }
648
649 pub fn send_campaign(&self) -> MailchimpResult<EmptyType> {
654 let endpoint = self.get_base_endpoint() + "/actions/send";
656 self._api
657 .post::<EmptyType, HashMap<String, String>>(&endpoint, HashMap::new())
658 }
659
660 pub fn send_test_email(&self, param: EmailParam) -> MailchimpResult<EmptyType> {
664 let endpoint = self.get_base_endpoint() + "/actions/test";
666 self._api.post::<EmptyType, EmailParam>(&endpoint, param)
667 }
668
669 pub fn unschedule_campaign(&self) -> MailchimpResult<EmptyType> {
673 let endpoint = self.get_base_endpoint() + "/actions/unschedule";
675 self._api
676 .post::<EmptyType, HashMap<String, String>>(&endpoint, HashMap::new())
677 }
678
679 pub fn delete(&self) -> MailchimpResult<bool> {
684 let endpoint = self.get_base_endpoint();
686 match self._api.delete::<EmptyType>(&endpoint, HashMap::new()) {
687 Ok(_) => Ok(true),
688 Err(e) => Err(e),
689 }
690 }
691
692 pub fn update(&self, param: UpdateCampaignParam) -> MailchimpResult<CampaignType> {
697 let endpoint = self.get_base_endpoint();
699 self._api
700 .patch::<CampaignType, UpdateCampaignParam>(&endpoint, param)
701 }
702
703 pub fn get_content(
715 &self,
716 fields: Option<String>,
717 exclude_fields: Option<String>,
718 ) -> MailchimpResult<CampaignContentType> {
719 let endpoint = self.get_base_endpoint() + "/content";
721 let mut payload = HashMap::new();
722 if let Some(field) = fields {
723 payload.insert("fields".to_string(), field);
724 }
725 if let Some(ef) = exclude_fields {
726 payload.insert("exclude_fields".to_string(), ef);
727 }
728 self._api
729 .get::<CampaignContentType>(endpoint.as_str(), payload)
730 }
731
732 pub fn update_content(
736 &self,
737 param: CampaignContentParam,
738 ) -> MailchimpResult<CampaignContentType> {
739 let endpoint = self.get_base_endpoint() + "/content";
741 self._api
742 .put::<CampaignContentType, CampaignContentParam>(&endpoint, param)
743 }
744
745 pub fn send_checklist(
756 &self,
757 fields: Option<String>,
758 exclude_fields: Option<String>,
759 ) -> MailchimpResult<SendChecklistType> {
760 let endpoint = self.get_base_endpoint() + "/send-checklist";
762 let mut payload = HashMap::new();
763 if let Some(field) = fields {
764 payload.insert("fields".to_string(), field);
765 }
766 if let Some(ef) = exclude_fields {
767 payload.insert("exclude_fields".to_string(), ef);
768 }
769 self._api
770 .get::<SendChecklistType>(endpoint.as_str(), payload)
771 }
772 pub fn get_feedbacks(
783 &self,
784 fields: Option<String>,
785 exclude_fields: Option<String>,
786 ) -> MalchimpIter<CampaignFeedbackBuilder> {
787 let endpoint = self.get_base_endpoint() + "/feedback";
789 let mut filters = SimpleFilter::default();
790
791 if let Some(f) = fields {
792 filters.fields = Some(f.clone())
793 }
794 if let Some(ex) = exclude_fields {
795 filters.exclude_fields = Some(ex.clone())
796 }
797
798 let payload = filters.build_payload();
799 let response = self
800 ._api
801 .get::<CollectionCampaignFeedback>(&endpoint, payload);
802 match response {
803 Ok(collection) => MalchimpIter {
804 builder: CampaignFeedbackBuilder {
805 endpoint: endpoint.clone(),
806 },
807 data: collection.feedback,
808 cur_filters: filters.clone(),
809 cur_it: 0,
810 total_items: collection.total_items,
811 api: self._api.clone(),
812 endpoint: endpoint.clone(),
813 },
814 Err(e) => {
815 println!("Feedback Iter {:?}", e);
816 MalchimpIter {
817 builder: CampaignFeedbackBuilder {
818 endpoint: endpoint.clone(),
819 },
820 data: Vec::new(),
821 cur_filters: filters.clone(),
822 cur_it: 0,
823 total_items: 0,
824 api: self._api.clone(),
825 endpoint: endpoint.clone(),
826 }
827 }
828 }
829 }
830
831 pub fn get_feedback_info<'a>(
835 &self,
836 feedback_id: &'a str,
837 fields: Option<String>,
838 exclude_fields: Option<String>,
839 ) -> MailchimpResult<CampaignFeedbackType> {
840 let mut endpoint = self.get_base_endpoint() + "/feedback/";
842 endpoint = endpoint + feedback_id;
843 let mut payload = HashMap::new();
844 if let Some(f) = fields {
845 payload.insert("fields".to_string(), f.clone());
846 }
847 if let Some(ex) = exclude_fields {
848 payload.insert("exclude_fields".to_string(), ex.clone());
849 }
850
851 match self._api.get::<CampaignFeedbackType>(&endpoint, payload) {
852 Ok(feedback) => {
853 let mut n_f = feedback;
854 n_f.set_api(self._api.clone());
855 n_f.set_endpoint(&endpoint);
856 Ok(n_f)
857 }
858 Err(e) => Err(e),
859 }
860 }
861
862 fn get_base_endpoint(&self) -> String {
866 String::from("campaigns/") + &self.id.as_ref().unwrap()
867 }
868}