twitch_api/helix/endpoints/chat/
get_emote_sets.rs

1//! Gets all Twitch emotes for one or more specific emote sets.
2//! [`get-emote-sets`](https://dev.twitch.tv/docs/api/reference#get-emote-sets)
3//!
4//! # Accessing the endpoint
5//!
6//! ## Request: [GetEmoteSetsRequest]
7//!
8//! To use this endpoint, construct a [`GetEmoteSetsRequest`] with the [`GetEmoteSetsRequest::emote_set_ids()`] method.
9//!
10//! ```rust
11//! use twitch_api::helix::chat::get_emote_sets;
12//! let request = get_emote_sets::GetEmoteSetsRequest::emote_set_ids(&"1234");
13//! ```
14//!
15//! ## Response: [Emote]
16//!
17//! Send the request to receive the response with [`HelixClient::req_get()`](helix::HelixClient::req_get).
18//!
19//! ```rust, no_run
20//! use twitch_api::helix::{self, chat::get_emote_sets};
21//! # use twitch_api::{client, types};
22//! # #[tokio::main]
23//! # async fn main() -> Result<(), Box<dyn std::error::Error + Send + Sync + 'static>> {
24//! # let client: helix::HelixClient<'static, client::DummyHttpClient> = helix::HelixClient::default();
25//! # let token = twitch_oauth2::AccessToken::new("validtoken".to_string());
26//! # let token = twitch_oauth2::UserToken::from_existing(&client, token, None, None).await?;
27//! let request = get_emote_sets::GetEmoteSetsRequest::emote_set_ids(&"1234");
28//! let response: Vec<helix::chat::get_emote_sets::Emote> = client.req_get(request, &token).await?.data;
29//! # Ok(())
30//! # }
31//! ```
32//!
33//! You can also get the [`http::Request`] with [`request.create_request(&token, &client_id)`](helix::RequestGet::create_request)
34//! and parse the [`http::Response`] with [`GetEmoteSetsRequest::parse_response(None, &request.get_uri(), response)`](GetEmoteSetsRequest::parse_response)
35
36use super::*;
37use helix::RequestGet;
38
39/// Query Parameters for [Get Channel Emotes](super::get_emote_sets)
40///
41/// [`get-emote-sets`](https://dev.twitch.tv/docs/api/reference#get-emote-sets)
42#[derive(PartialEq, Eq, Deserialize, Serialize, Clone, Debug)]
43#[cfg_attr(feature = "typed-builder", derive(typed_builder::TypedBuilder))]
44#[must_use]
45#[non_exhaustive]
46pub struct GetEmoteSetsRequest<'a> {
47    /// The broadcaster whose emotes are being requested. Minimum: 1. Maximum: 25
48    #[cfg_attr(
49        feature = "typed-builder",
50        builder(default_code = "types::Collection::default()", setter(into))
51    )]
52    #[cfg_attr(feature = "deser_borrow", serde(borrow = "'a"))]
53    // FIXME: This is essentially the same as borrow, but worse
54    #[cfg_attr(not(feature = "deser_borrow"), serde(bound(deserialize = "'de: 'a")))]
55    pub emote_set_id: types::Collection<'a, types::EmoteSetId>,
56}
57
58impl<'a> GetEmoteSetsRequest<'a> {
59    /// Get emotes in these sets
60    pub fn emote_set_ids(
61        emote_set_ids: impl Into<types::Collection<'a, types::EmoteSetId>>,
62    ) -> Self {
63        Self {
64            emote_set_id: emote_set_ids.into(),
65        }
66    }
67}
68
69/// Return Values for [Get Channel Emotes](super::get_emote_sets)
70///
71/// [`get-emote-sets`](https://dev.twitch.tv/docs/api/reference#get-emote-sets)
72#[derive(PartialEq, Eq, Deserialize, Serialize, Debug, Clone)]
73#[cfg_attr(feature = "deny_unknown_fields", serde(deny_unknown_fields))]
74#[non_exhaustive]
75pub struct Emote {
76    /// Emote ID.
77    pub id: types::EmoteId,
78    /// Name of the emote a viewer types into Twitch chat for the image to appear.
79    pub name: String,
80    /// Object of image URLs for the emote.
81    pub images: types::Image,
82    // FIXME: Enumify?
83    /// The type of emote.
84    pub emote_type: String,
85    /// ID of the emote set the emote belongs to.
86    pub emote_set_id: types::EmoteSetId,
87    /// User ID of the broadcaster who owns the emote.
88    pub owner_id: types::UserId,
89    /// The formats that the emote is available in.
90    pub format: Vec<types::EmoteAnimationSetting>,
91    /// The sizes that the emote is available in.
92    pub scale: Vec<types::EmoteScale>,
93    /// The background themes that the emote is available in.
94    pub theme_mode: Vec<types::EmoteThemeMode>,
95}
96
97impl Emote {
98    /// Create an emote builder for this emote.
99    ///
100    /// # Examples
101    ///
102    /// ```rust, no_run
103    /// use twitch_api::helix::{self, chat::get_channel_emotes};
104    /// use futures::TryStreamExt;
105    /// # use twitch_api::{client, types};
106    /// # #[tokio::main]
107    /// # async fn main() -> Result<(), Box<dyn std::error::Error + Send + Sync + 'static>> {
108    /// # let client: helix::HelixClient<'static, client::DummyHttpClient> = helix::HelixClient::default();
109    /// # let token = twitch_oauth2::AccessToken::new("validtoken".to_string());
110    /// # let token = twitch_oauth2::UserToken::from_existing(&client, token, None, None).await?;
111    /// let emotes: Vec<_> = client.get_emote_sets(&["301590448"][..].into(), &token).try_collect().await?;
112    /// assert_eq!(emotes[0].url().size_3x().dark_mode().render(), "https://static-cdn.jtvnw.net/emoticons/v2/emotesv2_dc24652ada1e4c84a5e3ceebae4de709/default/dark/3.0");
113    /// # Ok(())
114    /// # }
115    /// ```
116    pub fn url(&self) -> types::EmoteUrlBuilder<'_> { EmoteUrlBuilder::new(&self.id) }
117}
118
119impl Request for GetEmoteSetsRequest<'_> {
120    type Response = Vec<Emote>;
121
122    const PATH: &'static str = "chat/emotes/set";
123    #[cfg(feature = "twitch_oauth2")]
124    const SCOPE: twitch_oauth2::Validator = twitch_oauth2::validator![];
125}
126
127impl RequestGet for GetEmoteSetsRequest<'_> {}
128
129#[cfg(test)]
130#[test]
131fn test_request() {
132    use helix::*;
133
134    let ids: &[&types::EmoteSetIdRef] = &["301590448".into()];
135    let req = GetEmoteSetsRequest::emote_set_ids(ids);
136
137    // From twitch docs
138    // FIXME: Example has ... and is malformed, uses [] in images
139    let data = br#"
140    {
141      "data": [
142        {
143          "id": "304456832",
144          "name": "twitchdevPitchfork",
145          "images": {
146            "url_1x": "https://static-cdn.jtvnw.net/emoticons/v2/304456832/static/light/1.0",
147            "url_2x": "https://static-cdn.jtvnw.net/emoticons/v2/304456832/static/light/2.0",
148            "url_4x": "https://static-cdn.jtvnw.net/emoticons/v2/304456832/static/light/3.0"
149          },
150          "emote_type": "subscriptions",
151          "emote_set_id": "301590448",
152          "owner_id": "141981764",
153          "format": [
154            "static"
155          ],
156          "scale": [
157            "1.0",
158            "2.0",
159            "3.0"
160          ],
161          "theme_mode": [
162            "light",
163            "dark"
164          ]
165        }
166      ],
167      "template": "https://static-cdn.jtvnw.net/emoticons/v2/{{id}}/{{format}}/{{theme_mode}}/{{scale}}"
168    }
169"#
170    .to_vec();
171
172    let http_response = http::Response::builder().body(data).unwrap();
173
174    let uri = req.get_uri().unwrap();
175    assert_eq!(
176        uri.to_string(),
177        "https://api.twitch.tv/helix/chat/emotes/set?emote_set_id=301590448"
178    );
179
180    dbg!(GetEmoteSetsRequest::parse_response(Some(req), &uri, http_response).unwrap());
181}