Skip to main content

twitch_api/helix/endpoints/subscriptions/
check_user_subscription.rs

1//! Checks if a specific user is subscribed to a specific channel.
2//! [`check-user-subscription`](https://dev.twitch.tv/docs/api/reference#check-user-subscription)
3//!
4//! # Accessing the endpoint
5//!
6//! ## Request: [CheckUserSubscriptionRequest]
7//!
8//! To use this endpoint, construct a [`CheckUserSubscriptionRequest`] with the [`CheckUserSubscriptionRequest::broadcaster_id()`] method.
9//!
10//! ```rust
11//! use twitch_api::helix::subscriptions::check_user_subscription;
12//! let request =
13//!     check_user_subscription::CheckUserSubscriptionRequest::broadcaster_id(
14//!         "1234",
15//!     );
16//! ```
17//!
18//! ## Response: [UserSubscription]
19//!
20//! Send the request to receive the response with [`HelixClient::req_get()`](helix::HelixClient::req_get).
21//!
22//! ```rust, no_run
23//! use twitch_api::helix::{self, subscriptions::check_user_subscription};
24//! # use twitch_api::client;
25//! # #[tokio::main]
26//! # async fn main() -> Result<(), Box<dyn std::error::Error + Send + Sync + 'static>> {
27//! # let client: helix::HelixClient<'static, client::DummyHttpClient> = helix::HelixClient::default();
28//! # let token = twitch_oauth2::AccessToken::new("validtoken".to_string());
29//! # let token = twitch_oauth2::UserToken::from_existing(&client, token, None, None).await?;
30//! let request = check_user_subscription::CheckUserSubscriptionRequest::broadcaster_id("1234");
31//! let response: check_user_subscription::UserSubscription = client.req_get(request, &token).await?.data;
32//! # Ok(())
33//! # }
34//! ```
35//!
36//! You can also get the [`http::Request`] with [`request.create_request(&token, &client_id)`](helix::RequestGet::create_request)
37//! and parse the [`http::Response`] with [`CheckUserSubscriptionRequest::parse_response(None, &request.get_uri(), response)`](CheckUserSubscriptionRequest::parse_response)
38use super::*;
39use helix::RequestGet;
40
41/// Query Parameters for [Check User Subscription](super::check_user_subscription)
42///
43/// [`check-user-subscription`](https://dev.twitch.tv/docs/api/reference#check-user-subscription)
44#[derive(PartialEq, Eq, Deserialize, Serialize, Clone, Debug)]
45#[cfg_attr(feature = "typed-builder", derive(typed_builder::TypedBuilder))]
46#[must_use]
47#[non_exhaustive]
48pub struct CheckUserSubscriptionRequest<'a> {
49    /// User ID of the broadcaster. Must match the User ID in the Bearer token.
50    #[cfg_attr(feature = "typed-builder", builder(setter(into)))]
51    #[cfg_attr(feature = "deser_borrow", serde(borrow = "'a"))]
52    pub broadcaster_id: Cow<'a, types::UserIdRef>,
53    /// Unique identifier of account to get subscription status of. Accepts up to 100 values.
54    #[cfg_attr(feature = "typed-builder", builder(default))]
55    #[cfg_attr(feature = "deser_borrow", serde(borrow = "'a"))]
56    // FIXME: This is essentially the same as borrow, but worse
57    #[cfg_attr(not(feature = "deser_borrow"), serde(bound(deserialize = "'de: 'a")))]
58    pub user_id: types::Collection<'a, types::UserId>,
59}
60
61impl<'a> CheckUserSubscriptionRequest<'a> {
62    /// Checks subscribed users to this specific channel.
63    pub fn broadcaster_id(broadcaster_id: impl types::IntoCow<'a, types::UserIdRef> + 'a) -> Self {
64        Self {
65            broadcaster_id: broadcaster_id.into_cow(),
66            user_id: types::Collection::default(),
67        }
68    }
69
70    /// Filter the results for specific users.
71    pub fn user_ids(mut self, user_ids: impl Into<types::Collection<'a, types::UserId>>) -> Self {
72        self.user_id = user_ids.into();
73        self
74    }
75}
76
77/// Return Values for [Check User Subscription](super::check_user_subscription)
78///
79/// [`check-user-subscription`](https://dev.twitch.tv/docs/api/reference#check-user-subscription)
80#[derive(PartialEq, Eq, Deserialize, Serialize, Debug, Clone)]
81#[cfg_attr(feature = "deny_unknown_fields", serde(deny_unknown_fields))]
82#[non_exhaustive]
83pub struct UserSubscription {
84    /// User ID of the broadcaster.
85    pub broadcaster_id: types::UserId,
86    /// Login of the broadcaster.
87    pub broadcaster_login: types::UserName,
88    /// Display name of the broadcaster.
89    pub broadcaster_name: types::DisplayName,
90    /// Indicates if the subscription is a gift.
91    pub is_gift: bool,
92    /// Login of the gifter (if is_gift is true).
93    pub gifter_login: Option<types::UserName>,
94    /// Display name of the gifter (if is_gift is true).
95    pub gifter_name: Option<types::DisplayName>,
96    /// Subscription tier. 1000 is tier 1, 2000 is tier 2, and 3000 is tier 3.
97    pub tier: types::SubscriptionTier,
98}
99
100impl Request for CheckUserSubscriptionRequest<'_> {
101    type PaginationData = ();
102    type Response = UserSubscription;
103
104    const PATH: &'static str = "subscriptions/user";
105    #[cfg(feature = "twitch_oauth2")]
106    const SCOPE: twitch_oauth2::Validator =
107        twitch_oauth2::validator![twitch_oauth2::Scope::UserReadSubscriptions];
108}
109
110impl RequestGet for CheckUserSubscriptionRequest<'_> {
111    fn parse_inner_response(
112        _request: Option<Self>,
113        uri: &http::Uri,
114        text: &str,
115        status: http::StatusCode,
116    ) -> Result<helix::Response<Self, Self::Response>, helix::HelixRequestGetError>
117    where
118        Self: Sized,
119    {
120        helix::parse_single_return(_request, uri, text, status)
121    }
122}
123
124#[cfg(test)]
125#[test]
126fn test_request1() {
127    use helix::*;
128    let req = CheckUserSubscriptionRequest::broadcaster_id("123");
129
130    // From twitch docs.
131    let data = br#"
132    {
133        "data": [
134          {
135            "broadcaster_id": "149747285",
136            "broadcaster_name": "TwitchPresents",
137            "broadcaster_login": "twitchpresents",
138            "is_gift": false,
139            "tier": "1000"
140          }
141        ]
142      }
143"#
144    .to_vec();
145
146    let http_response = http::Response::builder().body(data).unwrap();
147
148    let uri = req.get_uri().unwrap();
149    assert_eq!(
150        uri.to_string(),
151        "https://api.twitch.tv/helix/subscriptions/user?broadcaster_id=123"
152    );
153
154    dbg!(CheckUserSubscriptionRequest::parse_response(Some(req), &uri, http_response).unwrap());
155}
156
157#[cfg(test)]
158#[test]
159fn test_request2() {
160    use helix::*;
161    let req = CheckUserSubscriptionRequest::broadcaster_id("123");
162
163    // From twitch docs.
164    let data = br#"
165    {
166        "error": "Not Found",
167        "message": "twitchdev has no subscription to twitchpresents",
168        "status": 404
169      }
170"#
171    .to_vec();
172
173    let http_response = http::Response::builder().status(404).body(data).unwrap();
174
175    let uri = req.get_uri().unwrap();
176    assert_eq!(
177        uri.to_string(),
178        "https://api.twitch.tv/helix/subscriptions/user?broadcaster_id=123"
179    );
180
181    dbg!(CheckUserSubscriptionRequest::parse_response(Some(req), &uri, http_response).unwrap_err());
182}