1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
use errors::SendgridResult;
use mail::Mail;
use std::io::Read;
use reqwest::header::{Authorization, Bearer, ContentType, Headers, UserAgent};
use reqwest::Client;
use url::form_urlencoded::Serializer;
static API_URL: &'static str = "https://api.sendgrid.com/api/mail.send.json?";
pub struct SGClient {
api_key: String,
}
fn make_form_key(form: &str, key: &str) -> String {
let mut value = String::new();
value.push_str(form);
value.push('[');
value.push_str(key);
value.push(']');
value
}
fn make_post_body(mut mail_info: Mail) -> SendgridResult<String> {
let body = String::new();
let mut encoder = Serializer::new(body);
for to in mail_info.to.iter() {
encoder.append_pair("to[]", &to);
}
for to_name in mail_info.to_names.iter() {
encoder.append_pair("toname[]", &to_name);
}
for cc in mail_info.cc.iter() {
encoder.append_pair("cc[]", &cc);
}
for bcc in mail_info.bcc.iter() {
encoder.append_pair("bcc[]", &bcc);
}
for (attachment, contents) in &mail_info.attachments {
encoder.append_pair(&make_form_key("files", attachment), contents);
}
for (id, value) in &mail_info.content {
encoder.append_pair(&make_form_key("content", id), value);
}
encoder.append_pair("from", &mail_info.from);
encoder.append_pair("subject", &mail_info.subject);
encoder.append_pair("html", &mail_info.html);
encoder.append_pair("text", &mail_info.text);
encoder.append_pair("fromname", &mail_info.from_name);
encoder.append_pair("replyto", &mail_info.reply_to);
encoder.append_pair("date", &mail_info.date);
encoder.append_pair("headers", &mail_info.make_header_string()?);
encoder.append_pair("x-smtpapi", &mail_info.x_smtpapi);
Ok(encoder.finish())
}
impl SGClient {
pub fn new(key: String) -> SGClient {
SGClient { api_key: key }
}
pub fn send(self, mail_info: Mail) -> SendgridResult<String> {
let client = Client::new()?;
let mut headers = Headers::new();
headers.set(Authorization(Bearer { token: self.api_key.to_owned() }));
headers.set(ContentType::form_url_encoded());
headers.set(UserAgent::new("sendgrid-rs"));
let post_body = make_post_body(mail_info)?;
let mut res = client
.post(API_URL)?
.headers(headers)
.body(post_body)
.send()?;
let mut body = String::new();
res.read_to_string(&mut body)?;
Ok(body)
}
}
#[test]
fn basic_message_body() {
let mut m = Mail::new();
m.add_to("test@example.com");
m.add_from("me@example.com");
m.add_subject("Test");
m.add_text("It works");
let body = make_post_body(m);
let want = "to%5B%5D=test%40example.com&from=me%40example.com&subject=Test&\
html=&text=It+works&fromname=&replyto=&date=&headers=%7B%7D&x-smtpapi=";
assert_eq!(body.unwrap(), want);
}
#[test]
fn test_proper_key() {
let want = "files[test.jpg]";
let got = make_form_key("files", "test.jpg");
assert_eq!(want, got);
}