Skip to content

Commit c283fa9

Browse files
committed
Adding EventSub and Websub support for Channel Ban events
1 parent 89cc2bd commit c283fa9

File tree

7 files changed

+334
-12
lines changed

7 files changed

+334
-12
lines changed

docs/event.md

+5
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,9 @@ Used to either create or send mock events for use with local webhooks testing.
3434
| `streamdown` | Only usable with the `eventsub` transport, a stream offline event. |
3535
| `add-moderator` | Channel moderator add event. |
3636
| `remove-moderator` | Channel moderator removal event. |
37+
| `ban` | Channel ban event. |
38+
| `unban` | Channel unban event. |
39+
3740

3841
**Flags**
3942

@@ -117,6 +120,8 @@ Allows you to test if your webserver responds to subscription requests properly.
117120
| `streamdown` | Only usable with the `eventsub` transport, a stream offline event. |
118121
| `add-moderator` | Channel moderator add event. |
119122
| `remove-moderator` | Channel moderator removal event. |
123+
| `ban` | Channel ban event. |
124+
| `unban` | Channel unban event. |
120125

121126
**Flags**
122127

internal/events/event.go

+15-12
Original file line numberDiff line numberDiff line change
@@ -5,18 +5,21 @@ package events
55
// MockEventParameters are used to craft the event; most of this data is prepopulated by lower services, such as the from/to users to avoid
66
// replicating logic across files
77
type MockEventParameters struct {
8-
ID string
9-
Transport string
10-
Trigger string
11-
FromUserID string
12-
FromUserName string
13-
ToUserID string
14-
ToUserName string
15-
IsAnonymous bool
16-
IsGift bool
17-
Status string
18-
ItemID string
19-
Cost int64
8+
ID string
9+
Transport string
10+
Trigger string
11+
FromUserID string
12+
FromUserName string
13+
ToUserID string
14+
ToUserName string
15+
IsAnonymous bool
16+
IsGift bool
17+
Status string
18+
ItemID string
19+
Cost int64
20+
ModeratorUserID string
21+
ModeratorUserName string
22+
IsPermanent bool
2023
}
2124

