1use std::fs;
2use json::JsonValue;
3use lettre::{Message, SmtpTransport, Transport};
4use lettre::message::{Attachment, header, MultiPart, SinglePart};
5use lettre::message::header::ContentType;
6use lettre::transport::smtp::authentication::Credentials;
7use log::info;
8
9#[derive(Clone)]
10pub struct Smtp {
11 default: String,
12 connections: JsonValue,
13
14 send_name: String,
15 send_mail: String,
16 send_pass: String,
17
18 smtp_host: String,
19 smtp_port: u16,
20
21 to_name: String,
22 to_mail: String,
23 reply_to_name: String,
24 reply_to_mail: String,
25}
26
27impl Smtp {
28 pub fn connect(config: JsonValue) -> Self {
42 if config.is_empty() {
43 return Self {
44 default: "".to_string(),
45 connections: JsonValue::Null,
46 send_name: "".to_string(),
47 send_mail: "".to_string(),
48 send_pass: "".to_string(),
49 smtp_host: "".to_string(),
50 smtp_port: 0,
51 to_name: "".to_string(),
52 to_mail: "".to_string(),
53 reply_to_name: "".to_string(),
54 reply_to_mail: "".to_string(),
55 };
56 }
57 let default = config["default"].to_string();
58 let connections = config["connections"].clone();
59 let connection = connections[default.clone()].clone();
60
61 let smtp_host = connection["smtp_host"].to_string();
62 let smtp_port = connection["smtp_port"].as_u16().unwrap();
63
64 let send_name = connection["send_name"].to_string();
65 let send_mail = connection["send_mail"].to_string();
66 let send_pass = connection["send_pass"].to_string();
67
68 Self {
69 default,
70 connections,
71 send_name,
72 send_mail,
73 send_pass,
74 smtp_host,
75 smtp_port,
76 to_name: String::new(),
77 to_mail: String::new(),
78 reply_to_name: String::new(),
79 reply_to_mail: String::new(),
80 }
81 }
82
83 pub fn change_connection(&mut self, name: &str) {
84 let connection = self.connections[name.clone()].clone();
85 self.default = name.to_string();
86 self.smtp_host = connection["smtp_host"].to_string();
87 self.smtp_port = connection["smtp_port"].as_u16().unwrap();
88 self.send_name = connection["send_name"].to_string();
89 self.send_mail = connection["send_mail"].to_string();
90 self.send_pass = connection["send_pass"].to_string();
91 }
92
93 pub fn set_send_name(&mut self, send_name: &str) -> &mut Self {
95 self.send_name = send_name.to_string();
96 self
97 }
98
99 pub fn to(&mut self, name: &str, mail: &str) -> &mut Self {
103 self.to_name = name.to_string();
104 self.to_mail = mail.to_string();
105 self
106 }
107 pub fn reply_to(&mut self, name: &str, mail: &str) -> &mut Self {
111 self.reply_to_name = name.to_string();
112 self.reply_to_mail = mail.to_string();
113 self
114 }
115
116 pub fn add_file(&mut self, path: &str, name: &str, content_type: &str) -> SinglePart {
118 let content_type = {
119 match content_type {
120 "pdf" => {
121 ContentType::parse("application/pdf").unwrap()
122 }
123 "html" => {
124 ContentType::parse("text/html").unwrap()
125 }
126 "jpeg" => {
127 ContentType::parse("image/jpeg").unwrap()
128 }
129 "json" => {
130 ContentType::parse("application/json").unwrap()
131 }
132 _ => {
133 ContentType::parse("text/plain").unwrap()
134 }
135 }
136 };
137 return Attachment::new(name.to_string()).body(fs::read(path.clone()).unwrap(), content_type);
138 }
139 pub fn send(&mut self, subject: &str, body: &str, files: Vec<SinglePart>) -> bool {
144 let mut builder = Message::builder().from(format!("{} <{}>",self.send_name,self.send_mail).parse().unwrap()).subject(subject);
145
146 builder = builder.to(format!("{} <{}>", self.to_name, self.to_mail).parse().unwrap());
147
148 if !self.reply_to_name.is_empty() {
149 builder = builder.reply_to(format!("{} <{}>", self.reply_to_name, self.reply_to_mail).parse().unwrap());
150 }
151
152 let mut body = MultiPart::alternative().multipart(
153 MultiPart::alternative_plain_html(String::from("text/plain"), String::from(body))
154 ).singlepart(SinglePart::builder().header(header::ContentType::TEXT_PLAIN).body(String::from(body)));
155
156 if !files.is_empty() {
157 for file in files.iter() {
158 body = body.singlepart(file.clone()).clone();
159 }
160 }
161
162 let email = builder.multipart(body.clone()).unwrap();
163
164 let mailer = SmtpTransport::relay(self.smtp_host.as_str())
165 .unwrap()
166 .port(self.smtp_port)
167 .credentials(Credentials::new(self.send_mail.to_string(), self.send_pass.to_string()))
168 .build();
169 match mailer.send(&email) {
170 Ok(_) => {
171 true
172 }
173 Err(e) => {
174 info!("错误: {}", e);
175 false
176 }
177 }
178 }
179}