twitch_api/eventsub/channel/shoutout/
create.rs1#![doc(alias = "channel.shoutout.create")]
2use super::*;
5#[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 ChannelShoutoutCreateV1 {
11 #[cfg_attr(feature = "typed-builder", builder(setter(into)))]
13 pub broadcaster_user_id: types::UserId,
14 #[cfg_attr(feature = "typed-builder", builder(setter(into)))]
16 pub moderator_user_id: types::UserId,
17}
18
19impl ChannelShoutoutCreateV1 {
20 pub fn new(
22 broadcaster_user_id: impl Into<types::UserId>,
23 moderator_user_id: impl Into<types::UserId>,
24 ) -> Self {
25 Self {
26 broadcaster_user_id: broadcaster_user_id.into(),
27 moderator_user_id: moderator_user_id.into(),
28 }
29 }
30}
31
32impl EventSubscription for ChannelShoutoutCreateV1 {
33 type Payload = ChannelShoutoutCreateV1Payload;
34
35 const EVENT_TYPE: EventType = EventType::ChannelShoutoutCreate;
36 #[cfg(feature = "twitch_oauth2")]
37 const SCOPE: twitch_oauth2::Validator = twitch_oauth2::validator![any(
38 twitch_oauth2::Scope::ModeratorReadShoutouts,
39 twitch_oauth2::Scope::ModeratorManageShoutouts
40 )];
41 const VERSION: &'static str = "1";
42}
43
44#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
46#[cfg_attr(feature = "deny_unknown_fields", serde(deny_unknown_fields))]
47#[non_exhaustive]
48pub struct ChannelShoutoutCreateV1Payload {
49 pub broadcaster_user_id: types::UserId,
51 pub broadcaster_user_login: types::UserName,
53 pub broadcaster_user_name: types::DisplayName,
55 pub to_broadcaster_user_id: types::UserId,
57 pub to_broadcaster_user_login: types::UserName,
59 pub to_broadcaster_user_name: types::DisplayName,
61 pub moderator_user_id: types::UserId,
63 pub moderator_user_login: types::UserName,
65 pub moderator_user_name: types::DisplayName,
67 pub viewer_count: i64,
69 pub started_at: types::Timestamp,
71 pub cooldown_ends_at: types::Timestamp,
73 pub target_cooldown_ends_at: types::Timestamp,
75}
76
77#[cfg(test)]
78#[test]
79fn parse_payload() {
80 let payload = r##"
81 {
82 "subscription": {
83 "id": "f1c2a387-161a-49f9-a165-0f21d7a4e1c4",
84 "type": "channel.shoutout.create",
85 "version": "1",
86 "status": "enabled",
87 "cost": 0,
88 "condition": {
89 "broadcaster_user_id": "12345",
90 "moderator_user_id": "98765"
91 },
92 "transport": {
93 "method": "webhook",
94 "callback": "https://example.com/webhooks/callback"
95 },
96 "created_at": "2022-07-25T10:11:12.1236739Z"
97 },
98 "event": {
99 "broadcaster_user_id": "12345",
100 "broadcaster_user_name": "SimplySimple",
101 "broadcaster_user_login": "simplysimple",
102 "moderator_user_id": "98765",
103 "moderator_user_name": "ParticularlyParticular123",
104 "moderator_user_login": "particularlyparticular123",
105 "to_broadcaster_user_id": "626262",
106 "to_broadcaster_user_name": "SandySanderman",
107 "to_broadcaster_user_login": "sandysanderman",
108 "started_at": "2022-07-26T17:00:03.17106713Z",
109 "viewer_count": 860,
110 "cooldown_ends_at": "2022-07-26T17:02:03.17106713Z",
111 "target_cooldown_ends_at":"2022-07-26T18:00:03.17106713Z"
112 }
113 }
114 "##;
115
116 let val = dbg!(crate::eventsub::Event::parse(payload).unwrap());
117 crate::tests::roundtrip(&val)
118}