Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add automod.message.hold v2 event #347

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
95 changes: 48 additions & 47 deletions docs/event.md
Original file line number Diff line number Diff line change
Expand Up @@ -35,53 +35,54 @@ Used to either create or send mock events for use with local webhooks testing.

This command can take either the Event or Alias listed as an argument. It is preferred that you work with the Event, but for backwards compatibility Aliases still work.

| Event | Alias | Description |
|----------------------------------------------------------|-----------------------|-------------|
| `channel.ban` | `ban` | Channel ban event. |
| `channel.channel_points_custom_reward.add` | `add-reward` | Channel Points event for a Custom Reward being added. |
| `channel.channel_points_custom_reward.remove` | `remove-reward` | Channel Points event for a Custom Reward being removed. |
| `channel.channel_points_custom_reward.update` | `update-reward` | Channel Points event for a Custom Reward being updated. |
| `channel.channel_points_custom_reward_redemption.add` | `add-redemption` | Channel Points EventSub event for a redemption being performed. |
| `channel.channel_points_custom_reward_redemption.update` | `add-update` | Channel Points EventSub event for a redemption being performed. |
| `channel.charity_campaign.donate` | `charity-donate` | Charity campaign donation occurance event. |
| `channel.charity_campaign.progress` | `charity-progress` | Charity campaign progress event. |
| `channel.charity_campaign.start` | `charity-start` | Charity campaign start event. |
| `channel.charity_campaign.stop` | `charity-stop` | Charity campaign stop event. |
| `channel.cheer` | `cheer` | Channel event for receiving cheers. |
| `channel.follow` | `follow` | Channel event for receiving a follow. |
| `channel.goal.begin` | `goal-begin` | Channel creator goal start event. |
| `channel.goal.end` | `goal-end` | Channel creator goal end event. |
| `channel.goal.progress` | `goal-progress` | Channel creator goal progress event. |
| `channel.hype_train.begin` | `hype-train-begin` | Channel hype train start event. |
| `channel.hype_train.end` | `hype-train-end` | Channel hype train start event. |
| `channel.hype_train.progress` | `hype-train-progress` | Channel hype train start event. |
| `channel.moderator.add` | `add-moderator` | Channel moderator add event. |
| `channel.moderator.remove` | `remove-moderator` | Channel moderator removal event. |
| `channel.poll.begin` | `poll-begin` | Channel poll begin event. |
| `channel.poll.end` | `poll-end` | Channel poll end event. |
| `channel.poll.progress` | `poll-progress` | Channel poll progress event. |
| `channel.prediction.begin` | `prediction-begin` | Channel prediction begin event. |
| `channel.prediction.end` | `prediction-end` | Channel prediction end event. |
| `channel.prediction.lock` | `prediction-lock` | Channel prediction lock event. |
| `channel.prediction.progress` | `prediction-progress` | Channel prediction progress event. |
| `channel.raid` | `raid` | Channel raid event with a random viewer count. |
| `channel.shield_mode.begin` | `shield-mode-begin` | Channel Shield Mode activate event. |
| `channel.shield_mode.end` | `shield-mode-end` | Channel Shield Mode deactivate event. |
| `channel.shoutout.create` | `shoutout-create` | Channel shoutout created event. This is for outgoing shoutouts, from your channel to another. |
| `channel.shoutout.receive` | `shoutout-received` | Channel shoutout created event. This is for incoming shoutouts, to your channel from anothers. |
| `channel.subscribe` | `subscribe` | A standard subscription event. Triggers a basic tier 1 sub, but can be flexible with --tier |
| `channel.subscribe` | `gift` | A gifted subscription event. Triggers a basic tier 1 sub, but can be flexible with --tier |
| `channel.subscription.end` | `unsubscribe` | A standard subscription end event. Triggers a basic tier 1 sub, but can be flexible with --tier |
| `channel.subscription.gift` | `channel-gift` | Channel gifting event; not to be confused with the `gift` event. This event is a description of the number of gifts given by a user. |
| `channel.subscription.message` | `subscribe-message` | Subscription Message event. |
| `channel.unban` | `unban` | Channel unban event. |
| `channel.update` | `stream-change` | Channel update event. When a broadcaster updates channel properties. |
| `drop.entitlement.grant` | `drop` | Drop Entitlement event. |
| `extension.bits_transaction.create` | `transaction` | Bits in Extensions transactions events. |
| `stream.offline` | `streamdown` | Stream offline event. |
| `stream.online` | `streamup` | Stream online event. |
| `user.authorization.grant` | `grant` | Authorization grant event. |
| `user.authorization.revoke` | `revoke` | User authorization revoke event. Uses local Client as set in `twitch configure` or generates one randomly. |
| Event | Alias | Description |
|----------------------------------------------------------|------------------------|-------------|
| `automod.message.hold` | `automod-message-hold` | Automod caught a message for review. |
| `channel.ban` | `ban` | Channel ban event. |
| `channel.channel_points_custom_reward.add` | `add-reward` | Channel Points event for a Custom Reward being added. |
| `channel.channel_points_custom_reward.remove` | `remove-reward` | Channel Points event for a Custom Reward being removed. |
| `channel.channel_points_custom_reward.update` | `update-reward` | Channel Points event for a Custom Reward being updated. |
| `channel.channel_points_custom_reward_redemption.add` | `add-redemption` | Channel Points EventSub event for a redemption being performed. |
| `channel.channel_points_custom_reward_redemption.update` | `add-update` | Channel Points EventSub event for a redemption being performed. |
| `channel.charity_campaign.donate` | `charity-donate` | Charity campaign donation occurance event. |
| `channel.charity_campaign.progress` | `charity-progress` | Charity campaign progress event. |
| `channel.charity_campaign.start` | `charity-start` | Charity campaign start event. |
| `channel.charity_campaign.stop` | `charity-stop` | Charity campaign stop event. |
| `channel.cheer` | `cheer` | Channel event for receiving cheers. |
| `channel.follow` | `follow` | Channel event for receiving a follow. |
| `channel.goal.begin` | `goal-begin` | Channel creator goal start event. |
| `channel.goal.end` | `goal-end` | Channel creator goal end event. |
| `channel.goal.progress` | `goal-progress` | Channel creator goal progress event. |
| `channel.hype_train.begin` | `hype-train-begin` | Channel hype train start event. |
| `channel.hype_train.end` | `hype-train-end` | Channel hype train start event. |
| `channel.hype_train.progress` | `hype-train-progress` | Channel hype train start event. |
| `channel.moderator.add` | `add-moderator` | Channel moderator add event. |
| `channel.moderator.remove` | `remove-moderator` | Channel moderator removal event. |
| `channel.poll.begin` | `poll-begin` | Channel poll begin event. |
| `channel.poll.end` | `poll-end` | Channel poll end event. |
| `channel.poll.progress` | `poll-progress` | Channel poll progress event. |
| `channel.prediction.begin` | `prediction-begin` | Channel prediction begin event. |
| `channel.prediction.end` | `prediction-end` | Channel prediction end event. |
| `channel.prediction.lock` | `prediction-lock` | Channel prediction lock event. |
| `channel.prediction.progress` | `prediction-progress` | Channel prediction progress event. |
| `channel.raid` | `raid` | Channel raid event with a random viewer count. |
| `channel.shield_mode.begin` | `shield-mode-begin` | Channel Shield Mode activate event. |
| `channel.shield_mode.end` | `shield-mode-end` | Channel Shield Mode deactivate event. |
| `channel.shoutout.create` | `shoutout-create` | Channel shoutout created event. This is for outgoing shoutouts, from your channel to another. |
| `channel.shoutout.receive` | `shoutout-received` | Channel shoutout created event. This is for incoming shoutouts, to your channel from anothers. |
| `channel.subscribe` | `subscribe` | A standard subscription event. Triggers a basic tier 1 sub, but can be flexible with --tier |
| `channel.subscribe` | `gift` | A gifted subscription event. Triggers a basic tier 1 sub, but can be flexible with --tier |
| `channel.subscription.end` | `unsubscribe` | A standard subscription end event. Triggers a basic tier 1 sub, but can be flexible with --tier |
| `channel.subscription.gift` | `channel-gift` | Channel gifting event; not to be confused with the `gift` event. This event is a description of the number of gifts given by a user. |
| `channel.subscription.message` | `subscribe-message` | Subscription Message event. |
| `channel.unban` | `unban` | Channel unban event. |
| `channel.update` | `stream-change` | Channel update event. When a broadcaster updates channel properties. |
| `drop.entitlement.grant` | `drop` | Drop Entitlement event. |
| `extension.bits_transaction.create` | `transaction` | Bits in Extensions transactions events. |
| `stream.offline` | `streamdown` | Stream offline event. |
| `stream.online` | `streamup` | Stream online event. |
| `user.authorization.grant` | `grant` | Authorization grant event. |
| `user.authorization.revoke` | `revoke` | User authorization revoke event. Uses local Client as set in `twitch configure` or generates one randomly. |



Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,164 @@
// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
// SPDX-License-Identifier: Apache-2.0
package automod_message_hold

