rupushdeer/
lib.rs

1//!# Pushdeer SDK for Rust
2//!
3//!## install
4//!
5//!```toml
6//![dependencies]
7//!rupushdeer = "0.1.0"
8//!```
9//!
10//!## Usage:
11//!
12//!### 1. Use pushdeer default server
13//!
14//!```rust
15//!use rupushdeer::PushDeer;
16//!
17//!let deer = PushDeer::new("PDU5315TCkMN0KiBRqbceaXxpYx3DvdbiZ3JpAIE");
18//!deer.send_text("title").expect("");
19//!deer.send_text_with_desp("Hello", "send_text_with_desp").expect("");
20//!deer.send_markdown("# markdown\npushdeer").expect("");
21//!deer.send_markdown_with_desp("# markdown\npushdeer", "send_markdown_with_desp").expect("");
22//!deer.send_image("https://gitee.com/easychen/pushdeer/raw/main/doc/image/clipcode.png").expect("");
23//! ```
24//!
25//!### 2. Use self-hosted server
26//!
27//!```rust
28//!use rupushdeer::PushDeer;
29//!
30//!let deer = PushDeer::new("PDU5315TCkMN0KiBRqbceaXxpYx3DvdbiZ3JpAIE").set_server("http://127.0.0.1:12345");
31//!deer.send_text("title").expect("");
32//!```
33
34use log::debug;
35use serde_json::Value;
36use std::ops::Add;
37
38pub struct PushDeer {
39    server: String,
40    endpoint: String,
41    push_key: String,
42}
43
44impl PushDeer {
45    pub fn new(push_key: impl Into<String>) -> Self {
46        let push_key = push_key.into();
47        PushDeer {
48            server: String::from("https://api2.pushdeer.com"),
49            endpoint: String::from("/message/push"),
50            push_key,
51        }
52    }
53
54    pub fn set_server(mut self, server: impl Into<String>) -> Self {
55        let server = server.into();
56        self.server = server;
57        self
58    }
59
60    fn push(
61        &self,
62        text: impl Into<String>,
63        desp: Option<impl Into<String>>,
64        text_type: String,
65    ) -> Result<(), Box<dyn std::error::Error>> {
66        let text = text.into();
67        let desp = if desp.is_some() {
68            desp.unwrap().into()
69        } else {
70            String::from("")
71        };
72
73        let client = reqwest::blocking::Client::new();
74        let mut params = vec![("pushkey", &self.push_key), ("text", &text)];
75        if desp.ne("") {
76            params.push(("desp", &desp));
77        }
78        if !text_type.eq("text") {
79            params.push(("type", &text_type));
80        }
81
82        let res = client
83            .get(String::from(&self.server).add(&self.endpoint))
84            .query(&params)
85            .send()?;
86        debug!("pushing url: {}", res.url().as_str());
87
88        let json_serde: Value = res.json()?;
89        debug!("pushing result: {}", &json_serde);
90        let json_serde = json_serde["content"]["result"][0].as_str().unwrap();
91        let json_res: Value = serde_json::from_str(json_serde)?;
92
93        if json_res["success"] == "ok" {
94            Ok(())
95        } else {
96            Err("push error".into())
97        }
98    }
99
100    /// Any text are accepted when type is text.
101    pub fn send_text(&self, body: impl Into<String>) -> Result<(), Box<dyn std::error::Error>> {
102        self.push(body, None::<String>, String::from("text"))
103    }
104
105    /// Any text with the second part are accepted when type is text.
106    pub fn send_text_with_desp(
107        &self,
108        body: impl Into<String>,
109        desp: impl Into<String>,
110    ) -> Result<(), Box<dyn std::error::Error>> {
111        self.push(body, Some(desp), String::from("text"))
112    }
113
114    /// Text in Markdown format are accepted when type is markdown.
115    pub fn send_markdown(&self, body: impl Into<String>) -> Result<(), Box<dyn std::error::Error>> {
116        self.push(body, None::<String>, String::from("markdown"))
117    }
118
119    /// Text in Markdown format with the second part are accepted when type is markdown.
120    pub fn send_markdown_with_desp(
121        &self,
122        body: impl Into<String>,
123        desp: impl Into<String>,
124    ) -> Result<(), Box<dyn std::error::Error>> {
125        self.push(body, Some(desp), String::from("markdown"))
126    }
127
128    /// Only image src are accepted by API now, when type is image.
129    pub fn send_image(&self, body: impl Into<String>) -> Result<(), Box<dyn std::error::Error>> {
130        self.push(body, None::<String>, String::from("image"))
131    }
132}
133
134#[cfg(test)]
135mod tests {
136    use super::*;
137
138    #[test]
139    fn set_server() -> Result<(), Box<dyn std::error::Error>> {
140        PushDeer::new("PDU5315TCkMN0KiBRqbceaXxpYx3DvdbiZ3JpAIE")
141            .set_server("http://127.0.0.1:12345");
142        Ok(())
143    }
144}