volt/
bot.rs

1use crate::core::structs::bot_structs::{Bot, Bots, PublicBot};
2use crate::core::Cache;
3use crate::core::TokenBucket;
4
5use reqwest::{Client as ReqwestClient};
6use reqwest::header::{HeaderMap, HeaderValue};
7use serde::{Serialize, Deserialize};
8use tokio::time;
9
10use std::time::Duration;
11use std::sync::{Arc, Mutex};
12
13#[derive(Debug, Clone)]
14pub struct BotClient{
15    auth: String,
16    cache: Cache,
17    url: String,
18    bucket: Arc<Mutex<TokenBucket>>,
19    bot: String,
20    json: String,
21    data: Data,
22}
23
24#[derive(Debug, Serialize, Deserialize, Clone, PartialEq)]
25pub(crate) enum Data {
26    Bot(),
27    PublicBots(),
28    Bots(),
29    String(),
30}
31
32#[derive(Debug, Serialize, Deserialize, Clone, PartialEq)]
33pub enum BotResult {
34    Bot(Bot),
35    PublicBot(PublicBot),
36    Bots(Bots),
37    String(String),
38}
39
40impl BotClient {
41    
42    pub fn new(auth: String) -> BotClient {
43        BotClient {
44            auth,
45            cache: Cache::new(),
46            url: String::new(),
47            bucket: Arc::new(Mutex::new(TokenBucket::new(10))),
48            bot: String::new(),
49            json: String::new(),
50            data: Data::Bot(),
51        }
52    }
53
54    /// Post
55    pub fn create_bot(&mut self, name: &str) -> &mut Self {
56        self.url = "https://api.revolt.chat/bots/create".to_string();
57        self.json = format!("{{\"name\":\"{}\"}}", name);
58        self
59    }
60
61    /// Get for other peoples bots
62    pub fn fetch_public_bot(&mut self, target: &str) -> &mut Self {
63        self.data = Data::PublicBots();
64        self.url = format!("https://api.revolt.chat/bots/{}/invite", target);
65        self.bot = target.to_string();
66        self
67    }
68
69    /// Post
70    /// 
71    /// bot, then server/group id
72    pub fn invite_bot(&mut self, target: &str, server: &str) -> &mut Self {
73        self.url = format!("https://api.revolt.chat/bots/{}/invite", target);
74        self.json = format!("{{\"group\":\"{}\"}}", server);
75        self
76    }
77
78    /// Get
79    /// 
80    /// ONLY YOUR BOTS
81    pub fn fetch_owned_bot(&mut self, target: &str) -> &mut Self {
82        self.data = Data::Bot();
83        self.url = format!("https://api.revolt.chat/bots/{}", target);
84        self.bot = target.to_string();
85        self
86    }
87
88    /// Get
89    pub fn fetch_owned_bots(&mut self) -> &mut Self {
90        self.data = Data::Bots();
91        self.url = "https://api.revolt.chat/bots/@me".to_string();
92        self
93    }
94
95    /// Del
96    pub fn delete_bot(&mut self, target: &str) -> &mut Self {
97        self.url = format!("https://api.revolt.chat/bots/{}", target);
98        self
99    }
100
101    /// patch
102    #[cfg(feature="experimental")]
103    pub fn edit_bot(&mut self, target: &str, changes: &str) -> &mut Self {
104        self.url = format!("https://api.revolt.chat/bots/{}", target);
105        self.json = changes.to_string();
106        self
107    }
108
109    #[tokio::main]
110    pub async fn get(&mut self) -> BotResult {
111        
112        if self.cache.get(&self.bot).is_some() {
113            let text = self.cache.get(&self.bot).unwrap();
114            match text.1.to_lowercase().as_str(){
115                "bot" => {
116                    if self.data == Data::Bot() {
117                        let parsed_value: Bot = serde_json::from_str(&text.0).unwrap();
118                        return BotResult::Bot(parsed_value);
119                    }
120                },
121                "publicbot" => {
122                    if self.data == Data::PublicBots() {
123                        let parsed_value: PublicBot = serde_json::from_str(&text.0)
124                        .expect(&format!("The bot you are searching for {} is not listed as public or the id is inccorect!", self.bot));
125                        return BotResult::PublicBot(parsed_value);
126                    }
127                },
128                _ => {
129                    panic!("Error retriving item from cache")
130                }
131            }
132
133        }
134
135        let bucket = self.bucket.clone();
136        let mut bucket = bucket.lock().unwrap();
137
138        let mut header: HeaderMap = HeaderMap::new();
139        header.insert("x-session-token", HeaderValue::from_str(&self.auth).unwrap()); 
140
141        while !bucket.try_acquire() {
142            time::sleep(Duration::from_millis(100)).await;
143        }
144
145        let client = ReqwestClient::new().get(&self.url).headers(header).send().await.unwrap();
146
147        // Might be a problem in the future
148        let body = client.text().await.unwrap();
149
150        return self.return_data(body)
151    }
152
153    fn return_data(&mut self, body: String) -> BotResult{
154        match self.data{
155            Data::Bot() => {
156                let value: Bot = serde_json::from_str(&body).unwrap();
157                self.cache.add(self.bot.clone(), (body, "Bot".to_string()));
158                return BotResult::Bot(value);
159            },
160            Data::PublicBots() => {
161                let value: PublicBot = serde_json::from_str(&body)
162                .expect(&format!("The bot you are searching for {} is not listed as public or the id is inccorect!", self.bot));
163                self.cache.add(self.bot.clone(), (body, "PublicBot".to_string()));
164                return BotResult::PublicBot(value);
165            },
166            Data::Bots() => {
167                let value: Bots = serde_json::from_str(&body).unwrap();
168                return BotResult::Bots(value);
169            }
170            _ => return BotResult::String(body)
171        }
172    }
173}