1 个不稳定版本
0.1.0 | 2020年3月29日 |
---|
#217 在 电子邮件
17KB
278 行代码(不包括注释)
cheap_alerts
通过电子邮件发送文本警报的实用工具
基本思想
所有美国蜂窝网络服务提供商都允许用户通过电子邮件发送和接收短信。利用这一点,如果您有访问电子邮件服务器的权限,就可以发送类似推送的通知。
一个例子
假设您的电话号码是(612)-555-0111,您的运营商是Verizon,您的号码将有一个电子邮件地址 [email protected]。
假设您想在您的最喜欢的当地披萨店您的披萨订单状态改变时收到提醒。您可以构建一个小的网络爬虫来跟踪您的当前订单,当状态改变时,您可以通过发送电子邮件来将更新状态发送到您的手机。
use cheap_alerts::{Carrier, Destination, Sender};
use std::sync::atomic::{AtomicU8, Ordering};
static STATUS: AtomicU8 = AtomicU8::new(0);
fn main() {
let mut current: Option<String> = None;
loop {
match check_for_pizza_status() {
Some(status) => {
if let Some(prev) = ¤t {
if prev != &status {
send_update(&status, &prev);
current = Some(status.to_string());
}
} else {
send_update(&status, "nothing");
current = Some(status.to_string());
}
}
None => {
current = None;
}
}
std::thread::sleep(std::time::Duration::from_secs(1));
}
}
/// Fake web scraping
fn check_for_pizza_status() -> Option<&'static str> {
let old = STATUS.fetch_add(1, Ordering::Relaxed);
if old > 4 {
STATUS.store(0, Ordering::Relaxed);
None
} else {
determine_status(&STATUS)
}
}
fn determine_status(val: &AtomicU8) -> Option<&'static str> {
match val.load(Ordering::Relaxed) {
1 => Some("Pending"),
2 => Some("Cooking"),
3 => Some("On the way"),
4 => Some("Complete"),
_ => None,
}
}
fn send_update(new: &str, old: &str) {
let mut sender = Sender::builder()
.address("[email protected]")
.stdout()
.expect("failed to create sender");
let dest = Destination::new("6125550111", &Carrier::Verizon);
sender
.send_to(
&dest,
&format!(
"🍕🍕🍕🍕🍕🍕🍕🍕\nPizza Update: {} -> {}\n🍕🍕🍕🍕🍕🍕🍕🍕\n===========\n",
old, new
),
)
.expect("failed to send notification");
}
一些细节
电子邮件部分基于 lettre
构建,发送者有3种选项
- 文件:接受文件路径,并将电子邮件作为 json 格式写入文件系统上的文件,文件名使用消息 ID(RFC 2822 时间戳)
- Sendmail:使用
sendmail
命令行工具发送电子邮件 - SMTP:使用简单邮件传输协议,有3种方法
- 未加密的本地主机,这是最简单但最不安全的方法
- 简单,您提供一个域名(作为
&str
),它将使用 TLS 发送消息 - 完整,这是
依赖关系
~3–4MB
~69K SLoC