twitch_api/eventsub/channel/channel_points_custom_reward/
remove.rs

1#![doc(alias = "channel.channel_points_custom_reward.remove")]
2//! A custom channel points reward has been removed from the specified channel.
3
4use super::*;
5/// [`channel.channel_points_custom_reward.remove`](https://dev.twitch.tv/docs/eventsub/eventsub-subscription-types#channelchannel_points_custom_rewardremove): a custom channel points reward has been removed from the specified channel.
6#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
7#[cfg_attr(feature = "typed-builder", derive(typed_builder::TypedBuilder))]
8#[cfg_attr(feature = "deny_unknown_fields", serde(deny_unknown_fields))]
9#[non_exhaustive]
10pub struct ChannelPointsCustomRewardRemoveV1 {
11    /// The broadcaster user ID for the channel you want to receive channel points custom reward remove notifications for.
12    #[cfg_attr(feature = "typed-builder", builder(setter(into)))]
13    pub broadcaster_user_id: types::UserId,
14    /// Optional. Specify a reward id to only receive notifications for a specific reward.
15    #[cfg_attr(feature = "typed-builder", builder(default, setter(into)))]
16    pub reward_id: Option<types::RewardId>,
17}
18
19impl ChannelPointsCustomRewardRemoveV1 {
20    /// The broadcaster user ID for the channel you want to receive channel points custom reward remove notifications for.
21    pub fn broadcaster_user_id(broadcaster_user_id: impl Into<types::UserId>) -> Self {
22        Self {
23            broadcaster_user_id: broadcaster_user_id.into(),
24            reward_id: None,
25        }
26    }
27
28    /// Specify a reward id to only receive notifications for a specific reward.
29    pub fn reward_id(mut self, reward_id: impl Into<types::RewardId>) -> Self {
30        self.reward_id = Some(reward_id.into());
31        self
32    }
33}
34
35impl EventSubscription for ChannelPointsCustomRewardRemoveV1 {
36    type Payload = ChannelPointsCustomRewardRemoveV1Payload;
37
38    const EVENT_TYPE: EventType = EventType::ChannelPointsCustomRewardRemove;
39    #[cfg(feature = "twitch_oauth2")]
40    const SCOPE: twitch_oauth2::Validator = twitch_oauth2::validator![any(
41        twitch_oauth2::Scope::ChannelReadRedemptions,
42        twitch_oauth2::Scope::ChannelManageRedemptions
43    )];
44    const VERSION: &'static str = "1";
45}
46
47/// [`channel.channel_points_custom_reward.remove`](ChannelPointsCustomRewardRemoveV1) response payload.
48#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
49#[cfg_attr(feature = "deny_unknown_fields", serde(deny_unknown_fields))]
50#[non_exhaustive]
51pub struct ChannelPointsCustomRewardRemoveV1Payload {
52    /// Custom background color for the reward. Format: Hex with # prefix. Example: #FA1ED2.
53    pub background_color: String,
54    /// The requested broadcaster ID.
55    pub broadcaster_user_id: types::UserId,
56    /// The requested broadcaster login.
57    pub broadcaster_user_login: types::UserName,
58    /// The requested broadcaster display name.
59    pub broadcaster_user_name: types::DisplayName,
60    /// Timestamp of the cooldown expiration. null if the reward isn’t on cooldown.
61    pub cooldown_expires_at: Option<types::Timestamp>,
62    /// The reward cost.
63    pub cost: i64,
64    /// Set of default images of 1x, 2x and 4x sizes for the reward.
65    pub default_image: Option<types::Image>,
66    /// Whether a cooldown is enabled and what the cooldown is in seconds.
67    pub global_cooldown: types::GlobalCooldown,
68    /// The reward identifier.
69    pub id: types::RewardId,
70    /// Set of custom images of 1x, 2x and 4x sizes for the reward. Can be null if no images have been uploaded.
71    pub image: Option<types::Image>,
72    /// Is the reward currently enabled. If false, the reward won’t show up to viewers.
73    pub is_enabled: bool,
74    /// Is the reward currently in stock. If false, viewers can’t redeem.
75    pub is_in_stock: bool,
76    /// Is the reward currently paused. If true, viewers can’t redeem.
77    pub is_paused: bool,
78    /// Does the viewer need to enter information when redeeming the reward.
79    pub is_user_input_required: bool,
80    /// Whether a maximum per stream is enabled and what the maximum is.
81    pub max_per_stream: types::Max,
82    /// Whether a maximum per user per stream is enabled and what the maximum is.
83    pub max_per_user_per_stream: types::Max,
84    /// The reward description.
85    pub prompt: String,
86    /// The number of redemptions redeemed during the current live stream. Counts against the max_per_stream limit. null if the broadcasters stream isn’t live or max_per_stream isn’t enabled.
87    pub redemptions_redeemed_current_stream: Option<u32>,
88    /// Should redemptions be set to fulfilled status immediately when redeemed and skip the request queue instead of the normal unfulfilled status.
89    pub should_redemptions_skip_request_queue: bool,
90    /// The reward title.
91    pub title: String,
92}
93
94#[cfg(test)]
95#[test]
96fn parse_payload() {
97    // FIXME: Twitch reee. The condition `reward_id` is documented as a string, but in example is int
98    let payload = r##"
99    {
100        "subscription": {
101            "id": "f1c2a387-161a-49f9-a165-0f21d7a4e1c4",
102            "type": "channel.channel_points_custom_reward.remove",
103            "version": "1",
104            "status": "enabled",
105            "cost": 0,
106            "condition": {
107                "broadcaster_user_id": "1337",
108                "reward_id": "12345"
109            },
110             "transport": {
111                "method": "webhook",
112                "callback": "https://example.com/webhooks/callback"
113            },
114            "created_at": "2019-11-16T10:11:12.123Z"
115        },
116        "event": {
117            "id": "9001",
118            "broadcaster_user_id": "1337",
119            "broadcaster_user_login": "cool_user",
120            "broadcaster_user_name": "Cool_User",
121            "is_enabled": true,
122            "is_paused": false,
123            "is_in_stock": true,
124            "title": "Cool Reward",
125            "cost": 100,
126            "prompt": "reward prompt",
127            "is_user_input_required": true,
128            "should_redemptions_skip_request_queue": false,
129            "cooldown_expires_at": "2019-11-16T10:11:12.123Z",
130            "redemptions_redeemed_current_stream": 123,
131            "max_per_stream": {
132                "is_enabled": true,
133                "value": 1000
134            },
135            "max_per_user_per_stream": {
136                "is_enabled": true,
137                "value": 1000
138            },
139            "global_cooldown": {
140                "is_enabled": true,
141                "seconds": 1000
142            },
143            "background_color": "#FA1ED2",
144            "image": {
145                "url_1x": "https://static-cdn.jtvnw.net/image-1.png",
146                "url_2x": "https://static-cdn.jtvnw.net/image-2.png",
147                "url_4x": "https://static-cdn.jtvnw.net/image-4.png"
148            },
149            "default_image": {
150                "url_1x": "https://static-cdn.jtvnw.net/default-1.png",
151                "url_2x": "https://static-cdn.jtvnw.net/default-2.png",
152                "url_4x": "https://static-cdn.jtvnw.net/default-4.png"
153            }
154        }
155    }
156    "##;
157
158    let val = dbg!(crate::eventsub::Event::parse(payload).unwrap());
159    crate::tests::roundtrip(&val)
160}