diff --git a/internal/events/trigger/trigger_event_test.go b/internal/events/trigger/trigger_event_test.go index d47c3730..5471faf1 100644 --- a/internal/events/trigger/trigger_event_test.go +++ b/internal/events/trigger/trigger_event_test.go @@ -172,7 +172,8 @@ func TestFire(t *testing.T) { Count: 0, } res, err = Fire(params) - a.NotNil(err) + a.Nil(err) + a.NotEmpty(res) params = *&TriggerParameters{ Event: "add-reward", diff --git a/internal/events/types/extension_transaction/transaction_event.go b/internal/events/types/extension_transaction/transaction_event.go index 60a8e0a3..cebb8bc1 100644 --- a/internal/events/types/extension_transaction/transaction_event.go +++ b/internal/events/types/extension_transaction/transaction_event.go @@ -4,9 +4,9 @@ package extension_transaction import ( "encoding/json" - "errors" "time" + "github.com/spf13/viper" "github.com/twitchdev/twitch-cli/internal/events" "github.com/twitchdev/twitch-cli/internal/models" "github.com/twitchdev/twitch-cli/internal/util" @@ -14,7 +14,7 @@ import ( var transportsSupported = map[string]bool{ models.TransportWebSub: true, - models.TransportEventSub: false, + models.TransportEventSub: true, } var triggerSupported = []string{"transaction"} @@ -23,6 +23,9 @@ var triggerMapping = map[string]map[string]string{ models.TransportWebSub: { "transaction": "transaction", }, + models.TransportEventSub: { + "transaction": "extension.bits_transaction.create", + }, } type Event struct{} @@ -31,12 +34,55 @@ func (e Event) GenerateEvent(params events.MockEventParameters) (events.MockEven var event []byte var err error + clientID := viper.GetString("clientId") + + // if not configured, generate a random one + if clientID == "" { + clientID = util.RandomClientID() + } + if params.Cost == 0 { params.Cost = 100 } switch params.Transport { case models.TransportEventSub: - return events.MockEventResponse{}, errors.New("Extension transactions are unsupported on Eventsub") + body := &models.TransactionEventSubResponse{ + Subscription: models.EventsubSubscription{ + ID: params.ID, + Status: "enabled", + Type: triggerMapping[params.Transport][params.Trigger], + Version: "1", + Condition: models.EventsubCondition{ + ExtensionClientID: clientID, + }, + Transport: models.EventsubTransport{ + Method: "webhook", + Callback: "null", + }, + Cost: 1, + CreatedAt: util.GetTimestamp().Format(time.RFC3339Nano), + }, + Event: models.TransactionEventSubEvent{ + ID: params.ID, + ExtensionClientID: clientID, + BroadcasterUserID: params.ToUserID, + BroadcasterUserLogin: "testBroadcaster", + BroadcasterUserName: "testBroadcaster", + UserName: "testUser", + UserLogin: "testUser", + UserID: params.FromUserID, + Product: models.TransactionEventSubProduct{ + Name: "Test Trigger Item from CLI", + Sku: "testItemSku", + Bits: params.Cost, + InDevelopment: true, + }, + }, + } + event, err = json.Marshal(body) + if err != nil { + return events.MockEventResponse{}, err + } case models.TransportWebSub: body := *&models.TransactionWebSubResponse{ Data: []models.TransactionWebsubEvent{ diff --git a/internal/events/types/extension_transaction/transaction_event_test.go b/internal/events/types/extension_transaction/transaction_event_test.go index 9b146f4c..53f911a6 100644 --- a/internal/events/types/extension_transaction/transaction_event_test.go +++ b/internal/events/types/extension_transaction/transaction_event_test.go @@ -6,6 +6,7 @@ import ( "encoding/json" "testing" + "github.com/spf13/viper" "github.com/twitchdev/twitch-cli/internal/events" "github.com/twitchdev/twitch-cli/internal/models" "github.com/twitchdev/twitch-cli/test_setup" @@ -13,6 +14,7 @@ import ( var fromUser = "1234" var toUser = "4567" +var clientId = "7890" func TestWebusbTransaction(t *testing.T) { a := test_setup.SetupTestEnv(t) @@ -46,8 +48,18 @@ func TestEventsubTransaction(t *testing.T) { Trigger: "transaction", } - _, err := Event{}.GenerateEvent(params) - a.NotNil(err) + viper.Set("clientId", clientId) + + r, err := Event{}.GenerateEvent(params) + a.Nil(err) + + var body models.TransactionEventSubResponse + 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", fromUser, body.Event.UserID) + a.Equal(clientId, body.Event.ExtensionClientID, "Expected client id %v, got %v", clientId, body.Event.ExtensionClientID) } func TestFakeTransport(t *testing.T) { diff --git a/internal/models/eventsub.go b/internal/models/eventsub.go index 3f17b77a..7c88d736 100644 --- a/internal/models/eventsub.go +++ b/internal/models/eventsub.go @@ -23,6 +23,7 @@ type EventsubCondition struct { ToBroadcasterUserID string `json:"to_broadcaster_user_id,omitempty"` FromBroadcasterUserID string `json:"from_broadcaster_user_id,omitempty"` ClientID string `json:"client_id,omitempty"` + ExtensionClientID string `json:"extension_client_id,omitempty"` } type EventsubResponse struct { diff --git a/internal/models/transactions.go b/internal/models/transactions.go index f231e842..c7bd47f6 100644 --- a/internal/models/transactions.go +++ b/internal/models/transactions.go @@ -2,6 +2,30 @@ // SPDX-License-Identifier: Apache-2.0 package models +type TransactionEventSubEvent struct { + ID string `json:"id"` + ExtensionClientID string `json:"extension_client_id"` + BroadcasterUserID string `json:"broadcaster_user_id"` + BroadcasterUserLogin string `json:"broadcaster_user_login"` + BroadcasterUserName string `json:"broadcaster_user_name"` + UserName string `json:"user_name"` + UserLogin string `json:"user_login"` + UserID string `json:"user_id"` + Product TransactionEventSubProduct `json:"product"` +} + +type TransactionEventSubProduct struct { + Name string `json:"name"` + Sku string `json:"sku"` + Bits int64 `json:"bits"` + InDevelopment bool `json:"in_development"` +} + +type TransactionEventSubResponse struct { + Subscription EventsubSubscription `json:"subscription"` + Event TransactionEventSubEvent `json:"event"` +} + type TransactionWebsubEvent struct { ID string `json:"id"` Timestamp string `json:"timestamp"`