2225
type MockEventResponse struct {

internal/events/models.go

+2
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,8 @@ var triggerSupported = map[string]bool{
1616
"remove-reward": true,
1717
"add-moderator": true,
1818
"remove-moderator": true,
19+
"ban": true,
20+
"unban": true,
1921
}
2022

2123
var transportSupported = map[string]bool{

internal/events/types/ban/ban.go

+133
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,133 @@
1+
// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
2+
// SPDX-License-Identifier: Apache-2.0
3+
package ban
4+
5+
import (
6+
"encoding/json"
7+
"time"
8+
9+
"github.com/twitchdev/twitch-cli/internal/events"
10+
"github.com/twitchdev/twitch-cli/internal/models"
11+
"github.com/twitchdev/twitch-cli/internal/util"
12+
)
13+
14+
var transportsSupported = map[string]bool{
15+
models.TransportWebSub: true,
16+
models.TransportEventSub: true,
17+
}
18+
19+
var triggerSupported = []string{"ban"}
20+
21+
var triggerMapping = map[string]map[string]string{
22+
models.TransportWebSub: {
23+
"ban": "moderation.user.ban",
24+
"unban": "moderation.user.ban",
25+
},
26+
models.TransportEventSub: {
27+
"ban": "channel.ban",
28+
"unban": "channel.unban",
29+
},
30+
}
31+
32+
type Event struct{}
33+
34+
func (e Event) GenerateEvent(params events.MockEventParameters) (events.MockEventResponse, error) {
35+
var event []byte
36+
var err error
37+
38+
if params.IsAnonymous == true {
39+
params.FromUserID = ""
40+
params.FromUserName = ""
41+
}
42+
43+
if params.Cost <= 0 {
44+
params.Cost = 100
45+
}
46+
47+
switch params.Transport {
48+
case models.TransportEventSub:
49+
body := *&models.EventsubResponse{
50+
Subscription: models.EventsubSubscription{
51+
ID: params.ID,
52+
Status: "enabled",
53+
Type: triggerMapping[params.Transport][params.Trigger],
54+
Version: "1",
55+
Condition: models.EventsubCondition{
56+
BroadcasterUserID: params.ToUserID,
57+
},
58+
Transport: models.EventsubTransport{
59+
Method: "webhook",
60+
Callback: "null",
61+
},
62+
CreatedAt: util.GetTimestamp().Format(time.RFC3339Nano),
63+
},
64+
Event: models.BanEventSubEvent{
65+
UserID: params.FromUserID,
66+
UserLogin: params.FromUserName,
67+
UserName: params.FromUserName,
68+
BroadcasterUserID: params.ToUserID,
69+
BroadcasterUserLogin: params.ToUserName,
70+
BroadcasterUserName: params.ToUserName,
71+
ModeratorUserId: params.ModeratorUserID,
72+
ModeratorUserLogin: params.ModeratorUserName,
73+
ModeratorUserName: params.ModeratorUserName,
74+
Reason: "This is a test event",
75+
EndsAt: util.GetTimestamp().Format(time.RFC3339Nano),
76+
IsPermanent: params.IsPermanent,
77+
},
78+
}
79+
80+
event, err = json.Marshal(body)
81+
if err != nil {
82+
return events.MockEventResponse{}, err
83+
}
84+
85+
case models.TransportWebSub:
86+
body := *&models.BanWebSubResponse{
87+
Data: []models.BanWebSubResponseData{
88+
{
89+
ID: params.ID,
90+
EventType: triggerMapping[params.Transport][params.Trigger],
91+
EventTimestamp: util.GetTimestamp().Format(time.RFC3339),
92+
Version: "v1",
93+
EventData: models.BanWebSubEventData{
94+
BroadcasterID: params.ToUserID,
95+
BroadcasterName: params.ToUserName,
96+
UserID: params.FromUserID,
97+
UserName: params.FromUserName,
98+
},
99+
},
100+
}}
101+
102+
event, err = json.Marshal(body)
103+
if err != nil {
104+
return events.MockEventResponse{}, err
105+
}
106+
default:
107+
return events.MockEventResponse{}, nil
108+
}
109+
110+
return events.MockEventResponse{
111+
ID: params.ID,
112+
JSON: event,
113+
FromUser: params.FromUserID,
114+
ToUser: params.ToUserID,
115+
}, nil
116+
}
117+
118+
func (e Event) ValidTransport(t string) bool {
119+
return transportsSupported[t]
120+
}
121+
122+
func (e Event) ValidTrigger(t string) bool {
123+
for _, ts := range triggerSupported {
124+
if ts == t {
125+
return true
126+
}
127+
}
128+
return false
129+
}
130+
131+
func (e Event) GetTopic(transport string, trigger string) string {
132+
return triggerMapping[transport][trigger]
133+
}

internal/events/types/ban/ban_test.go

+134
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,134 @@
1+
// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
2+
// SPDX-License-Identifier: Apache-2.0
3+
package ban
4+
5+
import (
6+
"encoding/json"
7+
"testing"
8+
9+
"github.com/twitchdev/twitch-cli/internal/events"
10+
"github.com/twitchdev/twitch-cli/internal/models"
11+
"github.com/twitchdev/twitch-cli/internal/util"
12+
)
13+
14+
var fromUser = "1234"
15+
var toUser = "4567"
16+
17+
func TestEventSubBan(t *testing.T) {
18+
a := util.SetupTestEnv(t)
19+
params := events.MockEventParameters{
20+
FromUserID: fromUser,
21+
ToUserID: toUser,
22+
Transport: models.TransportEventSub,
23+
Trigger: "ban",
24+
}
25+
26+
r, err := Event{}.GenerateEvent(params)
27+
a.Nil(err, "Error generating body.")
28+
29+
var body models.BanEventSubResponse
30+
31+
err = json.Unmarshal(r.JSON, &body)
32+
a.Nil(err, "Error unmarshalling JSON")
33+
34+
a.Equal(toUser, body.Event.BroadcasterUserID, "Expected to user %v, got %v", toUser, body.Event.BroadcasterUserID)
35+
a.Equal(fromUser, body.Event.UserID, "Expected from user %v, got %v", r.ToUser, body.Event.UserID)
36+
37+
// test for unban
38+
params = events.MockEventParameters{
39+
FromUserID: fromUser,
40+
ToUserID: toUser,
41+
Transport: models.TransportEventSub,
42+
Trigger: "unban",
43+
}
44+
45+
r, err = Event{}.GenerateEvent(params)
46+
a.Nil(err)
47+
48+
err = json.Unmarshal(r.JSON, &body)
49+
a.Nil(err)
50+
51+
a.Equal(toUser, body.Event.BroadcasterUserID, "Expected to user %v, got %v", toUser, body.Event.BroadcasterUserID)
52+
a.Equal(fromUser, body.Event.UserID, "Expected from user %v, got %v", fromUser, body.Event.UserID)
53+
}
54+
55+
func TestWebSubBan(t *testing.T) {
56+
a := util.SetupTestEnv(t)
57+
58+
params := *&events.MockEventParameters{
59+
FromUserID: fromUser,
60+
ToUserID: toUser,
61+
Transport: models.TransportWebSub,
62+
Trigger: "ban",
63+
}
64+
65+
r, err := Event{}.GenerateEvent(params)
66+
a.Nil(err)
67+
68+
var body models.BanWebSubResponse
69+
err = json.Unmarshal(r.JSON, &body)
70+
a.Nil(err)
71+
72+
a.Equal(toUser, body.Data[0].EventData.BroadcasterID, "Expected to user %v, got %v", toUser, body.Data[0].EventData.BroadcasterID)
73+
a.Equal(fromUser, body.Data[0].EventData.UserID, "Expected from user %v, got %v", fromUser, body.Data[0].EventData.UserID)
74+
75+
76+
params = *&events.MockEventParameters{
77+
FromUserID: fromUser,
78+
ToUserID: toUser,
79+
Transport: models.TransportWebSub,
80+
Trigger: "unban",
81+
}
82+
83+
r, err = Event{}.GenerateEvent(params)
84+
a.Nil(err)
85+
86+
err = json.Unmarshal(r.JSON, &body)
87+
a.Nil(err)
88+
89+
a.Equal(toUser, body.Data[0].EventData.BroadcasterID, "Expected to user %v, got %v", toUser, body.Data[0].EventData.BroadcasterID)
90+
a.Equal(fromUser, body.Data[0].EventData.UserID, "Expected from user %v, got %v", fromUser, body.Data[0].EventData.UserID)
91+
92+
}
93+
94+
func TestFakeTransport(t *testing.T) {
95+
a := util.SetupTestEnv(t)
96+
97+
params := events.MockEventParameters{
98+
FromUserID: fromUser,
99+
ToUserID: toUser,
100+
Transport: "fake_transport",
101+
Trigger: "unban",
102+
}
103+
104+
r, err := Event{}.GenerateEvent(params)
105+
a.Nil(err)
106+
a.Empty(r)
107+
}
108+
109+
func TestValidTrigger(t *testing.T) {
110+
a := util.SetupTestEnv(t)
111+
112+
r := Event{}.ValidTrigger("ban")
113+
a.Equal(true, r)
114+
115+
r = Event{}.ValidTrigger("unban")
116+
a.Equal(false, r)
117+
}
118+
119+
func TestValidTransport(t *testing.T) {
120+
a := util.SetupTestEnv(t)
121+
122+
r := Event{}.ValidTransport(models.TransportEventSub)
123+
a.Equal(true, r)
124+
125+
r = Event{}.ValidTransport("noteventsub")
126+
a.Equal(false, r)
127+
}
128+
129+
func TestGetTopic(t *testing.T) {
130+
a := util.SetupTestEnv(t)
131+
132+
r := Event{}.GetTopic(models.TransportEventSub, "ban")
133+
a.NotNil(r)
134+
}

internal/events/types/types.go

+2
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ import (
1717
"github.com/twitchdev/twitch-cli/internal/events/types/streamdown"
1818
"github.com/twitchdev/twitch-cli/internal/events/types/streamup"
1919
"github.com/twitchdev/twitch-cli/internal/events/types/subscribe"
20+
"github.com/twitchdev/twitch-cli/internal/events/types/ban"
2021
)
2122

2223
func All() []events.MockEvent {
@@ -32,6 +33,7 @@ func All() []events.MockEvent {
3233
streamup.Event{},
3334
streamdown.Event{},
3435
moderator_change.Event{},
36+
ban.Event{},
3537
}
3638
}
3739

internal/models/ban.go

+43
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
2+
// SPDX-License-Identifier: Apache-2.0
3+
package models
4+
5+
type BanEventSubEvent struct {
6+
UserID string `json:"user_id"`
7+
UserLogin string `json:"user_login"`
8+
UserName string `json:"user_name"`
9+
BroadcasterUserID string `json:"broadcaster_user_id"`
10+
BroadcasterUserLogin string `json:"broadcaster_user_login"`
11+
BroadcasterUserName string `json:"broadcaster_user_name"`
12+
ModeratorUserId string `json:"moderator_user_id"`
13+
ModeratorUserLogin string `json:"moderator_user_login"`
14+
ModeratorUserName string `json:"moderator_user_name"`
15+
Reason string `json:"reason"`
16+
EndsAt string `json:"ends_at"`
17+
IsPermanent bool `json:"is_permanent"`
18+
}
19+
20+
type BanEventSubResponse struct {
21+
Subscription EventsubSubscription `json:"ban"`
22+
Event BanEventSubEvent `json:"event"`
23+
}
24+
25+
26+
type BanWebSubResponse struct {
27+
Data []BanWebSubResponseData `json:"data"`
28+
}
29+
30+
type BanWebSubResponseData struct {
31+
ID string `json:"id"`
32+
EventType string `json:"event_type"`
33+
EventTimestamp string `json:"event_timestamp"`
34+
Version string `json:"version"`
35+
EventData BanWebSubEventData `json:"event_data"`
36+
}
37+
38+
type BanWebSubEventData struct {
39+
BroadcasterID string `json:"broadcaster_id"`
40+
BroadcasterName string `json:"broadcaster_name"`
41+
UserID string `json:"user_id"`
42+
UserName string `json:"user_name"`
43+
}

0 commit comments

Comments
 (0)