use base64::Engine;
use base64::engine::general_purpose;
use crate::config::JPushConfig;
use crate::msg::{JPushMessage, JPushMessageResp};
#[cfg(feature = "spring")]
use spring::tracing;
const AUTHORIZATION_HEADER: &str = "Authorization";
#[derive(Debug, Clone)]
pub struct JPushClient {
pub config: JPushConfig,
}
impl JPushClient {
pub fn new(config: JPushConfig) -> Self {
JPushClient {
config
}
}
pub async fn send(&self, message: JPushMessage) -> Result<JPushMessageResp, Box<dyn std::error::Error>> {
let resp = self.request(message).await;
match resp {
Ok(resp) => {
if resp.is_empty() {
#[cfg(feature = "spring")]
tracing::error!("JPush Send Response Empty");
return Err("JPush Send Response Empty".into());
}
let msg_resp = serde_json::from_str::<JPushMessageResp>(&resp);
match msg_resp {
Ok(msg_resp) => Ok(msg_resp),
Err(e) => {
#[cfg(feature = "spring")]
tracing::error!("JPushMessageResp Deserialize Error: {:?}", e);
#[cfg(feature = "spring")]
tracing::error!("JPushMessageResp Deserialize String: {}", resp);
Err(e.into())
}
}
},
Err(e) => {
#[cfg(feature = "spring")]
tracing::error!("JPush Send Error: {:?}", e);
Err(e.into())
}
}
}
fn authorization(&self) -> String {
format!("Basic {}", general_purpose::STANDARD.encode(&format!("{}:{}", self.config.app_key, self.config.secret)))
}
async fn request(&self, msg: JPushMessage) -> Result<String, Box<dyn std::error::Error>> {
let client = reqwest::Client::new();
let res = client.post(&self.config.url)
.header(AUTHORIZATION_HEADER, self.authorization())
.body(msg)
.send()
.await?
.text()
.await?;
Ok(res)
}
}