1use crate::{error::WiError, types::*};
2use std::sync::Arc;
3
4#[derive(Clone)]
8pub struct Session {
9 pub(crate) id: String,
10 pub(crate) http: Arc<reqwest::Client>,
11 pub(crate) base_url: Arc<String>,
12 pub(crate) api_key: Arc<String>,
13}
14
15impl Session {
16 fn url(&self, path: &str) -> String {
17 format!("{}/sessions/{}{}", self.base_url, self.id, path)
18 }
19
20 async fn post<B: serde::Serialize, R: serde::de::DeserializeOwned>(
21 &self,
22 path: &str,
23 body: &B,
24 ) -> Result<R, WiError> {
25 let res = self
26 .http
27 .post(self.url(path))
28 .header("x-api-key", self.api_key.as_str())
29 .json(body)
30 .send()
31 .await?;
32
33 if !res.status().is_success() {
34 return Err(WiError::from_response(res).await);
35 }
36 Ok(res.json().await?)
37 }
38
39 async fn post_empty(&self, path: &str) -> Result<(), WiError> {
40 let res = self
41 .http
42 .post(self.url(path))
43 .header("x-api-key", self.api_key.as_str())
44 .header("content-length", "0")
45 .send()
46 .await?;
47
48 if !res.status().is_success() {
49 return Err(WiError::from_response(res).await);
50 }
51 Ok(())
52 }
53
54 async fn get<R: serde::de::DeserializeOwned>(&self, path: &str) -> Result<R, WiError> {
55 let res = self
56 .http
57 .get(self.url(path))
58 .header("x-api-key", self.api_key.as_str())
59 .send()
60 .await?;
61
62 if !res.status().is_success() {
63 return Err(WiError::from_response(res).await);
64 }
65 Ok(res.json().await?)
66 }
67
68 pub async fn status(&self) -> Result<SessionStatus, WiError> {
71 self.get("/status").await
72 }
73
74 pub async fn qr(&self) -> Result<QRCode, WiError> {
75 self.get("/qr").await
76 }
77
78 pub async fn connect(&self) -> Result<(), WiError> {
79 self.post_empty("/connect").await
80 }
81
82 pub async fn disconnect(&self) -> Result<(), WiError> {
83 self.post_empty("/disconnect").await
84 }
85
86 pub async fn logout(&self) -> Result<(), WiError> {
87 self.post_empty("/logout").await
88 }
89
90 pub async fn pair_phone(&self, phone: &str) -> Result<PairPhoneResult, WiError> {
91 #[derive(serde::Serialize)]
92 struct Body<'a> { phone: &'a str }
93 self.post("/pairphone", &Body { phone }).await
94 }
95
96 pub async fn send_text(&self, p: SendTextParams) -> Result<MessageResponse, WiError> {
99 self.post("/messages/send-text", &p).await
100 }
101
102 pub async fn send_image(&self, p: SendImageParams) -> Result<MessageResponse, WiError> {
103 self.post("/messages/send-image", &p).await
104 }
105
106 pub async fn send_audio(&self, p: SendAudioParams) -> Result<MessageResponse, WiError> {
107 self.post("/messages/send-audio", &p).await
108 }
109
110 pub async fn send_video(&self, p: SendVideoParams) -> Result<MessageResponse, WiError> {
111 self.post("/messages/send-video", &p).await
112 }
113
114 pub async fn send_document(&self, p: SendDocumentParams) -> Result<MessageResponse, WiError> {
115 self.post("/messages/send-document", &p).await
116 }
117
118 pub async fn send_location(&self, p: SendLocationParams) -> Result<MessageResponse, WiError> {
119 self.post("/messages/send-location", &p).await
120 }
121
122 pub async fn send_contact(&self, p: SendContactParams) -> Result<MessageResponse, WiError> {
123 self.post("/messages/send-contact", &p).await
124 }
125
126 pub async fn send_sticker(&self, p: SendStickerParams) -> Result<MessageResponse, WiError> {
127 self.post("/messages/send-sticker", &p).await
128 }
129
130 pub async fn send_poll(&self, p: SendPollParams) -> Result<MessageResponse, WiError> {
131 self.post("/messages/send-poll", &p).await
132 }
133
134 pub async fn react(&self, p: SendReactionParams) -> Result<(), WiError> {
135 self.post::<_, serde_json::Value>("/chat/react", &p).await?;
136 Ok(())
137 }
138
139 pub async fn mark_read(&self, p: MarkReadParams) -> Result<(), WiError> {
142 self.post::<_, serde_json::Value>("/chat/markread", &p).await?;
143 Ok(())
144 }
145
146 pub async fn presence(&self, p: PresenceParams) -> Result<(), WiError> {
147 self.post::<_, serde_json::Value>("/chat/presence", &p).await?;
148 Ok(())
149 }
150}