1
2
3use serde::{Deserialize, Serialize};
45use reqwest::Client;
46
47use std::collections::HashMap;
48use std::time::Duration;
49use std::io::{Result, Error, ErrorKind};
50
51
52const URL: &str = "https://sms.yunpian.com/v2/sms/single_send.json";
53const SUCC_CODE: i64 = 0i64;
54
55#[derive(Debug, Deserialize, Serialize)]
56struct SingleSendResult {
57 code: i64,
58 msg: String,
59 count: i64,
60 fee: f64,
61 unit: String,
62 mobile: String,
63 sid: i64,
64}
65
66pub struct Yunpian<'a> {
67 api_key: &'a str,
68 http_client: Client,
69}
70
71impl<'a> Yunpian<'a>{
72 pub fn new(api_key: &'a str) -> Yunpian {
73 Yunpian{
74 api_key,
75 http_client: Client::new(),
76 }
77 }
78
79 pub async fn single_send(&self, text: &str, phone: &str) -> Result<bool> {
80 let mut param = HashMap::new();
81 param.insert("text", text);
82 param.insert("mobile", phone);
83 param.insert("apikey", &self.api_key);
84
85 let response = match self.http_client
86 .post(URL)
87 .form(¶m)
88 .timeout(Duration::from_secs(10))
89 .send().await{
90 Ok(t) => t,
91 Err(e) => {
92 let err_str = format!("{}", e);
93 return Err(Error::new(ErrorKind::Other, err_str))
94 }
95 };
96
97 let response_obj: SingleSendResult = match response.json().await{
98 Ok(t) => t,
99 Err(e) => {
100 let err_str = format!("{}", e);
101 return Err(Error::new(ErrorKind::Other, err_str))
102 }
103 };
104
105 if response_obj.code == SUCC_CODE {
106 return Ok(true);
107 }
108
109 Err(Error::new(ErrorKind::Other, response_obj.msg))
110
111 }
112}
113
114
115#[cfg(test)]
116mod tests {
117
118 use super::*;
119
120 #[tokio::test]
121 async fn test_single_send(){
122 let api_key = "云片api_key";
123 let sms = Yunpian::new(api_key);
124 let text = "【天涯网络】您的验证码为1024,10分钟内有效,请勿泄露。如非本人操作,请忽略本短信。";
125 let phone = "18610996705";
126 let result = match sms.single_send(text, phone).await{
127 Ok(b) => b,
128 Err(_e) => false
129 };
130
131 assert_eq!(true, result)
132 }
133
134}