twitch_api/helix/endpoints/moderation/
get_banned_users.rs

1//! Returns all banned and timed-out users in a channel.
2//! [`get-banned-users`](https://dev.twitch.tv/docs/api/reference#get-banned-users)
3//!
4//! # Accessing the endpoint
5//!
6//! ## Request: [GetBannedUsersRequest]
7//!
8//! To use this endpoint, construct a [`GetBannedUsersRequest`] with the [`GetBannedUsersRequest::broadcaster_id()`] method.
9//!
10//! ```rust
11//! use twitch_api::helix::moderation::get_banned_users;
12//! let request =
13//!     get_banned_users::GetBannedUsersRequest::broadcaster_id("1234");
14//! ```
15//!
16//! ## Response: [BannedUser]
17//!
18//! Send the request to receive the response with [`HelixClient::req_get()`](helix::HelixClient::req_get).
19//!
20//! ```rust, no_run
21//! use twitch_api::helix::{self, moderation::get_banned_users};
22//! # use twitch_api::client;
23//! # #[tokio::main]
24//! # async fn main() -> Result<(), Box<dyn std::error::Error + Send + Sync + 'static>> {
25//! # let client: helix::HelixClient<'static, client::DummyHttpClient> = helix::HelixClient::default();
26//! # let token = twitch_oauth2::AccessToken::new("validtoken".to_string());
27//! # let token = twitch_oauth2::UserToken::from_existing(&client, token, None, None).await?;
28//! let request = get_banned_users::GetBannedUsersRequest::broadcaster_id("1234");
29//! let response: Vec<get_banned_users::BannedUser> = client.req_get(request, &token).await?.data;
30//! # Ok(())
31//! # }
32//! ```
33//!
34//! You can also get the [`http::Request`] with [`request.create_request(&token, &client_id)`](helix::RequestGet::create_request)
35//! and parse the [`http::Response`] with [`GetBannedUsersRequest::parse_response(None, &request.get_uri(), response)`](GetBannedUsersRequest::parse_response)
36
37use super::*;
38use helix::RequestGet;
39
40/// Query Parameters for [Get Banned Users](super::get_banned_users)
41///
42/// [`get-banned-users`](https://dev.twitch.tv/docs/api/reference#get-banned-users)
43#[derive(PartialEq, Eq, Deserialize, Serialize, Clone, Debug)]
44#[cfg_attr(feature = "typed-builder", derive(typed_builder::TypedBuilder))]
45#[must_use]
46#[non_exhaustive]
47pub struct GetBannedUsersRequest<'a> {
48    /// Must match the User ID in the Bearer token.
49    #[cfg_attr(feature = "typed-builder", builder(setter(into)))]
50    #[cfg_attr(feature = "deser_borrow", serde(borrow = "'a"))]
51    pub broadcaster_id: Cow<'a, types::UserIdRef>,
52    /// Filters the results and only returns a status object for users who are banned in this channel and have a matching user_id.
53    /// Format: Repeated Query Parameter, eg. /moderation/banned?broadcaster_id=1&user_id=2&user_id=3
54    /// Maximum: 100
55    #[cfg_attr(feature = "typed-builder", builder(default))]
56    #[cfg_attr(feature = "deser_borrow", serde(borrow = "'a"))]
57    // FIXME: This is essentially the same as borrow, but worse
58    #[cfg_attr(not(feature = "deser_borrow"), serde(bound(deserialize = "'de: 'a")))]
59    pub user_id: types::Collection<'a, types::UserId>,
60    /// Cursor for forward pagination: tells the server where to start fetching the next set of results, in a multi-page response. The cursor value specified here is from the pagination response field of a prior query.
61    #[cfg_attr(feature = "typed-builder", builder(default))]
62    #[cfg_attr(feature = "deser_borrow", serde(borrow = "'a"))]
63    pub after: Option<Cow<'a, helix::CursorRef>>,
64    /// Cursor for backward pagination: tells the server where to start fetching the next set of results, in a multi-page response. The cursor value specified here is from the pagination response field of a prior query.
65    #[cfg_attr(feature = "typed-builder", builder(default))]
66    #[cfg_attr(feature = "deser_borrow", serde(borrow = "'a"))]
67    pub before: Option<Cow<'a, helix::CursorRef>>,
68    /// Number of values to be returned per page. Limit: 100. Default: 20.
69    #[cfg_attr(feature = "typed-builder", builder(setter(into), default))]
70    pub first: Option<usize>,
71}
72
73impl<'a> GetBannedUsersRequest<'a> {
74    /// Get banned users in a broadcasters channel.
75    pub fn broadcaster_id(broadcaster_id: impl types::IntoCow<'a, types::UserIdRef> + 'a) -> Self {
76        Self {
77            broadcaster_id: broadcaster_id.into_cow(),
78            user_id: types::Collection::default(),
79            after: Default::default(),
80            before: Default::default(),
81            first: Default::default(),
82        }
83    }
84
85    /// Check if supplied users are banned.
86    pub fn users(mut self, user_ids: impl Into<types::Collection<'a, types::UserId>>) -> Self {
87        self.user_id = user_ids.into();
88        self
89    }
90
91    /// Set amount of results returned per page.
92    pub const fn first(mut self, first: usize) -> Self {
93        self.first = Some(first);
94        self
95    }
96}
97
98/// Return Values for [Get Banned Users](super::get_banned_users)
99///
100/// [`get-banned-users`](https://dev.twitch.tv/docs/api/reference#get-banned-users)
101#[derive(PartialEq, Eq, Deserialize, Serialize, Debug, Clone)]
102#[cfg_attr(feature = "deny_unknown_fields", serde(deny_unknown_fields))]
103#[non_exhaustive]
104pub struct BannedUser {
105    /// User ID of a user who has been banned.
106    pub user_id: types::UserId,
107    /// Display name of a user who has been banned.
108    pub user_name: types::DisplayName,
109    /// Login of a user who has been banned.
110    pub user_login: types::UserName,
111    #[serde(deserialize_with = "crate::deserialize_none_from_empty_string")]
112    /// RFC3339 formatted timestamp for timeouts; empty string for bans.
113    pub expires_at: Option<types::Timestamp>,
114    /// The reason for the ban if provided by the moderator.
115    #[serde(deserialize_with = "crate::deserialize_none_from_empty_string")]
116    pub reason: Option<String>,
117    /// User ID of the moderator who initiated the ban.
118    pub moderator_id: types::UserId,
119    /// Login of the moderator who initiated the ban.
120    pub moderator_login: types::UserName,
121    /// Display name of the moderator who initiated the ban.
122    pub moderator_name: types::DisplayName,
123}
124
125impl Request for GetBannedUsersRequest<'_> {
126    type Response = Vec<BannedUser>;
127
128    const PATH: &'static str = "moderation/banned";
129    #[cfg(feature = "twitch_oauth2")]
130    const SCOPE: twitch_oauth2::Validator = twitch_oauth2::validator![any(
131        twitch_oauth2::Scope::ModerationRead,
132        twitch_oauth2::Scope::ModeratorManageBannedUsers
133    )];
134}
135
136impl RequestGet for GetBannedUsersRequest<'_> {}
137
138impl helix::Paginated for GetBannedUsersRequest<'_> {
139    fn set_pagination(&mut self, cursor: Option<helix::Cursor>) {
140        self.after = cursor.map(|c| c.into_cow())
141    }
142}
143
144#[cfg(test)]
145#[test]
146fn test_request() {
147    use helix::*;
148    let req = GetBannedUsersRequest::broadcaster_id("198704263");
149
150    // From twitch docs
151    let data = br#"
152{
153  "data": [
154    {
155      "user_id": "423374343",
156      "user_login": "glowillig",
157      "user_name": "glowillig",
158      "expires_at": "2022-03-15T02:00:28Z",
159      "reason": "Does not like pineapple on pizza.",
160      "moderator_id": "141981764",
161      "moderator_login": "twitchdev",
162      "moderator_name": "TwitchDev"
163    },
164    {
165      "user_id": "424596340",
166      "user_login": "quotrok",
167      "user_name": "quotrok",
168      "expires_at": "2022-08-07T02:07:55Z",
169      "reason": "Inappropriate words.",
170      "moderator_id": "141981764",
171      "moderator_login": "twitchdev",
172      "moderator_name": "TwitchDev"
173    },
174    {
175      "user_id": "424596340",
176      "user_login": "quotrok",
177      "user_name": "quotrok",
178      "expires_at": "",
179      "reason": "",
180      "moderator_id": "141981764",
181      "moderator_login": "twitchdev",
182      "moderator_name": "TwitchDev"
183    }
184  ],
185  "pagination": {
186    "cursor": "eyJiIjpudWxsLCJhIjp7IkN1cnNvciI6IjEwMDQ3MzA2NDo4NjQwNjU3MToxSVZCVDFKMnY5M1BTOXh3d1E0dUdXMkJOMFcifX0"
187  }
188}
189"#
190        .to_vec();
191
192    let http_response = http::Response::builder().body(data).unwrap();
193
194    let uri = req.get_uri().unwrap();
195    assert_eq!(
196        uri.to_string(),
197        "https://api.twitch.tv/helix/moderation/banned?broadcaster_id=198704263"
198    );
199
200    dbg!(GetBannedUsersRequest::parse_response(Some(req), &uri, http_response).unwrap());
201}