import (
"encoding/json"
"strings"

"github.com/twitchdev/twitch-cli/internal/events"
"github.com/twitchdev/twitch-cli/internal/models"
"github.com/twitchdev/twitch-cli/internal/util"
)

var transportsSupported = map[string]bool{
models.TransportWebhook: true,
models.TransportWebSocket: true,
}

var triggerSupported = []string{"automod-message-hold"}

var triggerMapping = map[string]map[string]string{
models.TransportWebhook: {
"automod-message-hold": "automod.message.hold",
},
models.TransportWebSocket: {
"automod-message-hold": "automod.message.hold",
},
}

type Event struct{}

func (e Event) GenerateEvent(params events.MockEventParameters) (events.MockEventResponse, error) {
var event []byte
var err error

switch params.Transport {
case models.TransportWebhook, models.TransportWebSocket:
body := &models.EventsubResponse{
Subscription: models.EventsubSubscription{
ID: params.SubscriptionID,
Status: params.SubscriptionStatus,
Type: triggerMapping[params.Transport][params.Trigger],
Version: e.SubscriptionVersion(),
Condition: models.EventsubCondition{
BroadcasterUserID: params.ToUserID,
ModeratorUserID: params.ToUserID,
},
Transport: models.EventsubTransport{
Method: "webhook",
Callback: "null",
},
Cost: 0,
CreatedAt: params.Timestamp,
},
Event: models.AutomodMessageHoldEvent{
UserID: params.FromUserID,
UserLogin: params.FromUserName,
UserName: params.FromUserName,
BroadcasterUserID: params.ToUserID,
BroadcasterUserLogin: params.ToUserName,
BroadcasterUserName: params.ToUserName,
MessageID: util.RandomGUID(),
Message: models.AutomodMessage{
Text: "I am very angry SwiftRage",
Fragments: []models.AutomodMessageFragment{
{
Type: "text",
Text: "I am very angry",
},
{
Type: "emote",
Text: "SwiftRage",
Emote: &models.MessagePartialEmote{
ID: "34",
EmoteSetID: "0",
},
},
},
},
HeldAt: params.Timestamp,
Reason: "blocked_term",
BlockedTerm: &models.AutomodMessageBlockedTermReason{
TermsFound: []models.AutomodMessageFoundTerm{
{
TermID: util.RandomGUID(),
Boundary: models.AutomodMessageBoundary{
StartPos: 10,
EndPos: 14,
},
OwnerBroadcasterUserID: params.ToUserID,
OwnerBroadcasterUserLogin: params.ToUserName,
OwnerBroadcasterUserName: params.ToUserName,
},
},
},
},
}
event, err = json.Marshal(body)
if err != nil {
return events.MockEventResponse{}, err
}

// Delete event info if Subscription.Status is not set to "enabled"
if !strings.EqualFold(params.SubscriptionStatus, "enabled") {
var i any
if err := json.Unmarshal([]byte(event), &i); err != nil {
return events.MockEventResponse{}, err
}
if m, ok := i.(map[string]any); ok {
delete(m, "event") // Matches JSON key defined in body variable above
}

event, err = json.Marshal(i)
if err != nil {
return events.MockEventResponse{}, err
}
}
default:
return events.MockEventResponse{}, nil
}

return events.MockEventResponse{
ID: params.EventMessageID,
JSON: event,
FromUser: params.FromUserID,
ToUser: params.ToUserID,
}, nil
}

