1use anyhow::Result;
2use rusoto_core::Region;
3use rusoto_sns::{MessageAttributeValue, PublishInput, PublishResponse, Sns, SnsClient};
4use std::{collections::HashMap, process};
5pub enum SmsType {
6 Promotional,
7 Transactional,
8}
9
10impl SmsType {
11 fn value(&self) -> String {
12 match *self {
13 SmsType::Promotional => "Promotional".into(),
14 SmsType::Transactional => "Transactional".into(),
15 }
16 }
17}
18
19pub struct SMS {
20 pub sms_type: SmsType,
21 pub sender_id: String,
22 pub max_price: f64,
23}
24
25impl Default for SMS {
26 fn default() -> Self {
27 SMS {
28 sms_type: SmsType::Transactional,
29 sender_id: "".into(),
30 max_price: 0.01,
31 }
32 }
33}
34
35impl SMS {
36 pub async fn send(&self, message: String, phone_number: String) -> Result<PublishResponse> {
37 let aws_region = std::env::var("AWS_REGION").unwrap_or_else(|_| {
38 println!(
39 "Error: AWS_REGION env variable is required. \nTIP: export AWS_REGION=us-east-1"
40 );
41 process::exit(1);
42 });
43 let _aws_key = std::env::var("AWS_SECRET_ACCESS_KEY").unwrap_or_else(|_| {
44 println!(
45 "Error: AWS_SECRET_ACCESS_KEY env variable is required. \nTIP: export AWS_SECRET_ACCESS_KEY=xxxxx"
46 );
47 process::exit(1);
48 });
49 let _aws_access = std::env::var("AWS_ACCESS_KEY_ID").unwrap_or_else(|_| {
50 println!(
51 "Error: AWS_ACCESS_KEY_ID env variable is required. \nTIP: export AWS_ACCESS_KEY_ID=xxxxx"
52 );
53 process::exit(1);
54 });
55
56 let mut attrs: HashMap<String, MessageAttributeValue> = HashMap::new();
57
58 if self.sender_id != "" {
59 attrs.insert(
60 "AWS.SNS.SMS.SenderID".into(),
61 rusoto_sns::MessageAttributeValue {
62 data_type: "String".to_string(),
63 string_value: Some(self.sender_id.clone()),
64 binary_value: None,
65 },
66 );
67 }
68
69 attrs.insert(
70 "AWS.SNS.SMS.MaxPrice".into(),
71 rusoto_sns::MessageAttributeValue {
72 data_type: "String".to_string(),
73 string_value: Some(self.max_price.to_string()),
74 binary_value: None,
75 },
76 );
77
78 attrs.insert(
79 "AWS.SNS.SMS.SMSType".into(),
80 rusoto_sns::MessageAttributeValue {
81 data_type: "String".to_string(),
82 string_value: Some(self.sms_type.value()),
83 binary_value: None,
84 },
85 );
86
87 let params = PublishInput {
88 message: message.into(),
89 phone_number: Some(phone_number.into()),
90 message_attributes: Some(attrs),
91 ..Default::default()
92 };
93
94 let client = SnsClient::new(aws_region.parse::<Region>()?);
95 Ok(client.publish(params).await?)
96 }
97}