diff options
| author | ilotterytea <iltsu@alright.party> | 2025-04-02 18:04:09 +0500 |
|---|---|---|
| committer | ilotterytea <iltsu@alright.party> | 2025-04-02 18:04:09 +0500 |
| commit | cf2dd7c5f6293df675d88f1867015ad0730e0cfe (patch) | |
| tree | 32023e3accc666ac846658e66a934444dd092c49 | |
| parent | f8fc21903b0ac7bbdcbfdb95b295b9b98af4b1fa (diff) | |
feat: get betterttv emotes
| -rw-r--r-- | Cargo.lock | 15 | ||||
| -rw-r--r-- | Cargo.toml | 3 | ||||
| -rw-r--r-- | src/betterttv.rs | 73 | ||||
| -rw-r--r-- | src/lib.rs | 30 |
4 files changed, 115 insertions, 6 deletions
@@ -1062,10 +1062,22 @@ dependencies = [ "mio", "pin-project-lite", "socket2", + "tokio-macros", "windows-sys 0.52.0", ] [[package]] +name = "tokio-macros" +version = "2.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6e06d43f1345a3bcd39f6a56dbb7dcab2ba47e68e8ac134855e7e2bdbaf8cab8" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] name = "tokio-native-tls" version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -1155,6 +1167,9 @@ name = "twitch_emotes" version = "0.1.0" dependencies = [ "reqwest", + "serde", + "serde_json", + "tokio", ] [[package]] @@ -7,3 +7,6 @@ edition = "2024" [dependencies] reqwest = { version = "0.12.15", features = ["json"] } +serde = { version = "1.0.219", features = ["derive"] } +serde_json = "1.0.140" +tokio = { version = "1.44.1", default-features = false, features = ["rt", "macros"] } diff --git a/src/betterttv.rs b/src/betterttv.rs new file mode 100644 index 0000000..23ae608 --- /dev/null +++ b/src/betterttv.rs @@ -0,0 +1,73 @@ +use reqwest::{Client, Error}; +use serde::Deserialize; +use serde_json::Value; + +use crate::emotes::RetrieveEmoteAPI; + +#[derive(Debug, Deserialize)] +pub struct BetterTTVEmote { + pub id: String, + pub code: String, + #[serde(rename = "imageType")] + pub image_type: String, + pub animated: bool, +} + +pub struct BetterTTVAPIClient { + client: Client, + base_url: String, +} + +impl BetterTTVAPIClient { + pub fn new() -> Self { + Self { + client: Client::new(), + base_url: "https://api.betterttv.net/3".into(), + } + } +} + +impl RetrieveEmoteAPI<BetterTTVEmote> for BetterTTVAPIClient { + async fn get_channel_emotes(&self, channel_id: &str) -> Result<Vec<BetterTTVEmote>, Error> { + let response = self + .client + .get(format!( + "{}/cached/users/twitch/{}", + self.base_url, channel_id + )) + .send() + .await? + .error_for_status()?; + + let json: Value = response.json().await?; + + let mut emotes = Vec::new(); + + if let Some(shared_emotes) = json.get("sharedEmotes") { + let shared_emotes: Vec<BetterTTVEmote> = + serde_json::from_value(shared_emotes.clone()).unwrap(); + emotes.extend(shared_emotes); + } + + if let Some(channel_emotes) = json.get("channelEmotes") { + let channel_emotes: Vec<BetterTTVEmote> = + serde_json::from_value(channel_emotes.clone()).unwrap(); + emotes.extend(channel_emotes); + } + + Ok(emotes) + } + + async fn get_global_emotes(&self) -> Result<Vec<BetterTTVEmote>, Error> { + let response = self + .client + .get(format!("{}/cached/emotes/global", self.base_url)) + .send() + .await? + .error_for_status()?; + + let json: Value = response.json().await?; + + Ok(serde_json::from_value(json).unwrap()) + } +} @@ -1,14 +1,32 @@ mod emotes; -} +pub mod betterttv; #[cfg(test)] mod tests { - use super::*; + use crate::{betterttv::BetterTTVAPIClient, emotes::RetrieveEmoteAPI}; + + #[tokio::test] + async fn get_betterttv_channel_emotes() { + let bttv = BetterTTVAPIClient::new(); + let emotes = bttv.get_channel_emotes("555579413").await; + + assert_eq!(emotes.is_ok(), true); + + let emotes = emotes.unwrap(); + + assert_eq!(emotes.len(), 1); + } + + #[tokio::test] + async fn get_betterttv_global_emotes() { + let bttv = BetterTTVAPIClient::new(); + let emotes = bttv.get_global_emotes().await; + + assert_eq!(emotes.is_ok(), true); + + let emotes = emotes.unwrap(); - #[test] - fn it_works() { - let result = add(2, 2); - assert_eq!(result, 4); + assert_eq!(emotes.len() >= 1, true); } } |
