sendgrid_rs/
message.rs

1use crate::attachment::Attachment;
2use crate::mail_settings::MailSettings;
3use crate::personalization::Personalization;
4use crate::tracking_settings::TrackingSettings;
5use crate::{Asm, Contact, Content};
6use serde::Serialize;
7use std::collections::HashMap;
8
9/// Message is the wrapper around the entire payload to be sent to SendGrid's API.
10/// Use [MessageBuilder](struct.MessageBuilder.html) to properly construct this. The `to_json`
11/// method is available to turn this struct into the request body to send to SendGrid
12#[derive(Debug, Serialize)]
13pub struct Message {
14    #[serde(skip_serializing_if = "Vec::is_empty")]
15    personalizations: Vec<Personalization>,
16    from: Contact,
17    #[serde(skip_serializing_if = "Option::is_none")]
18    reply_to: Option<Contact>,
19    subject: String,
20    #[serde(skip_serializing_if = "Vec::is_empty")]
21    content: Vec<Content>,
22    #[serde(skip_serializing_if = "Vec::is_empty")]
23    attachments: Vec<Attachment>,
24    #[serde(skip_serializing_if = "Option::is_none")]
25    template_id: Option<String>,
26    #[serde(skip_serializing_if = "HashMap::is_empty")]
27    sections: HashMap<String, String>,
28    #[serde(skip_serializing_if = "HashMap::is_empty")]
29    headers: HashMap<String, String>,
30    #[serde(skip_serializing_if = "Vec::is_empty")]
31    categories: Vec<String>,
32    #[serde(skip_serializing_if = "HashMap::is_empty")]
33    custom_args: HashMap<String, String>,
34    #[serde(skip_serializing_if = "Option::is_none")]
35    send_at: Option<i32>,
36    #[serde(skip_serializing_if = "Option::is_none")]
37    batch_id: Option<String>,
38    #[serde(skip_serializing_if = "Option::is_none")]
39    asm: Option<Asm>,
40    #[serde(skip_serializing_if = "Option::is_none")]
41    ip_pool_name: Option<String>,
42    #[serde(skip_serializing_if = "Option::is_none")]
43    mail_settings: Option<MailSettings>,
44    #[serde(skip_serializing_if = "Option::is_none")]
45    tracking_settings: Option<TrackingSettings>,
46}
47
48impl Message {
49    /// `to_json` serializes the entire message into JSON. The result of this method call
50    /// should contain the entire body for the HTTP POST to SendGrid. This method will
51    /// panic if it is unable to serialize, because it is likely a bug in this crate that
52    /// is causing it.
53    pub fn to_json(&self) -> String {
54        serde_json::to_string(&self).expect("could not properly serialize into JSON")
55    }
56}
57
58/// A `builder pattern` type for constructing `Message`
59///
60/// Use this to construct a Message with the desired data.
61/// Make sure you call the 'build' method at the end to
62/// consume this builder and return the underyling message.
63///
64/// # API Requirements
65/// At least one personalization is required
66/// From is required, but handled in the constructor
67/// Subject is required, but handled in the constructor
68pub struct MessageBuilder {
69    message: Message,
70}
71
72impl MessageBuilder {
73    /// Creates a `MessageBuilder`.
74    ///
75    /// # Parameters
76    /// from: Contact
77    /// subject: impl Into<String>
78    ///
79    /// # Examples
80    ///
81    /// ```
82    /// # use sendgrid_rs::{MessageBuilder, ContactBuilder};
83    ///
84    /// let builder = MessageBuilder::new(
85    ///         ContactBuilder::new("from@example.com").build(),
86    ///         "Subject Line"
87    ///     );
88    /// ```
89    pub fn new(from: Contact, subject: impl Into<String>) -> Self {
90        MessageBuilder {
91            message: Message {
92                personalizations: vec![],
93                from,
94                reply_to: None,
95                subject: subject.into(),
96                content: vec![],
97                attachments: vec![],
98                template_id: None,
99                sections: HashMap::new(),
100                headers: HashMap::new(),
101                categories: vec![],
102                custom_args: HashMap::new(),
103                send_at: None,
104                batch_id: None,
105                asm: None,
106                ip_pool_name: None,
107                mail_settings: None,
108                tracking_settings: None,
109            },
110        }
111    }
112
113    /// Adds a `Personalization` to the `Message`
114    /// At least one is required according to the API specification
115    /// Use a `PersonalizationBuilder` to construct the `Personalization`
116    ///
117    /// # Examples
118    /// ```
119    /// # use sendgrid_rs::{MessageBuilder, ContactBuilder, PersonalizationBuilder};
120    ///
121    /// let builder = MessageBuilder::new(
122    ///         ContactBuilder::new("from@example.com").build(),
123    ///         "Subject Line"
124    ///     )
125    ///     .personalization(
126    ///         PersonalizationBuilder::default().build()
127    ///     );
128    /// ```
129    pub fn personalization(mut self, per: Personalization) -> Self {
130        self.message.personalizations.push(per);
131        self
132    }
133
134    /// Overwrites personalializations with input data.
135    ///
136    /// Use this to assign many personalizations at once.
137    ///
138    /// # Examples
139    /// ```
140    /// # use sendgrid_rs::{MessageBuilder, ContactBuilder, personalization::Personalization};
141    ///
142    /// let personalizations: Vec<Personalization> = Vec::new();
143    /// let builder = MessageBuilder::new(
144    ///         ContactBuilder::new("from@example.com").build(),
145    ///         "Subject Line"
146    ///     )
147    ///     .personalizations(personalizations);
148    /// ```
149    pub fn personalizations(mut self, data: Vec<Personalization>) -> Self {
150        self.message.personalizations = data;
151        self
152    }
153
154    /// Adds a reply_to `Contact` to the `Message`
155    /// Use a `ContactBuilder` to construct the `Contact`
156    ///
157    /// # Examples
158    /// ```
159    /// # use sendgrid_rs::{MessageBuilder, ContactBuilder};
160    ///
161    /// let builder = MessageBuilder::new(
162    ///         ContactBuilder::new("from@example.com").build(),
163    ///         "Subject Line"
164    ///     )
165    ///     .reply_to(
166    ///         ContactBuilder::new("reply_to@example.com").build()
167    ///     );
168    /// ```
169    pub fn reply_to(mut self, contact: Contact) -> Self {
170        self.message.reply_to = Some(contact);
171        self
172    }
173
174    /// Adds a `Content` to to the `Message`
175    ///
176    /// # Examples
177    /// ```
178    /// # use sendgrid_rs::{MessageBuilder, ContactBuilder, Content};
179    ///
180    /// let builder = MessageBuilder::new(
181    ///         ContactBuilder::new("from@example.com").build(),
182    ///         "Subject Line"
183    ///         )
184    ///         .content(
185    ///             Content::new("text/plain", "Email Body")
186    ///         );
187    /// ```
188    pub fn content(mut self, content: Content) -> Self {
189        self.message.content.push(content);
190        self
191    }
192
193    /// Adds an `Attachment` to the `Message`
194    /// Use an `AttachmentBuilder` to construct the `Attachment`
195    ///
196    /// # Examples
197    /// ```
198    /// # use sendgrid_rs::{MessageBuilder, ContactBuilder, AttachmentBuilder};
199    ///
200    /// let builder = MessageBuilder::new(
201    ///         ContactBuilder::new("from@example.com").build(),
202    ///         "Subject Line"
203    ///         )
204    ///         .attachment(
205    ///             AttachmentBuilder::new(
206    ///                 "SGVsbG8gV29ybGQh",
207    ///                 "file.txt"
208    ///             ).build()
209    ///         );
210    /// ```
211    pub fn attachment(mut self, attachment: Attachment) -> Self {
212        self.message.attachments.push(attachment);
213        self
214    }
215
216    /// Sets the template id the `Message` will use.
217    ///
218    /// # Examples
219    /// ```
220    /// # use sendgrid_rs::{MessageBuilder, ContactBuilder};
221    ///
222    /// let builder = MessageBuilder::new(
223    ///         ContactBuilder::new("from@example.com").build(),
224    ///         "Subject Line"
225    ///         )
226    ///         .template_id("0001");
227    /// ```
228    pub fn template_id(mut self, id: impl Into<String>) -> Self {
229        self.message.template_id = Some(id.into());
230        self
231    }
232
233    /// Adds a section key/value pair to the `Message`
234    ///
235    /// # Examples
236    /// ```
237    /// # use sendgrid_rs::{MessageBuilder, ContactBuilder};
238    ///
239    /// let builder = MessageBuilder::new(
240    ///         ContactBuilder::new("from@example.com").build(),
241    ///         "Subject Line"
242    ///         )
243    ///         .section("Key", "Value");
244    /// ```
245    pub fn section<S: Into<String>>(mut self, key: S, value: S) -> Self {
246        self.message.sections.insert(key.into(), value.into());
247        self
248    }
249
250    /// Adds a header key/value pair to the `Message`
251    ///
252    /// # Examples
253    /// ```
254    /// # use sendgrid_rs::{MessageBuilder, ContactBuilder};
255    ///
256    /// let builder = MessageBuilder::new(
257    ///         ContactBuilder::new("from@example.com").build(),
258    ///         "Subject Line"
259    ///         )
260    ///         .header("Key", "Value");
261    /// ```
262    pub fn header<S: Into<String>>(mut self, key: S, value: S) -> Self {
263        self.message.headers.insert(key.into(), value.into());
264        self
265    }
266
267    /// Adds a category to the `Message`
268    ///
269    /// # Examples
270    /// ```
271    /// # use sendgrid_rs::{MessageBuilder, ContactBuilder};
272    ///
273    /// let builder = MessageBuilder::new(
274    ///         ContactBuilder::new("from@example.com").build(),
275    ///         "Subject Line"
276    ///         )
277    ///         .category("Marketing");
278    /// ```
279    pub fn category(mut self, category: impl Into<String>) -> Self {
280        self.message.categories.push(category.into());
281        self
282    }
283
284    /// Adds a custom arg to the `Message`
285    ///
286    /// # Examples
287    /// ```
288    /// # use sendgrid_rs::{MessageBuilder, ContactBuilder};
289    ///
290    /// let builder = MessageBuilder::new(
291    ///         ContactBuilder::new("from@example.com").build(),
292    ///         "Subject Line"
293    ///         )
294    ///         .custom_arg("arg_name", "arg_value");
295    /// ```
296    pub fn custom_arg<S: Into<String>>(mut self, key: S, value: S) -> Self {
297        self.message.custom_args.insert(key.into(), value.into());
298        self
299    }
300
301    /// Adds a send_at time to the `Message`
302    ///
303    /// # Examples
304    /// ```
305    /// # use sendgrid_rs::{MessageBuilder, ContactBuilder};
306    ///
307    /// let builder = MessageBuilder::new(
308    ///         ContactBuilder::new("from@example.com").build(),
309    ///         "Subject Line"
310    ///         )
311    ///         .send_at(3600);
312    /// ```
313    pub fn send_at(mut self, time: i32) -> Self {
314        self.message.send_at = Some(time);
315        self
316    }
317
318    /// Adds a batch_id to the `Message`
319    ///
320    /// # Examples
321    /// ```
322    /// # use sendgrid_rs::{MessageBuilder, ContactBuilder};
323    ///
324    /// let builder = MessageBuilder::new(
325    ///         ContactBuilder::new("from@example.com").build(),
326    ///         "Subject Line"
327    ///         )
328    ///         .batch_id("abc123");
329    /// ```
330    pub fn batch_id(mut self, id: impl Into<String>) -> Self {
331        self.message.batch_id = Some(id.into());
332        self
333    }
334
335    /// Adds an `Asm` to the `Message`
336    /// Use `AsmBuilder` to construct the `Asm`
337    ///
338    /// # Examples
339    /// ```
340    /// # use sendgrid_rs::{MessageBuilder, ContactBuilder, AsmBuilder};
341    ///
342    /// let builder = MessageBuilder::new(
343    ///         ContactBuilder::new("from@example.com").build(),
344    ///         "Subject Line"
345    ///         )
346    ///         .asm(
347    ///             AsmBuilder::new(1)
348    ///             .build()
349    ///         );
350    /// ```
351    pub fn asm(mut self, asm: Asm) -> Self {
352        self.message.asm = Some(asm);
353        self
354    }
355
356    /// Adds the ip_pool_name to the `Message`
357    ///
358    /// # Examples
359    /// ```
360    /// # use sendgrid_rs::{MessageBuilder, ContactBuilder};
361    ///
362    /// let builder = MessageBuilder::new(
363    ///         ContactBuilder::new("from@example.com").build(),
364    ///         "Subject Line"
365    ///         )
366    ///         .ip_pool_name("marketing_pool");
367    /// ```
368    pub fn ip_pool_name(mut self, name: impl Into<String>) -> Self {
369        self.message.ip_pool_name = Some(name.into());
370        self
371    }
372
373    /// Adds `MailSettings` to the `Message`
374    /// Use `MailSettingsBuilder` to construct the `MailSettings`
375    ///
376    /// # Examples
377    /// ```
378    /// # use sendgrid_rs::{MessageBuilder, ContactBuilder, MailSettingsBuilder};
379    ///
380    /// let builder = MessageBuilder::new(
381    ///         ContactBuilder::new("from@example.com").build(),
382    ///         "Subject Line"
383    ///         )
384    ///         .mail_settings(
385    ///             MailSettingsBuilder::default().build()
386    ///         );
387    /// ```
388    pub fn mail_settings(mut self, settings: MailSettings) -> Self {
389        self.message.mail_settings = Some(settings);
390        self
391    }
392
393    /// Adds `TrackingSettings` to the `Message`
394    /// Use `TrackingSettingsBuilder` to construct the `TrackingSettings`
395    ///
396    /// # Examples
397    /// ```
398    /// # use sendgrid_rs::{MessageBuilder, ContactBuilder, TrackingSettingsBuilder};
399    ///
400    /// let builder = MessageBuilder::new(
401    ///         ContactBuilder::new("from@example.com").build(),
402    ///         "Subject Line"
403    ///         )
404    ///         .tracking_settings(
405    ///             TrackingSettingsBuilder::default().build()
406    ///         );
407    /// ```
408    pub fn tracking_settings(mut self, settings: TrackingSettings) -> Self {
409        self.message.tracking_settings = Some(settings);
410        self
411    }
412
413    /// Consumes the `MessageBuilder` and returns the `Message`
414    ///
415    /// # Examples
416    /// ```
417    /// # use sendgrid_rs::{MessageBuilder, ContactBuilder};
418    ///
419    /// let message = MessageBuilder::new(
420    ///         ContactBuilder::new("from@example.com").build(),
421    ///         "Subject Line"
422    ///         )
423    ///         .build();
424    /// ```
425    pub fn build(self) -> Message {
426        self.message
427    }
428}