func (e Event) ValidTransport(t string) bool {
return transportsSupported[t]
}

func (e Event) ValidTrigger(t string) bool {
for _, ts := range triggerSupported {
if ts == t {
return true
}
}
return false
}
func (e Event) GetTopic(transport string, trigger string) string {
return triggerMapping[transport][trigger]
}
func (e Event) GetAllTopicsByTransport(transport string) []string {
allTopics := []string{}
for _, topic := range triggerMapping[transport] {
allTopics = append(allTopics, topic)
}
return allTopics
}
func (e Event) GetEventSubAlias(t string) string {
// check for aliases
for trigger, topic := range triggerMapping[models.TransportWebhook] {
if topic == t {
return trigger
}
}
return ""
}

func (e Event) SubscriptionVersion() string {
return "2"
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
// SPDX-License-Identifier: Apache-2.0
package automod_message_hold

import (
"encoding/json"
"testing"

"github.com/twitchdev/twitch-cli/internal/events"
"github.com/twitchdev/twitch-cli/internal/models"
"github.com/twitchdev/twitch-cli/test_setup"
)

var fromUser = "1234"
var toUser = "4567"

func TestEventSub(t *testing.T) {
a := test_setup.SetupTestEnv(t)

params := events.MockEventParameters{
FromUserID: fromUser,
ToUserID: toUser,
Transport: models.TransportWebhook,
Trigger: "automod.message.hold",
SubscriptionStatus: "enabled",
}

r, err := Event{}.GenerateEvent(params)
a.Nil(err)

var body models.AutomodMessageHoldEventSubResponse
err = json.Unmarshal(r.JSON, &body)
a.Nil(err)

a.Equal(toUser, body.Event.BroadcasterUserID, "Expected to user %v, got %v", toUser, body.Event.BroadcasterUserID)
a.Equal(fromUser, body.Event.UserID, "Expected from user %v, got %v", r.ToUser, body.Event.UserID)
}
func TestFakeTransport(t *testing.T) {
a := test_setup.SetupTestEnv(t)

params := events.MockEventParameters{
FromUserID: fromUser,
ToUserID: toUser,
Transport: "fake_transport",
Trigger: "automod.message.hold",
}

r, err := Event{}.GenerateEvent(params)
a.Nil(err)
a.Empty(r)
}
func TestValidTrigger(t *testing.T) {
a := test_setup.SetupTestEnv(t)

r := Event{}.ValidTrigger("automod-message-hold")
a.Equal(true, r)

r = Event{}.ValidTrigger("automod")
a.Equal(false, r)
}

func TestValidTransport(t *testing.T) {
a := test_setup.SetupTestEnv(t)

r := Event{}.ValidTransport(models.TransportWebhook)
a.Equal(true, r)

r = Event{}.ValidTransport("noteventsub")
a.Equal(false, r)
}
func TestGetTopic(t *testing.T) {
a := test_setup.SetupTestEnv(t)

r := Event{}.GetTopic(models.TransportWebhook, "automod.message.hold")
a.NotNil(r)
}
2 changes: 2 additions & 0 deletions internal/events/types/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import (
"github.com/twitchdev/twitch-cli/internal/events/types/ad_break"
"github.com/twitchdev/twitch-cli/internal/events/types/authorization_grant"
"github.com/twitchdev/twitch-cli/internal/events/types/authorization_revoke"
"github.com/twitchdev/twitch-cli/internal/events/types/automod_message_hold"
"github.com/twitchdev/twitch-cli/internal/events/types/ban"
"github.com/twitchdev/twitch-cli/internal/events/types/channel_points_redemption"
"github.com/twitchdev/twitch-cli/internal/events/types/channel_points_reward"
Expand Down Expand Up @@ -46,6 +47,7 @@ func AllEvents() []events.MockEvent {
ad_break.Event{},
authorization_grant.Event{},
authorization_revoke.Event{},
automod_message_hold.Event{},
ban.Event{},
channel_points_redemption.Event{},
channel_points_reward.Event{},
Expand Down
Loading