Skip to main content

mailchimp/types/
campaign.rs

1//! Implement Campaign Types
2//!
3
4use 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///
24/// The days of the week to send a daily RSS Campaign.
25///
26#[derive(Serialize, Deserialize, Debug, Clone)]
27pub struct CampaignDeliveryStatusType {
28    /// Whether Campaign Delivery Status is enabled for this account and campaign.
29    #[serde(default, skip_serializing_if = "Option::is_none")]
30    pub enabled: Option<bool>,
31    /// Whether a campaign send can be canceled.
32    #[serde(default, skip_serializing_if = "Option::is_none")]
33    pub can_cancel: Option<bool>,
34    /// The current state of a campaign delivery.
35    #[serde(default, skip_serializing_if = "Option::is_none")]
36    pub status: Option<String>,
37    /// The total number of emails confirmed sent for this campaign so far.
38    #[serde(default, skip_serializing_if = "Option::is_none")]
39    pub emails_sent: Option<u64>,
40    /// The total number of emails canceled for this campaign.
41    #[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///
58/// The days of the week to send a daily RSS Campaign.
59///
60#[derive(Serialize, Deserialize, Debug, Clone)]
61pub struct ABTestingOptionsType {
62    /// The type of AB split to run.
63    #[serde(default, skip_serializing_if = "Option::is_none")]
64    pub split_test: Option<String>,
65    /// How we should evaluate a winner. Based on ‘opens’, ‘clicks’, or ‘manual’.
66    #[serde(default, skip_serializing_if = "Option::is_none")]
67    pub pick_winner: Option<String>,
68    /// How unit of time for measuring the winner (‘hours’ or ‘days’).
69    /// This cannot be changed after a campaign is sent.
70    #[serde(default, skip_serializing_if = "Option::is_none")]
71    pub wait_units: Option<String>,
72    /// The amount of time to wait before picking a winner. This cannot be
73    /// changed after a campaign is sent.
74    #[serde(default, skip_serializing_if = "Option::is_none")]
75    pub wait_time: Option<u64>,
76    /// The size of the split groups. Campaigns split based on ‘schedule’
77    /// are forced to have a 50⁄50 split. Valid split integers are between 1-50.
78    #[serde(default, skip_serializing_if = "Option::is_none")]
79    pub split_size: Option<u64>,
80    /// For campaigns split on ‘From Name’, the name for Group A.
81    #[serde(default, skip_serializing_if = "Option::is_none")]
82    pub from_name_a: Option<String>,
83    /// For campaigns split on ‘From Name’, the name for Group B.
84    #[serde(default, skip_serializing_if = "Option::is_none")]
85    pub from_name_b: Option<String>,
86    /// For campaigns split on ‘From Name’, the reply-to address for Group A.
87    #[serde(default, skip_serializing_if = "Option::is_none")]
88    pub reply_email_a: Option<String>,
89    /// For campaigns split on ‘From Name’, the reply-to address for Group B.
90    #[serde(default, skip_serializing_if = "Option::is_none")]
91    pub reply_email_b: Option<String>,
92    /// For campaigns split on ‘Subject Line’, the subject line for Group A.
93    #[serde(default, skip_serializing_if = "Option::is_none")]
94    pub subject_a: Option<String>,
95    /// For campaigns split on ‘Subject Line’, the subject line for Group B.
96    #[serde(default, skip_serializing_if = "Option::is_none")]
97    pub subject_b: Option<String>,
98    /// The send time for Group A.
99    #[serde(default, skip_serializing_if = "Option::is_none")]
100    pub send_time_a: Option<String>,
101    /// The send time for Group B.
102    #[serde(default, skip_serializing_if = "Option::is_none")]
103    pub send_time_b: Option<String>,
104    /// The send time for the winning version.
105    #[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///
131/// The days of the week to send a daily RSS Campaign.
132///
133#[derive(Serialize, Deserialize, Debug, Clone)]
134pub struct DailySendingDaysType {
135    /// Sends the daily RSS Campaign on Sundays.
136    #[serde(default, skip_serializing_if = "Option::is_none")]
137    pub sunday: Option<bool>,
138    /// Sends the daily RSS Campaign on Mondays.
139    #[serde(default, skip_serializing_if = "Option::is_none")]
140    pub monday: Option<bool>,
141    /// Sends the daily RSS Campaign on Tuesdays.
142    #[serde(default, skip_serializing_if = "Option::is_none")]
143    pub tuesday: Option<bool>,
144    /// Sends the daily RSS Campaign on Wednesdays.
145    #[serde(default, skip_serializing_if = "Option::is_none")]
146    pub wednesday: Option<bool>,
147    /// Sends the daily RSS Campaign on Thursdays.
148    #[serde(default, skip_serializing_if = "Option::is_none")]
149    pub thursday: Option<bool>,
150    /// Sends the daily RSS Campaign on Fridays.
151    #[serde(default, skip_serializing_if = "Option::is_none")]
152    pub friday: Option<bool>,
153    /// Sends the daily RSS Campaign on Saturdays.
154    #[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///
173/// The schedule for sending the RSS Campaign.
174///
175#[derive(Serialize, Deserialize, Debug, Clone)]
176pub struct SendingScheduleType {
177    /// The hour to send the campaign in local time. Acceptable hours are 0-23.
178    /// For example, ‘4’ would be 4am in your account’s default time zone.
179    #[serde(default, skip_serializing_if = "Option::is_none")]
180    pub hour: Option<u64>,
181    /// The days of the week to send a daily RSS Campaign.
182    #[serde(default, skip_serializing_if = "Option::is_none")]
183    pub daily_send: Option<DailySendingDaysType>,
184    /// The day of the week to send a weekly RSS Campaign.
185    #[serde(default, skip_serializing_if = "Option::is_none")]
186    pub weekly_send_day: Option<String>,
187    /// The day of the month to send a monthly RSS Campaign. Acceptable days are 0-31,
188    /// where ‘0’ is always the last day of a month. Months with fewer than the
189    /// selected number of days will not have an RSS campaign sent out that day.
190    /// For example, RSS Campaigns set to send on the 30th will not go out in February.
191    #[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///
207/// RSS options for a campaign.
208///
209#[derive(Serialize, Deserialize, Debug, Clone)]
210pub struct RSSOptionsType {
211    /// The URL for the RSS feed.
212    #[serde(default, skip_serializing_if = "Option::is_none")]
213    pub feed_url: Option<String>,
214    /// The frequency of the RSS Campaign.
215    #[serde(default, skip_serializing_if = "Option::is_none")]
216    pub frequency: Option<String>,
217    /// The schedule for sending the RSS Campaign.
218    #[serde(default, skip_serializing_if = "Option::is_none")]
219    pub schedule: Option<SendingScheduleType>,
220    /// The date the campaign was last sent.
221    #[serde(default, skip_serializing_if = "Option::is_none")]
222    pub last_sent: Option<String>,
223    /// Whether to add CSS to images in the RSS feed to constrain their width in campaigns.
224    #[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///
241/// The settings specific to A/B test campaigns.
242///
243#[derive(Serialize, Deserialize, Debug, Clone)]
244pub struct CombinationsType {
245    /// Unique ID for the combination.
246    #[serde(default, skip_serializing_if = "Option::is_none")]
247    pub id: Option<String>,
248    /// The index of variate_settings.subject_lines used.
249    #[serde(default, skip_serializing_if = "Option::is_none")]
250    pub subject_line: Option<u64>,
251    /// The index of variate_settings.send_times used.
252    #[serde(default, skip_serializing_if = "Option::is_none")]
253    pub send_time: Option<u64>,
254    /// The index of variate_settings.from_names used.
255    #[serde(default, skip_serializing_if = "Option::is_none")]
256    pub from_name: Option<u64>,
257    /// The index of variate_settings.reply_to_addresses used.
258    #[serde(default, skip_serializing_if = "Option::is_none")]
259    pub reply_to: Option<u64>,
260    /// The index of variate_settings.contents used.
261    #[serde(default, skip_serializing_if = "Option::is_none")]
262    pub content_description: Option<u64>,
263    /// The number of recipients for this combination.
264    #[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///
283/// The settings specific to A/B test campaigns.
284///
285#[derive(Serialize, Deserialize, Debug, Clone)]
286pub struct VariateSettingsType {
287    /// ID for the winning combination.
288    #[serde(default, skip_serializing_if = "Option::is_none")]
289    pub winning_combination_id: Option<String>,
290    /// ID of the campaign that was sent to the remaining recipients
291    /// based on the winning combination.
292    #[serde(default, skip_serializing_if = "Option::is_none")]
293    pub winning_campaign_id: Option<String>,
294    /// The combination that performs the best. This may be determined
295    /// automatically by click rate, open rate, or total revenue—or you
296    /// may choose manually based on the reporting data you find the most
297    /// valuable. For Multivariate Campaigns testing send_time,
298    ///  winner_criteria is ignored. For Multivariate Campaigns with ‘manual’
299    ///  as the winner_criteria, the winner must be chosen in the Mailchimp
300    /// web application.
301    #[serde(default, skip_serializing_if = "Option::is_none")]
302    pub winner_criteria: Option<String>,
303    /// The number of minutes to wait before choosing the winning campaign.
304    /// The value of wait_time must be greater than 0 and in whole hours,
305    /// specified in minutes.
306    #[serde(default, skip_serializing_if = "Option::is_none")]
307    pub wait_time: Option<u64>,
308    /// The percentage of recipients to send the test combinations to,
309    /// must be a value between 10 and 100.
310    #[serde(default, skip_serializing_if = "Option::is_none")]
311    pub test_size: Option<u64>,
312    /// The possible subject lines to test. If no subject lines are provided,
313    /// settings.subject_line will be used.
314    #[serde(default, skip_serializing_if = "Option::is_none")]
315    pub subject_lines: Option<Vec<String>>,
316    /// The possible send times to test. The times provided should
317    /// be in the format YYYY-MM-DD HH:MM:SS. If send_times are provided to
318    /// test, the test_size will be set to 100% and winner_criteria will be ignored.
319    #[serde(default, skip_serializing_if = "Option::is_none")]
320    pub send_times: Option<Vec<String>>,
321    /// The possible from names. The number of from_names provided must match the number
322    /// of reply_to_addresses. If no from_names are provided, settings.from_name will be used.
323    #[serde(default, skip_serializing_if = "Option::is_none")]
324    pub from_names: Option<Vec<String>>,
325    /// The possible reply-to addresses. The number of reply_to_addresses provided must match
326    /// the number of from_names. If no reply_to_addresses are provided, settings.reply_to will be used.
327    #[serde(default, skip_serializing_if = "Option::is_none")]
328    pub reply_to_addresses: Option<Vec<String>>,
329    /// Descriptions of possible email contents. To set campaign contents,
330    /// make a PUT request to /campaigns/{campaign_id}/content with the field ‘variate_contents’.
331    #[serde(default, skip_serializing_if = "Option::is_none")]
332    pub contents: Option<Vec<String>>,
333    /// Combinations of possible variables used to build emails.
334    #[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///
357/// Campaign
358///
359/// Endpoint
360///     GET /campaigns/{campaign_id}
361///
362#[derive(Serialize, Deserialize, Debug, Clone)]
363pub struct CampaignType {
364    /// A string that uniquely identifies this campaign.
365    #[serde(default, skip_serializing_if = "Option::is_none")]
366    pub id: Option<String>,
367    /// The ID used in the Mailchimp web application. View this campaign in
368    /// your Mailchimp account at https://{dc}.admin.mailchimp.com/campaigns/show/?id={web_id}.
369    #[serde(default, skip_serializing_if = "Option::is_none")]
370    pub web_id: Option<u64>,
371    /// If this campaign is the child of another campaign, this identifies the parent
372    /// campaign. For Example, for RSS or Automation children.
373    #[serde(default, skip_serializing_if = "Option::is_none")]
374    pub parent_campaign_id: Option<String>,
375    /// There are four types of campaigns you can create in Mailchimp. A/B Split
376    /// campaigns have been deprecated and variate campaigns should be used instead.
377    #[serde(default, skip_serializing_if = "Option::is_none", rename = "type")]
378    pub campaign_type: Option<String>,
379    /// The date and time the campaign was created in ISO 8601 format.
380    #[serde(default, skip_serializing_if = "Option::is_none")]
381    pub create_time: Option<String>,
382    /// The link to the campaign’s archive version in ISO 8601 format.
383    #[serde(default, skip_serializing_if = "Option::is_none")]
384    pub archive_url: Option<String>,
385    /// The original link to the campaign’s archive version.
386    #[serde(default, skip_serializing_if = "Option::is_none")]
387    pub long_archive_url: Option<String>,
388    /// The current status of the campaign.
389    #[serde(default, skip_serializing_if = "Option::is_none")]
390    pub status: Option<String>,
391    /// The total number of emails sent for this campaign.
392    #[serde(default, skip_serializing_if = "Option::is_none")]
393    pub emails_sent: Option<u64>,
394    /// The date and time a campaign was sent.
395    #[serde(default, skip_serializing_if = "Option::is_none")]
396    pub send_time: Option<String>,
397    /// How the campaign’s content is put together (‘template’, ‘drag_and_drop’, ‘html’, ‘url’).
398    #[serde(default, skip_serializing_if = "Option::is_none")]
399    pub content_type: Option<String>,
400    /// Determines if the campaign needs its blocks refreshed by opening the web-based campaign editor.
401    #[serde(default, skip_serializing_if = "Option::is_none")]
402    pub needs_block_refresh: Option<bool>,
403    /// Determines if the campaign contains the |BRAND:LOGO| merge tag.
404    #[serde(default, skip_serializing_if = "Option::is_none")]
405    pub has_logo_merge_tag: Option<bool>,
406    /// Determines if the campaign qualifies to be resent to non-openers.
407    #[serde(default, skip_serializing_if = "Option::is_none")]
408    pub resendable: Option<bool>,
409    /// List settings for the campaign.
410    #[serde(default, skip_serializing_if = "Option::is_none")]
411    pub recipients: Option<RecipientType>,
412    /// The settings for your campaign, including subject, from name,
413    /// reply-to address, and more.
414    #[serde(default, skip_serializing_if = "Option::is_none")]
415    pub settings: Option<CampaignSettingsType>,
416    /// The settings specific to A/B test campaigns.
417    #[serde(default, skip_serializing_if = "Option::is_none")]
418    pub variate_settings: Option<VariateSettingsType>,
419    /// The tracking options for a campaign.
420    #[serde(default, skip_serializing_if = "Option::is_none")]
421    pub tracking: Option<CampaignTrackingOptionsType>,
422    /// RSS options for a campaign.
423    #[serde(default, skip_serializing_if = "Option::is_none")]
424    pub rss_opts: Option<RSSOptionsType>,
425    /// A/B Testing options for a campaign.
426    #[serde(default, skip_serializing_if = "Option::is_none")]
427    pub ab_split_opts: Option<ABTestingOptionsType>,
428    /// The preview for the campaign, rendered by social networks like
429    /// Facebook and Twitter. Learn more.
430    #[serde(default, skip_serializing_if = "Option::is_none")]
431    pub social_card: Option<SocialCardType>,
432    /// For sent campaigns, a summary of opens, clicks, and e-commerce data.
433    #[serde(default, skip_serializing_if = "Option::is_none")]
434    pub report_summary: Option<CampaignReportSummaryType>,
435    /// Updates on campaigns in the process of sending.
436    #[serde(default, skip_serializing_if = "Option::is_none")]
437    pub delivery_status: Option<CampaignDeliveryStatusType>,
438    /// Desc: A list of link types and descriptions for the API schema documents.
439    #[serde(default, skip_serializing_if = "Option::is_none")]
440    pub _links: Option<Vec<LinkType>>,
441
442    // Mailchimp API
443    #[serde(skip)]
444    _api: Rc<MailchimpApi>,
445}
446
447impl MailchimpApiUpdate for CampaignType {
448    /**
449     * Update API
450     */
451    fn set_api(&mut self, n_api: Rc<MailchimpApi>) {
452        self._api = n_api
453    }
454}
455
456///
457/// Campaigns
458///
459/// Endpoint
460///     GET /campaigns
461///
462#[derive(Serialize, Deserialize, Debug, Clone)]
463pub struct CampaignsType {
464    /// An array of objects, each representing an email in an Automation workflow.
465    #[serde(default)]
466    pub campaigns: Vec<CampaignType>,
467    /// Desc: The total number of items matching the query regardless of pagination.
468    #[serde(default)]
469    pub total_items: u64,
470    /// Desc: A list of link types and descriptions for the API schema documents.
471    #[serde(default)]
472    pub _links: Vec<LinkType>,
473}
474
475impl MailchimpCollection<CampaignType> for CampaignsType {
476    /// Total Items
477    fn get_total_items(&self) -> u64 {
478        self.total_items
479    }
480    /// Data
481    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///
497/// Schedule Batch Delivery
498///
499#[derive(Serialize, Deserialize, Debug, Clone)]
500pub struct ScheduleBatchDelivery {
501    /// The delay, in minutes, between batches.
502    #[serde(default)]
503    pub batch_delay: u64,
504    /// The number of batches for the campaign send.
505    #[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///
519/// Schedule Param
520///
521#[derive(Serialize, Deserialize, Debug, Clone)]
522pub struct ScheduleParam {
523    /// The UTC date and time to schedule the campaign for delivery in ISO 8601 format.
524    /// Campaigns may only be scheduled to send on the quarter-hour (:00, :15, :30, :45).
525    #[serde(default)]
526    pub schedule_time: String,
527    /// Choose whether the campaign should use Timewarp when sending. Campaigns
528    /// scheduled with Timewarp are localized based on the recipients’ time zones.
529    /// For example, a Timewarp campaign with a schedule_time of 13:00 will be sent
530    /// to each recipient at 1:00pm in their local time. Cannot be set to true for
531    /// campaigns using Batch Delivery.
532    #[serde(default)]
533    pub timewarp: bool,
534    /// Choose whether the campaign should use Batch Delivery. Cannot be set
535    /// to true for campaigns using Timewarp.
536    #[serde(default)]
537    pub batch_delivery: Option<ScheduleBatchDelivery>,
538}
539
540///
541/// Email Param
542///
543#[derive(Serialize, Deserialize, Debug, Clone)]
544pub struct EmailParam {
545    /// An array of email addresses to send the test email to.
546    #[serde(default)]
547    pub test_emails: Vec<String>,
548    /// Choose the type of test email to send.  html or plaintext
549    #[serde(default)]
550    pub send_type: String,
551}
552
553impl EmailParam {
554    ///
555    /// New
556    ///
557    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///
566/// Update Cmapaign Param
567///
568#[derive(Serialize, Deserialize, Debug, Clone)]
569pub struct UpdateCampaignParam {
570    /// List settings for the campaign.
571    #[serde(default, skip_serializing_if = "Option::is_none")]
572    pub recipients: Option<RecipientType>,
573    /// The settings for your campaign, including subject, from name,
574    /// reply-to address, and more.
575    #[serde(default, skip_serializing_if = "Option::is_none")]
576    pub settings: Option<CampaignSettingsType>,
577    /// The settings specific to A/B test campaigns.
578    #[serde(default, skip_serializing_if = "Option::is_none")]
579    pub variate_settings: Option<VariateSettingsType>,
580    /// The tracking options for a campaign.
581    #[serde(default, skip_serializing_if = "Option::is_none")]
582    pub tracking: Option<CampaignTrackingOptionsType>,
583    /// RSS options for a campaign.
584    #[serde(default, skip_serializing_if = "Option::is_none")]
585    pub rss_opts: Option<RSSOptionsType>,
586    /// The preview for the campaign, rendered by social networks like
587    /// Facebook and Twitter. Learn more.
588    #[serde(default, skip_serializing_if = "Option::is_none")]
589    pub social_card: Option<SocialCardType>,
590}
591
592impl CampaignType {
593    // ==== Actions ===========
594    ///
595    ///  Cancel a campaign
596    ///
597    pub fn cancel_campaign(&self) -> MailchimpResult<EmptyType> {
598        // POST /campaigns/{campaign_id}/actions/cancel-send
599        let endpoint = self.get_base_endpoint() + "/actions/cancel-send";
600        self._api
601            .post::<EmptyType, HashMap<String, String>>(&endpoint, HashMap::new())
602    }
603    ///
604    ///  Resend a campaign
605    ///
606    pub fn resend_campaign(&self) -> MailchimpResult<CampaignType> {
607        // POST /campaigns/{campaign_id}/actions/create-resend
608        let endpoint = self.get_base_endpoint() + "/actions/create-resend";
609        self._api
610            .post::<CampaignType, HashMap<String, String>>(&endpoint, HashMap::new())
611    }
612    ///
613    /// Pause an RSS-Driven campaign
614    ///
615    pub fn pause_rss_driven_campaign(&self) -> MailchimpResult<EmptyType> {
616        // POST /campaigns/{campaign_id}/actions/pause
617        let endpoint = self.get_base_endpoint() + "/actions/pause";
618        self._api
619            .post::<EmptyType, HashMap<String, String>>(&endpoint, HashMap::new())
620    }
621    ///
622    /// Replicate a campaign in saved or send status.
623    ///
624    pub fn replicate_campaign(&self) -> MailchimpResult<CampaignType> {
625        // POST /campaigns/{campaign_id}/actions/replicate
626        let endpoint = self.get_base_endpoint() + "/actions/replicate";
627        self._api
628            .post::<CampaignType, HashMap<String, String>>(&endpoint, HashMap::new())
629    }
630    ///
631    /// Resume an RSS-Driven campaign.
632    ///
633    pub fn resume_rss_driven_campaign(&self) -> MailchimpResult<EmptyType> {
634        // POST /campaigns/{campaign_id}/actions/resume
635        let endpoint = self.get_base_endpoint() + "/actions/resume";
636        self._api
637            .post::<EmptyType, HashMap<String, String>>(&endpoint, HashMap::new())
638    }
639    ///
640    /// Schedule a campaign for delivery. If you’re using Multivariate Campaigns to
641    /// test send times or sending RSS Campaigns, use the send action instead.
642    ///
643    pub fn schedule_campaign(&self, param: ScheduleParam) -> MailchimpResult<EmptyType> {
644        // POST /campaigns/{campaign_id}/actions/schedule
645        let endpoint = self.get_base_endpoint() + "/actions/schedule";
646        self._api.post::<EmptyType, ScheduleParam>(&endpoint, param)
647    }
648
649    ///
650    /// Send a Mailchimp campaign. For RSS Campaigns, the campaign will send
651    /// according to its schedule. All other campaigns will send immediately.
652    ///
653    pub fn send_campaign(&self) -> MailchimpResult<EmptyType> {
654        // POST  /campaigns/{campaign_id}/actions/send
655        let endpoint = self.get_base_endpoint() + "/actions/send";
656        self._api
657            .post::<EmptyType, HashMap<String, String>>(&endpoint, HashMap::new())
658    }
659
660    ///
661    /// Send a test email.
662    ///
663    pub fn send_test_email(&self, param: EmailParam) -> MailchimpResult<EmptyType> {
664        // POST /campaigns/{campaign_id}/actions/test
665        let endpoint = self.get_base_endpoint() + "/actions/test";
666        self._api.post::<EmptyType, EmailParam>(&endpoint, param)
667    }
668
669    ///
670    /// Unschedule a scheduled campaign that hasn’t started sending.
671    ///
672    pub fn unschedule_campaign(&self) -> MailchimpResult<EmptyType> {
673        // POST  POST /campaigns/{campaign_id}/actions/unschedule
674        let endpoint = self.get_base_endpoint() + "/actions/unschedule";
675        self._api
676            .post::<EmptyType, HashMap<String, String>>(&endpoint, HashMap::new())
677    }
678
679    // ==== DELETE ===========
680    ///
681    /// Remove a campaign from your Mailchimp account.
682    ///
683    pub fn delete(&self) -> MailchimpResult<bool> {
684        // DELETE /campaigns/{campaign_id}
685        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    // ==== UPDATE ===========
693    ///
694    /// Remove a campaign from your Mailchimp account.
695    ///
696    pub fn update(&self, param: UpdateCampaignParam) -> MailchimpResult<CampaignType> {
697        // DELETE /campaigns/{campaign_id}
698        let endpoint = self.get_base_endpoint();
699        self._api
700            .patch::<CampaignType, UpdateCampaignParam>(&endpoint, param)
701    }
702
703    // ======================== Content ===========
704
705    ///
706    /// Get the the HTML and plain-text content for a campaign.
707    ///
708    /// Arguments:
709    ///     fields: A comma-separated list of fields to return. Reference parameters
710    ///         of sub-objects with dot notation.
711    ///     exclude_fields: A comma-separated list of fields to exclude. Reference
712    ///         parameters of sub-objects with dot notation.
713    ///
714    pub fn get_content(
715        &self,
716        fields: Option<String>,
717        exclude_fields: Option<String>,
718    ) -> MailchimpResult<CampaignContentType> {
719        // GET /campaigns/{campaign_id}/content
720        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    ///
733    /// Set the content for a campaign.
734    ///
735    pub fn update_content(
736        &self,
737        param: CampaignContentParam,
738    ) -> MailchimpResult<CampaignContentType> {
739        // PUT /campaigns/{campaign_id}/content
740        let endpoint = self.get_base_endpoint() + "/content";
741        self._api
742            .put::<CampaignContentType, CampaignContentParam>(&endpoint, param)
743    }
744
745    // ======================== Send Checklist ===========
746    ///
747    /// Review the send checklist for a campaign, and resolve any issues before sending.
748    ///
749    /// Arguments:
750    ///     fields: A comma-separated list of fields to return. Reference parameters
751    ///         of sub-objects with dot notation.
752    ///     exclude_fields: A comma-separated list of fields to exclude. Reference
753    ///         parameters of sub-objects with dot notation.
754    ///
755    pub fn send_checklist(
756        &self,
757        fields: Option<String>,
758        exclude_fields: Option<String>,
759    ) -> MailchimpResult<SendChecklistType> {
760        // GET /campaigns/{campaign_id}/send-checklist
761        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    // ======================== Feedback ===========
773    ///
774    /// Get team feedback while you’re working together on a Mailchimp campaign.
775    ///
776    /// Arguments:
777    ///     fields: A comma-separated list of fields to return. Reference
778    ///         parameters of sub-objects with dot notation.
779    ///     exclude_fields: A comma-separated list of fields to exclude.
780    ///         Reference parameters of sub-objects with dot notation.
781    ///
782    pub fn get_feedbacks(
783        &self,
784        fields: Option<String>,
785        exclude_fields: Option<String>,
786    ) -> MalchimpIter<CampaignFeedbackBuilder> {
787        // GET /campaigns/{campaign_id}/feedback
788        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    ///
832    /// Get Feedback Info
833    ///
834    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        // GET /campaigns/{campaign_id}/feedback/{feedback_id}
841        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    ///
863    /// Return the endpoint path
864    ///
865    fn get_base_endpoint(&self) -> String {
866        String::from("campaigns/") + &self.id.as_ref().unwrap()
867    }
868}