|
| 1 | +package events |
| 2 | + |
| 3 | +import ( |
| 4 | + "fmt" |
| 5 | + "net/url" |
| 6 | + |
| 7 | + "github.com/spf13/cobra" |
| 8 | + "github.com/twitchdev/twitch-cli/internal/events" |
| 9 | + configure_event "github.com/twitchdev/twitch-cli/internal/events/configure" |
| 10 | + "github.com/twitchdev/twitch-cli/internal/events/trigger" |
| 11 | + "github.com/twitchdev/twitch-cli/internal/events/types" |
| 12 | +) |
| 13 | + |
| 14 | +func TriggerCommand() (command *cobra.Command) { |
| 15 | + command = &cobra.Command{ |
| 16 | + Use: "trigger [event]", |
| 17 | + Short: "Creates mock events that can be forwarded to a local webserver for event testing.", |
| 18 | + Long: fmt.Sprintf(`Creates mock events that can be forwarded to a local webserver for event testing. |
| 19 | + Supported: |
| 20 | + %s`, types.AllWebhookTopics()), |
| 21 | + Args: cobra.MaximumNArgs(1), |
| 22 | + ValidArgs: types.AllWebhookTopics(), |
| 23 | + RunE: triggerCmdRun, |
| 24 | + Example: `twitch event trigger subscribe`, |
| 25 | + Aliases: []string{ |
| 26 | + "fire", "emit", |
| 27 | + }, |
| 28 | + } |
| 29 | + |
| 30 | + // flags for forwarding functionality/changing payloads |
| 31 | + command.Flags().StringVarP(&forwardAddress, "forward-address", "F", "", "Forward address for mock event (webhook only).") |
| 32 | + command.Flags().StringVarP(&transport, "transport", "T", "webhook", fmt.Sprintf("Preferred transport method for event. Defaults to /EventSub.\nSupported values: %s", events.ValidTransports())) |
| 33 | + command.Flags().StringVarP(&secret, "secret", "s", "", "Webhook secret. If defined, signs all forwarded events with the SHA256 HMAC and must be 10-100 characters in length.") |
| 34 | + command.Flags().BoolVarP(&noConfig, "no-config", "D", false, "Disables the use of the configuration, if it exists.") |
| 35 | + |
| 36 | + // per-topic flags |
| 37 | + command.Flags().StringVarP(&toUser, "to-user", "t", "", "User ID of the receiver of the event. For example, the user that receives a follow. In most contexts, this is the broadcaster.") |
| 38 | + command.Flags().StringVarP(&fromUser, "from-user", "f", "", "User ID of the user sending the event, for example the user following another user.") |
| 39 | + command.Flags().StringVarP(&giftUser, "gift-user", "g", "", "Used only for \"gift\" events. Denotes the User ID of the gifting user.") |
| 40 | + command.Flags().BoolVarP(&isAnonymous, "anonymous", "a", false, "Denotes if the event is anonymous. Only applies to Gift and Sub events.") |
| 41 | + command.Flags().IntVarP(&count, "count", "c", 1, "Number of times to run an event. This can be used to simulate rapid events, such as multiple sub gift, or large number of cheers.") |
| 42 | + command.Flags().StringVarP(&eventStatus, "event-status", "S", "", "Status of the Event object (.event.status in JSON); currently applies to channel points redemptions.") |
| 43 | + command.Flags().StringVarP(&subscriptionStatus, "subscription-status", "r", "enabled", "Status of the Subscription object (.subscription.status in JSON). Defaults to \"enabled\".") |
| 44 | + command.Flags().StringVarP(&itemID, "item-id", "i", "", "Manually set the ID of the event payload item (for example the reward ID in redemption events). For stream events, this is the game ID.") |
| 45 | + command.Flags().StringVarP(&itemName, "item-name", "n", "", "Manually set the name of the event payload item (for example the reward ID in redemption events). For stream events, this is the game title.") |
| 46 | + command.Flags().Int64VarP(&cost, "cost", "C", 0, "Amount of drops, subscriptions, bits, or channel points redeemed/used in the event.") |
| 47 | + command.Flags().StringVarP(&description, "description", "d", "", "Title the stream should be updated with.") |
| 48 | + command.Flags().StringVarP(&gameID, "game-id", "G", "", "Sets the game/category ID for applicable events.") |
| 49 | + command.Flags().StringVarP(&tier, "tier", "", "", "Sets the subscription tier. Valid values are 1000, 2000, and 3000.") |
| 50 | + command.Flags().StringVarP(&eventID, "subscription-id", "u", "", "Manually set the subscription/event ID of the event itself.") // TODO: This description will need to change with https://github.com/twitchdev/twitch-cli/issues/184 |
| 51 | + command.Flags().StringVar(×tamp, "timestamp", "", "Sets the timestamp to be used in payloads and headers. Must be in RFC3339Nano format.") |
| 52 | + command.Flags().IntVar(&charityCurrentValue, "charity-current-value", 0, "Only used for \"charity-*\" events. Manually set the current dollar value for charity events.") |
| 53 | + command.Flags().IntVar(&charityTargetValue, "charity-target-value", 1500000, "Only used for \"charity-*\" events. Manually set the target dollar value for charity events.") |
| 54 | + command.Flags().StringVar(&clientId, "client-id", "", "Manually set the Client ID used in revoke, grant, and bits transaction events.") |
| 55 | + command.Flags().StringVarP(&version, "version", "v", "", "Chooses the EventSub version used for a specific event. Not required for most events.") |
| 56 | + command.Flags().StringVar(&websocketClient, "session", "", "Defines a specific websocket client/session to forward an event to. Used only with \"websocket\" transport.") |
| 57 | + command.Flags().StringVar(&banStart, "ban-start", "", "Sets the timestamp a ban started at.") |
| 58 | + command.Flags().StringVar(&banEnd, "ban-end", "", "Sets the timestamp a ban is intended to end at. If not set, the ban event will appear as permanent. This flag can take a timestamp or relative time (600, 600s, 10d4h12m55s)") |
| 59 | + |
| 60 | + return |
| 61 | +} |
| 62 | + |
| 63 | +func triggerCmdRun(cmd *cobra.Command, args []string) error { |
| 64 | + if len(args) == 0 { |
| 65 | + cmd.Help() |
| 66 | + return fmt.Errorf("") |
| 67 | + } |
| 68 | + |
| 69 | + if transport == "websub" { |
| 70 | + return fmt.Errorf(websubDeprecationNotice) |
| 71 | + } |
| 72 | + |
| 73 | + defaults := configure_event.GetEventConfiguration(noConfig) |
| 74 | + |
| 75 | + if secret != "" { |
| 76 | + if len(secret) < 10 || len(secret) > 100 { |
| 77 | + return fmt.Errorf("Invalid secret provided. Secrets must be between 10-100 characters") |
| 78 | + } |
| 79 | + } else { |
| 80 | + secret = defaults.Secret |
| 81 | + } |
| 82 | + |
| 83 | + // Validate that the forward address is actually a URL |
| 84 | + if len(forwardAddress) > 0 { |
| 85 | + _, err := url.ParseRequestURI(forwardAddress) |
| 86 | + if err != nil { |
| 87 | + return err |
| 88 | + } |
| 89 | + } else { |
| 90 | + forwardAddress = defaults.ForwardAddress |
| 91 | + } |
| 92 | + |
| 93 | + for i := 0; i < count; i++ { |
| 94 | + res, err := trigger.Fire(trigger.TriggerParameters{ |
| 95 | + Event: args[0], |
| 96 | + EventID: eventID, |
| 97 | + Transport: transport, |
| 98 | + ForwardAddress: forwardAddress, |
| 99 | + FromUser: fromUser, |
| 100 | + ToUser: toUser, |
| 101 | + GiftUser: giftUser, |
| 102 | + Secret: secret, |
| 103 | + IsAnonymous: isAnonymous, |
| 104 | + EventStatus: eventStatus, |
| 105 | + ItemID: itemID, |
| 106 | + Cost: cost, |
| 107 | + Description: description, |
| 108 | + ItemName: itemName, |
| 109 | + GameID: gameID, |
| 110 | + Tier: tier, |
| 111 | + SubscriptionStatus: subscriptionStatus, |
| 112 | + Timestamp: timestamp, |
| 113 | + CharityCurrentValue: charityCurrentValue, |
| 114 | + CharityTargetValue: charityTargetValue, |
| 115 | + ClientID: clientId, |
| 116 | + Version: version, |
| 117 | + WebSocketClient: websocketClient, |
| 118 | + BanStartTimestamp: banStart, |
| 119 | + BanEndTimestamp: banEnd, |
| 120 | + }) |
| 121 | + |
| 122 | + if err != nil { |
| 123 | + return err |
| 124 | + } |
| 125 | + |
| 126 | + fmt.Println(res) |
| 127 | + } |
| 128 | + |
| 129 | + return nil |
| 130 | +} |
0 commit comments