Skip to content

Commit 55791b6

Browse files
authored
Merge pull request #36 from aydrian/main
Add event triggers for stream.online and stream.offline
2 parents 00c2451 + 36faa7c commit 55791b6

File tree

8 files changed

+393
-23
lines changed

8 files changed

+393
-23
lines changed

docs/event.md

+27-23
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,23 @@
11
# Events
2+
23
- [Events](#events)
34
- [Description](#description)
45
- [Trigger](#trigger)
56
- [Retrigger](#retrigger)
67
- [Verify-Subscription](#verify-subscription)
78

8-
## Description
9+
## Description
910

10-
The `event` product contains commands to trigger mock events for local webhook testing or migration.
11+
The `event` product contains commands to trigger mock events for local webhook testing or migration.
1112

1213
## Trigger
1314

1415
Used to either create or send mock events for use with local webhooks testing.
1516

16-
1717
**Args**
1818

1919
| Argument | Description |
20-
|---------------------|------------------------------------------------------------------------------------------------------------|
20+
| ------------------- | ---------------------------------------------------------------------------------------------------------- |
2121
| `subscribe` | A standard subscription event. Triggers a basic tier 1 sub. |
2222
| `unsubscribe` | A standard unsubscribe event. Triggers a basic tier 1 sub. |
2323
| `gift` | A gifted subscription event. Triggers a basic tier 1 sub. |
@@ -30,11 +30,13 @@ Used to either create or send mock events for use with local webhooks testing.
3030
| `update-redemption` | Channel Points EventSub event for a redemption being updated. |
3131
| `raid` | Channel Raid event with a random viewer count. |
3232
| `revoke` | User authorization revoke event. Uses local Client as set in `twitch configure` or generates one randomly. |
33+
| `streamup` | Only usable with the `eventsub` transport, a stream online event. |
34+
| `streamdown` | Only usable with the `eventsub` transport, a stream offline event. |
3335

3436
**Flags**
3537

3638
| Flag | Shorthand | Description | Example | Required? (Y/N) |
37-
|---------------------|-----------|----------------------------------------------------------------------------------------------------------------------------|-------------------------------------------|-----------------|
39+
| ------------------- | --------- | -------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------- | --------------- |
3840
| `--forward-address` | `-F` | Web server address for where to send mock events. | `-F https://localhost:8080` | N |
3941
| `--transport` | `-T` | The method used to send events. Default is eventsub, but can send using websub. | `-T websub` | N |
4042
| `--to-user` | `-t` | Denotes the receiver's TUID of the event, usually the broadcaster. | `-t 44635596` | N |
@@ -44,7 +46,7 @@ Used to either create or send mock events for use with local webhooks testing.
4446
| `--count` | `-c` | Count of events to fire. This can be used to simulate an influx of subscriptions. | `-c 100` | N |
4547
| `--anonymous` | `-a` | If the event is anonymous. Only applies to `gift` and `cheer` events. | `-a` | N |
4648
| `--status` | `-S` | Status of the event object, currently applies to channel points redemptions. | `-S fulfilled` | N |
47-
| `--item-id` | `-i` | Manually set the ID of the event payload item (for example the reward ID in redemption events). | `-i 032e4a6c-4aef-11eb-a9f5-1f703d1f0b92` | N |
49+
| `--item-id` | `-i` | Manually set the ID of the event payload item (for example the reward ID in redemption events). | `-i 032e4a6c-4aef-11eb-a9f5-1f703d1f0b92` | N |
4850
| `--cost` | `-C` | Amount of bits or channel points redeemed/used in the event. | `-C 250` | N |
4951

5052
**Examples**
@@ -56,9 +58,9 @@ twitch event trigger cheer -f 1234 -t 4567 // generates JSON for a cheer event f
5658

5759
## Retrigger
5860

59-
Allows previous events to be refired based on the event ID. The ID is noted within the event itself, such as in the "subscription" payload of standard webhooks.
61+
Allows previous events to be refired based on the event ID. The ID is noted within the event itself, such as in the "subscription" payload of standard webhooks.
6062

61-
For example, for:
63+
For example, for:
6264

6365
```json
6466
{
@@ -69,19 +71,19 @@ For example, for:
6971
}
7072
}
7173
```
72-
The resulting ID would be `713f3254-0178-9757-7439-d779400c0999`.
74+
75+
The resulting ID would be `713f3254-0178-9757-7439-d779400c0999`.
7376

7477
**Args**
7578
None
7679

7780
**Flags**
7881

79-
| Flag | Shorthand | Description | Example | Required? (Y/N) |
80-
|---------------------|-----------|----------------------------------------------------------------------------------------------------------------------------|-----------------------------|-----------------|
81-
| `--forward-address` | `-F` | Web server address for where to send mock events. | `-F https://localhost:8080` | N |
82-
| `--id` | `-i` | The ID of the event to refire. | `-i <id>` | Y |
83-
| `--secret` | `-s` | Webhook secret. If defined, signs all forwarded events with the SHA256 HMAC. | `-s testsecret` | N |
84-
82+
| Flag | Shorthand | Description | Example | Required? (Y/N) |
83+
| ------------------- | --------- | ---------------------------------------------------------------------------- | --------------------------- | --------------- |
84+
| `--forward-address` | `-F` | Web server address for where to send mock events. | `-F https://localhost:8080` | N |
85+
| `--id` | `-i` | The ID of the event to refire. | `-i <id>` | Y |
86+
| `--secret` | `-s` | Webhook secret. If defined, signs all forwarded events with the SHA256 HMAC. | `-s testsecret` | N |
8587

8688
**Examples**
8789

@@ -91,12 +93,12 @@ twitch event retrigger -i "713f3254-0178-9757-7439-d779400c0999" -F https://loca
9193

9294
## Verify-Subscription
9395

94-
Allows you to test if your webserver responds to subscription requests properly.
96+
Allows you to test if your webserver responds to subscription requests properly.
9597

9698
**Args**
9799

98100
| Argument | Description |
99-
|---------------------|------------------------------------------------------------------------------------------------------------|
101+
| ------------------- | ---------------------------------------------------------------------------------------------------------- |
100102
| `subscribe` | A standard subscription event. Triggers a basic tier 1 sub. |
101103
| `unsubscribe` | A standard unsubscribe event. Triggers a basic tier 1 sub. |
102104
| `gift` | A gifted subscription event. Triggers a basic tier 1 sub. |
@@ -109,17 +111,19 @@ Allows you to test if your webserver responds to subscription requests properly.
109111
| `update-redemption` | Channel Points EventSub event for a redemption being updated. |
110112
| `raid` | Channel Raid event with a random viewer count. |
111113
| `revoke` | User authorization revoke event. Uses local Client as set in `twitch configure` or generates one randomly. |
114+
| `streamup` | Only usable with the `eventsub` transport, a stream online event. |
115+
| `streamdown` | Only usable with the `eventsub` transport, a stream offline event. |
112116

113117
**Flags**
114118

115-
| Flag | Shorthand | Description | Example | Required? (Y/N) |
116-
|---------------------|-----------|----------------------------------------------------------------------------------------------------------------------------|-----------------------------|-----------------|
117-
| `--forward-address` | `-F` | Web server address for where to send mock subscription. | `-F https://localhost:8080` | Y |
118-
| `--secret` | `-s` | Webhook secret. If defined, signs all forwarded events with the SHA256 HMAC. | `-s testsecret` | N |
119-
| `--transport` | `-T` | The method used to send events. Default is eventsub, but can send using websub. | `-T websub` | N |
119+
| Flag | Shorthand | Description | Example | Required? (Y/N) |
120+
| ------------------- | --------- | ------------------------------------------------------------------------------- | --------------------------- | --------------- |
121+
| `--forward-address` | `-F` | Web server address for where to send mock subscription. | `-F https://localhost:8080` | Y |
122+
| `--secret` | `-s` | Webhook secret. If defined, signs all forwarded events with the SHA256 HMAC. | `-s testsecret` | N |
123+
| `--transport` | `-T` | The method used to send events. Default is eventsub, but can send using websub. | `-T websub` | N |
120124

121125
**Examples**
122126

123127
```sh
124128
twitch event verify-subscription cheer -F https://localhost:8080/ // triggers a fake "cheer" EventSub subscription and validates if localhost responds properly
125-
```
129+
```
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
2+
// SPDX-License-Identifier: Apache-2.0
3+
package streamdown
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: false,
16+
models.TransportEventSub: true,
17+
}
18+
19+
var triggerSupported = []string{"streamdown"}
20+
21+
var triggerMapping = map[string]map[string]string{
22+
models.TransportWebSub: {
23+
"streamdown": "channel.update",
24+
},
25+
models.TransportEventSub: {
26+
"streamdown": "stream.offline",
27+
},
28+
}
29+
30+
type Event struct{}
31+
32+
func (e Event) GenerateEvent(params events.MockEventParameters) (events.MockEventResponse, error) {
33+
var event []byte
34+
var err error
35+
36+
switch params.Transport {
37+
case models.TransportEventSub:
38+
body := &models.EventsubResponse{
39+
Subscription: models.EventsubSubscription{
40+
ID: params.ID,
41+
Status: "enabled",
42+
Type: triggerMapping[params.Transport][params.Trigger],
43+
Version: "1",
44+
Condition: models.EventsubCondition{
45+
BroadcasterUserID: params.ToUserID,
46+
},
47+
Transport: models.EventsubTransport{
48+
Method: "webhook",
49+
Callback: "null",
50+
},
51+
CreatedAt: util.GetTimestamp().Format(time.RFC3339Nano),
52+
},
53+
Event: models.StreamDownEventSubEvent{
54+
BroadcasterUserID: params.ToUserID,
55+
BroadcasterUserLogin: params.ToUserName,
56+
BroadcasterUserName: params.ToUserName,
57+
},
58+
}
59+
event, err = json.Marshal(body)
60+
if err != nil {
61+
return events.MockEventResponse{}, err
62+
}
63+
default:
64+
return events.MockEventResponse{}, nil
65+
}
66+
67+
return events.MockEventResponse{
68+
ID: params.ID,
69+
JSON: event,
70+
FromUser: params.FromUserID,
71+
ToUser: params.ToUserID,
72+
}, nil
73+
}
74+
75+
func (e Event) ValidTransport(t string) bool {
76+
return transportsSupported[t]
77+
}
78+
79+
func (e Event) ValidTrigger(t string) bool {
80+
for _, ts := range triggerSupported {
81+
if ts == t {
82+
return true
83+
}
84+
}
85+
return false
86+
}
87+
func (e Event) GetTopic(transport string, trigger string) string {
88+
return triggerMapping[transport][trigger]
89+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
2+
// SPDX-License-Identifier: Apache-2.0
3+
package streamdown
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 TestEventSub(t *testing.T) {
18+
a := util.SetupTestEnv(t)
19+
20+
params := *&events.MockEventParameters{
21+
FromUserID: fromUser,
22+
ToUserID: toUser,
23+
Transport: models.TransportEventSub,
24+
Trigger: "streamdown",
25+
}
26+
27+
r, err := Event{}.GenerateEvent(params)
28+
a.Nil(err)
29+
30+
var body models.StreamDownEventSubResponse
31+
err = json.Unmarshal(r.JSON, &body)
32+
a.Nil(err)
33+
34+
// write actual tests here (making sure you set appropriate values and the like) for eventsub
35+
}
36+
37+
func TestFakeTransport(t *testing.T) {
38+
a := util.SetupTestEnv(t)
39+
40+
params := *&events.MockEventParameters{
41+
FromUserID: fromUser,
42+
ToUserID: toUser,
43+
Transport: "fake_transport",
44+
Trigger: "unsubscribe",
45+
}
46+
47+
r, err := Event{}.GenerateEvent(params)
48+
a.Nil(err)
49+
a.Empty(r)
50+
}
51+
func TestValidTrigger(t *testing.T) {
52+
a := util.SetupTestEnv(t)
53+
54+
r := Event{}.ValidTrigger("streamdown")
55+
a.Equal(true, r)
56+
57+
r = Event{}.ValidTrigger("notgift")
58+
a.Equal(false, r)
59+
}
60+
61+
func TestValidTransport(t *testing.T) {
62+
a := util.SetupTestEnv(t)
63+
64+
r := Event{}.ValidTransport(models.TransportEventSub)
65+
a.Equal(true, r)
66+
67+
r = Event{}.ValidTransport("noteventsub")
68+
a.Equal(false, r)
69+
}
70+
func TestGetTopic(t *testing.T) {
71+
a := util.SetupTestEnv(t)
72+
73+
r := Event{}.GetTopic(models.TransportEventSub, "streamdown")
74+
a.NotNil(r)
75+
}
+92
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,92 @@
1+
// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
2+
// SPDX-License-Identifier: Apache-2.0
3+
package streamup
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: false,
16+
models.TransportEventSub: true,
17+
}
18+
19+
var triggerSupported = []string{"streamup"}
20+
21+
var triggerMapping = map[string]map[string]string{
22+
models.TransportWebSub: {
23+
"streamup": "channel.update",
24+
},
25+
models.TransportEventSub: {
26+
"streamup": "stream.online",
27+
},
28+
}
29+
30+
type Event struct{}
31+
32+
func (e Event) GenerateEvent(params events.MockEventParameters) (events.MockEventResponse, error) {
33+
var event []byte
34+
var err error
35+
36+
switch params.Transport {
37+
case models.TransportEventSub:
38+
body := &models.EventsubResponse{
39+
Subscription: models.EventsubSubscription{
40+
ID: params.ID,
41+
Status: "enabled",
42+
Type: triggerMapping[params.Transport][params.Trigger],
43+
Version: "1",
44+
Condition: models.EventsubCondition{
45+
BroadcasterUserID: params.ToUserID,
46+
},
47+
Transport: models.EventsubTransport{
48+
Method: "webhook",
49+
Callback: "null",
50+
},
51+
CreatedAt: util.GetTimestamp().Format(time.RFC3339Nano),
52+
},
53+
Event: models.StreamUpEventSubEvent{
54+
ID: util.RandomUserID(),
55+
BroadcasterUserID: params.ToUserID,
56+
BroadcasterUserLogin: params.ToUserName,
57+
BroadcasterUserName: params.ToUserName,
58+
Type: "live",
59+
StartedAt: util.GetTimestamp().Format(time.RFC3339Nano),
60+
},
61+
}
62+
event, err = json.Marshal(body)
63+
if err != nil {
64+
return events.MockEventResponse{}, err
65+
}
66+
default:
67+
return events.MockEventResponse{}, nil
68+
}
69+
70+
return events.MockEventResponse{
71+
ID: params.ID,
72+
JSON: event,
73+
FromUser: params.FromUserID,
74+
ToUser: params.ToUserID,
75+
}, nil
76+
}
77+
78+
func (e Event) ValidTransport(t string) bool {
79+
return transportsSupported[t]
80+
}
81+
82+
func (e Event) ValidTrigger(t string) bool {
83+
for _, ts := range triggerSupported {
84+
if ts == t {
85+
return true
86+
}
87+
}
88+
return false
89+
}
90+
func (e Event) GetTopic(transport string, trigger string) string {
91+
return triggerMapping[transport][trigger]
92+
}

0 commit comments

Comments
 (0)