mirror of https://git.sr.ht/~ashkeel/strimertul
feat: we can generate our own documentation... wait but why
This commit is contained in:
parent
87c80a81fb
commit
9df69d1b3d
|
@ -7,4 +7,5 @@
|
|||
.idea
|
||||
strimertul_*
|
||||
build/bin
|
||||
*.log
|
||||
*.log
|
||||
api.json
|
|
@ -6,6 +6,7 @@ Small broadcasting suite for Twitch, includes:
|
|||
- Loyalty points system with redeems and community goals
|
||||
- Twitch chat integration with custom commands
|
||||
- Support for Twitch alerts and channel point redeems
|
||||
- Built-in runner for simple extensions to add extra features
|
||||
|
||||
**Note:** some technical/coding experience is currently required to be able to use this effectively, see the technical overview below for more information.
|
||||
|
||||
|
|
6
app.go
6
app.go
|
@ -4,6 +4,8 @@ import (
|
|||
"context"
|
||||
"strconv"
|
||||
|
||||
"github.com/strimertul/strimertul/docs"
|
||||
|
||||
"git.sr.ht/~hamcha/containers/sync"
|
||||
"github.com/nicklaw5/helix/v2"
|
||||
"github.com/urfave/cli/v2"
|
||||
|
@ -137,3 +139,7 @@ func (a *App) GetTwitchLoggedUser() (helix.User, error) {
|
|||
func (a *App) GetLastLogs() []LogEntry {
|
||||
return lastLogs.Get()
|
||||
}
|
||||
|
||||
func (a *App) GetDocumentation() map[string]docs.KeyObject {
|
||||
return docs.Keys
|
||||
}
|
||||
|
|
|
@ -0,0 +1,14 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"os"
|
||||
|
||||
jsoniter "github.com/json-iterator/go"
|
||||
"github.com/strimertul/strimertul/docs"
|
||||
)
|
||||
|
||||
func main() {
|
||||
enc := jsoniter.ConfigFastest.NewEncoder(os.Stdout)
|
||||
enc.SetIndent("", " ")
|
||||
_ = enc.Encode(docs.Keys)
|
||||
}
|
|
@ -0,0 +1,94 @@
|
|||
package docs
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"reflect"
|
||||
"strings"
|
||||
|
||||
"github.com/strimertul/strimertul/docs/interfaces"
|
||||
)
|
||||
|
||||
type DataObject struct {
|
||||
Name string `json:"name"`
|
||||
Description string `json:"description,omitempty"`
|
||||
Kind Kind `json:"kind"`
|
||||
Keys []DataObject `json:"keys,omitempty"`
|
||||
Key *DataObject `json:"key,omitempty"`
|
||||
Element *DataObject `json:"element,omitempty"`
|
||||
EnumValues []string `json:"enumValues,omitempty"`
|
||||
}
|
||||
|
||||
type KeyObject struct {
|
||||
Description string `json:"description"`
|
||||
Schema DataObject `json:"schema"`
|
||||
Tags []interfaces.KeyTag `json:"tags,omitempty"`
|
||||
}
|
||||
|
||||
type Kind string
|
||||
|
||||
const (
|
||||
KindString Kind = "string"
|
||||
KindInt Kind = "int"
|
||||
KindFloat Kind = "float"
|
||||
KindStruct Kind = "object"
|
||||
KindBoolean Kind = "boolean"
|
||||
KindEnum Kind = "enum"
|
||||
KindUnknown Kind = "unknown"
|
||||
KindArray Kind = "array"
|
||||
KindDict Kind = "dictionary"
|
||||
)
|
||||
|
||||
func getKind(typ reflect.Kind) Kind {
|
||||
switch typ {
|
||||
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uintptr:
|
||||
return KindInt
|
||||
case reflect.Float32, reflect.Float64:
|
||||
return KindFloat
|
||||
case reflect.String:
|
||||
return KindString
|
||||
case reflect.Bool:
|
||||
return KindBoolean
|
||||
case reflect.Struct:
|
||||
return KindStruct
|
||||
case reflect.Map:
|
||||
return KindDict
|
||||
case reflect.Array, reflect.Slice:
|
||||
return KindArray
|
||||
}
|
||||
return KindUnknown
|
||||
}
|
||||
|
||||
func parseType(typ reflect.Type) (out DataObject) {
|
||||
out.Name = typ.Name()
|
||||
if enum, ok := Enums[out.Name]; ok {
|
||||
out.Kind = KindEnum
|
||||
for _, it := range enum.Values {
|
||||
out.EnumValues = append(out.EnumValues, fmt.Sprint(it))
|
||||
}
|
||||
return
|
||||
}
|
||||
out.Kind = getKind(typ.Kind())
|
||||
if out.Kind == KindArray || out.Kind == KindDict {
|
||||
elem := parseType(typ.Elem())
|
||||
out.Element = &elem
|
||||
if out.Kind == KindDict {
|
||||
key := parseType(typ.Key())
|
||||
out.Key = &key
|
||||
}
|
||||
}
|
||||
if out.Kind == KindStruct {
|
||||
for index := 0; index < typ.NumField(); index++ {
|
||||
field := typ.Field(index)
|
||||
obj := parseType(field.Type)
|
||||
if jsonName, ok := field.Tag.Lookup("json"); ok {
|
||||
parts := strings.SplitN(jsonName, ",", 2)
|
||||
obj.Name = parts[0]
|
||||
} else {
|
||||
obj.Name = field.Name
|
||||
}
|
||||
obj.Description = field.Tag.Get("desc")
|
||||
out.Keys = append(out.Keys, obj)
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
|
@ -0,0 +1,34 @@
|
|||
package docs
|
||||
|
||||
import (
|
||||
"github.com/strimertul/strimertul/docs/interfaces"
|
||||
"github.com/strimertul/strimertul/http"
|
||||
"github.com/strimertul/strimertul/loyalty"
|
||||
"github.com/strimertul/strimertul/twitch"
|
||||
"github.com/strimertul/strimertul/utils"
|
||||
)
|
||||
|
||||
var (
|
||||
Enums = interfaces.EnumMap{}
|
||||
Keys = map[string]KeyObject{}
|
||||
)
|
||||
|
||||
func addKeys(keyMap interfaces.KeyMap) {
|
||||
for key, obj := range keyMap {
|
||||
Keys[key] = KeyObject{
|
||||
Description: obj.Description,
|
||||
Tags: obj.Tags,
|
||||
Schema: parseType(obj.Type),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func init() {
|
||||
// Put all enums here
|
||||
utils.MergeMap(Enums, twitch.Enums)
|
||||
|
||||
// Put all keys here
|
||||
addKeys(twitch.Keys)
|
||||
addKeys(loyalty.Keys)
|
||||
addKeys(http.Keys)
|
||||
}
|
|
@ -0,0 +1,26 @@
|
|||
package interfaces
|
||||
|
||||
import "reflect"
|
||||
|
||||
type Enum struct {
|
||||
Values []any
|
||||
}
|
||||
|
||||
type KeyDef struct {
|
||||
Description string
|
||||
Type reflect.Type
|
||||
Tags []KeyTag
|
||||
}
|
||||
|
||||
type (
|
||||
EnumMap map[string]Enum // Go type-system is too prehistorical to support what I need here
|
||||
KeyMap map[string]KeyDef
|
||||
)
|
||||
|
||||
type KeyTag string
|
||||
|
||||
const (
|
||||
TagEvent KeyTag = "event"
|
||||
TagRPC KeyTag = "rpc"
|
||||
TagHistory KeyTag = "history"
|
||||
)
|
|
@ -1,88 +0,0 @@
|
|||
# Twitch integration
|
||||
|
||||
## Configuration
|
||||
|
||||
### Enable/disable Twitch integration
|
||||
|
||||
The Twitch integration can be enabled/disabled via `stul-meta/modules`, see [modules.md](./modules.md) for more details.
|
||||
|
||||
### Twitch integration configuration
|
||||
|
||||
The Twitch integration can be configured via `twitch/config` using a JSON object like this:
|
||||
|
||||
```js
|
||||
{
|
||||
"enabled": bool, // Enable Twitch module (required)
|
||||
"enable_bot": bool, // Enable IRC bot
|
||||
"api_client_id": string, // Twitch App Client ID
|
||||
"api_client_secret": string // Twitch App Client Secret
|
||||
}
|
||||
```
|
||||
|
||||
The IRC bot has its own configuration in `twitch/bot-config` as the following JSON object:
|
||||
|
||||
```js
|
||||
{
|
||||
"username": string, // Bot username, probably ignored
|
||||
"oauth": string, // OAuth token
|
||||
"channel": string, // Twitch channel to join
|
||||
"chat_keys": bool, // True to enable chatlog keys
|
||||
"chat_history": int // How many messages to save in twitch/chat-history
|
||||
}
|
||||
```
|
||||
|
||||
If `chat_keys` is enabled, these keys will be updated every time a new message is written in the specified channel:
|
||||
|
||||
- `twitch/ev/chat-message` containing the message that was just written
|
||||
- `twitch/chat-history` containing the updated list of the last N messages (N depends on `chat_history`)
|
||||
|
||||
See [this page](https://github.com/strimertul/strimertul/wiki/Extending-the-bot-with-external-modules) for info on chat message schema.
|
||||
|
||||
## Custom commands
|
||||
|
||||
The bot supports user-defined custom commands for basic things like auto-replies, counters and shoutouts.
|
||||
|
||||
The key `twitch/bot-custom-commands` contains a JSON dictionary of custom commands like the following:
|
||||
|
||||
```js
|
||||
{
|
||||
"!command" : {
|
||||
"description": string, // Command description, for UI only
|
||||
"access_level": string, // Minimum required access level, see below
|
||||
"response": string, // Response
|
||||
"enabled": bool // Must be true for the command to work
|
||||
},
|
||||
...
|
||||
}
|
||||
```
|
||||
|
||||
### Access levels
|
||||
|
||||
The `access_level` property must be a string determining what kind of users can use the command, it can be one of the following:
|
||||
|
||||
| Access level identifier | Minimum access level |
|
||||
| ----------------------- | ------------------------- |
|
||||
| `"streamer"` | Just the broadcaster |
|
||||
| `"moderators"` | Moderators and up |
|
||||
| `"vip"` | VIP and up |
|
||||
| `"subscriber"` | Twitch subscribers and up |
|
||||
| `"everyone"` | Everyone |
|
||||
|
||||
Every level allows people in the upper tiers to use the command as well (eg. a VIP-only command can be used by the broadcaster and moderators).
|
||||
|
||||
### Response templating
|
||||
|
||||
Responses are fully functional golang templates, please refer to [text/template](https://pkg.go.dev/text/template) for a full reference on syntax and functionality.
|
||||
|
||||
The following functions are available:
|
||||
|
||||
- Every function in [sprig](https://masterminds.github.io/sprig/)
|
||||
- [`user .`] retrieves the Twitch username of whoever typed the command
|
||||
- [`param N .`] retrieves the Nth word after the command (ie. "`param 1 .`" on "`!so something awful`" would return "`something`")
|
||||
- [`randomInt MIN MAX`] returns a random integer between MIN and MAX
|
||||
- [`game USERNAME`] returns the current game for Twitch user USERNAME
|
||||
- [`count COUNTER`] increases the counter for key `COUNTER` by 1 and returns it
|
||||
|
||||
## Sending text as the bot
|
||||
|
||||
Writing any string to `twitch/@send-chat-message` will send it as a message in chat from the bot's account
|
|
@ -0,0 +1,15 @@
|
|||
package http
|
||||
|
||||
import (
|
||||
"github.com/strimertul/strimertul/docs/interfaces"
|
||||
"reflect"
|
||||
)
|
||||
|
||||
// Documentation stuff, keep updated at all times
|
||||
|
||||
var Keys = interfaces.KeyMap{
|
||||
ServerConfigKey: interfaces.KeyDef{
|
||||
Description: "General server configuration",
|
||||
Type: reflect.TypeOf(ServerConfig{}),
|
||||
},
|
||||
}
|
|
@ -0,0 +1,47 @@
|
|||
package loyalty
|
||||
|
||||
import (
|
||||
"reflect"
|
||||
|
||||
"github.com/strimertul/strimertul/docs/interfaces"
|
||||
)
|
||||
|
||||
// Documentation stuff, keep updated at all times
|
||||
|
||||
var Keys = interfaces.KeyMap{
|
||||
ConfigKey: interfaces.KeyDef{
|
||||
Description: "General configuration for the loyalty subsystem",
|
||||
Type: reflect.TypeOf(Config{}),
|
||||
},
|
||||
RewardsKey: interfaces.KeyDef{
|
||||
Description: "List of available rewards",
|
||||
Type: reflect.TypeOf([]Reward{}),
|
||||
},
|
||||
GoalsKey: interfaces.KeyDef{
|
||||
Description: "List of all goals",
|
||||
Type: reflect.TypeOf([]Goal{}),
|
||||
},
|
||||
PointsPrefix + "<user>": interfaces.KeyDef{
|
||||
Description: "Point entry for a given user",
|
||||
Type: reflect.TypeOf(PointsEntry{}),
|
||||
},
|
||||
QueueKey: interfaces.KeyDef{
|
||||
Description: "All pending redeems",
|
||||
Type: reflect.TypeOf([]Redeem{}),
|
||||
},
|
||||
RedeemEvent: interfaces.KeyDef{
|
||||
Description: "On reward redeemed",
|
||||
Type: reflect.TypeOf(Redeem{}),
|
||||
Tags: []interfaces.KeyTag{interfaces.TagEvent},
|
||||
},
|
||||
CreateRedeemRPC: interfaces.KeyDef{
|
||||
Description: "Create a new pending redeem",
|
||||
Type: reflect.TypeOf(Redeem{}),
|
||||
Tags: []interfaces.KeyTag{interfaces.TagRPC},
|
||||
},
|
||||
RemoveRedeemRPC: interfaces.KeyDef{
|
||||
Description: "Remove a redeem from the queue",
|
||||
Type: reflect.TypeOf(Redeem{}),
|
||||
Tags: []interfaces.KeyTag{interfaces.TagRPC},
|
||||
},
|
||||
}
|
|
@ -20,17 +20,17 @@ const BotAlertsKey = "twitch/bot-modules/alerts/config"
|
|||
type eventSubNotification struct {
|
||||
Subscription helix.EventSubSubscription `json:"subscription"`
|
||||
Challenge string `json:"challenge"`
|
||||
Event jsoniter.RawMessage `json:"event"`
|
||||
Event jsoniter.RawMessage `json:"event" desc:"Event payload, as JSON object"`
|
||||
}
|
||||
|
||||
type BotAlertsConfig struct {
|
||||
Follow struct {
|
||||
Enabled bool `json:"enabled"`
|
||||
Messages []string `json:"messages"`
|
||||
Enabled bool `json:"enabled" desc:"Enable chat message alert on follow"`
|
||||
Messages []string `json:"messages" desc:"List of message to write on follow, one at random will be picked"`
|
||||
} `json:"follow"`
|
||||
Subscription struct {
|
||||
Enabled bool `json:"enabled"`
|
||||
Messages []string `json:"messages"`
|
||||
Enabled bool `json:"enabled" desc:"Enable chat message alert on subscription"`
|
||||
Messages []string `json:"messages" desc:"List of message to write on subscription, one at random will be picked"`
|
||||
Variations []struct {
|
||||
MinStreak *int `json:"min_streak,omitempty"`
|
||||
IsGifted *bool `json:"is_gifted,omitempty"`
|
||||
|
@ -38,8 +38,8 @@ type BotAlertsConfig struct {
|
|||
} `json:"variations"`
|
||||
} `json:"subscription"`
|
||||
GiftSub struct {
|
||||
Enabled bool `json:"enabled"`
|
||||
Messages []string `json:"messages"`
|
||||
Enabled bool `json:"enabled" desc:"Enable chat message alert on gifted subscription"`
|
||||
Messages []string `json:"messages" desc:"List of message to write on gifted subscription, one at random will be picked"`
|
||||
Variations []struct {
|
||||
MinCumulative *int `json:"min_cumulative,omitempty"`
|
||||
IsAnonymous *bool `json:"is_anonymous,omitempty"`
|
||||
|
@ -47,16 +47,16 @@ type BotAlertsConfig struct {
|
|||
} `json:"variations"`
|
||||
} `json:"gift_sub"`
|
||||
Raid struct {
|
||||
Enabled bool `json:"enabled"`
|
||||
Messages []string `json:"messages"`
|
||||
Enabled bool `json:"enabled" desc:"Enable chat message alert on raid"`
|
||||
Messages []string `json:"messages" desc:"List of message to write on raid, one at random will be picked"`
|
||||
Variations []struct {
|
||||
MinViewers *int `json:"min_viewers,omitempty"`
|
||||
Messages []string `json:"messages"`
|
||||
} `json:"variations"`
|
||||
} `json:"raid"`
|
||||
Cheer struct {
|
||||
Enabled bool `json:"enabled"`
|
||||
Messages []string `json:"messages"`
|
||||
Enabled bool `json:"enabled" desc:"Enable chat message alert on cheer"`
|
||||
Messages []string `json:"messages" desc:"List of message to write on cheer, one at random will be picked"`
|
||||
Variations []struct {
|
||||
MinAmount *int `json:"min_amount,omitempty"`
|
||||
Messages []string `json:"messages"`
|
||||
|
|
|
@ -14,15 +14,24 @@ import (
|
|||
const BotTimersKey = "twitch/bot-modules/timers/config"
|
||||
|
||||
type BotTimersConfig struct {
|
||||
Timers map[string]BotTimer `json:"timers"`
|
||||
Timers map[string]BotTimer `json:"timers" desc:"List of timers as a dictionary"`
|
||||
}
|
||||
|
||||
type BotTimer struct {
|
||||
Enabled bool `json:"enabled"` // Whether the timer is enabled
|
||||
Name string `json:"name"` // Timer name (must be unique)
|
||||
MinimumChatActivity int `json:"minimum_chat_activity"` // Minimum chat messages in the last 5 minutes
|
||||
MinimumDelay int `json:"minimum_delay"` // In seconds
|
||||
Messages []string `json:"messages"` // Messages to write (randomly chosen)
|
||||
// Whether the timer is enabled
|
||||
Enabled bool `json:"enabled" desc:"Enable the timer"`
|
||||
|
||||
// Timer name (must be unique)
|
||||
Name string `json:"name" desc:"Timer name (must be unique)"`
|
||||
|
||||
// Minimum chat messages in the last 5 minutes for timer to trigger
|
||||
MinimumChatActivity int `json:"minimum_chat_activity" desc:"Minimum chat messages in the last 5 minutes for timer to trigger"`
|
||||
|
||||
// Minimum amount of time (in seconds) that needs to pass before it triggers again
|
||||
MinimumDelay int `json:"minimum_delay" desc:"Minimum amount of time (in seconds) that needs to pass before it triggers again"`
|
||||
|
||||
// Messages to write (randomly chosen)
|
||||
Messages []string `json:"messages" desc:"Messages to write (randomly chosen)"`
|
||||
}
|
||||
|
||||
const AverageMessageWindow = 5
|
||||
|
|
|
@ -64,18 +64,21 @@ func (c *Client) connectWebsocket(userClient *helix.Client) {
|
|||
err = json.Unmarshal(wsMessage.Payload, &welcomeData)
|
||||
if err != nil {
|
||||
c.logger.Error("eventsub ws decode error", zap.String("message-type", wsMessage.Metadata.MessageType), zap.Error(err))
|
||||
break
|
||||
}
|
||||
c.logger.Info("eventsub ws connection established", zap.String("session-id", welcomeData.Session.Id))
|
||||
// Add subscription to websocket session
|
||||
err = c.addSubscriptionsForSession(userClient, welcomeData.Session.Id)
|
||||
if err != nil {
|
||||
c.logger.Error("could not add subscriptions", zap.Error(err))
|
||||
break
|
||||
}
|
||||
case "session_reconnect":
|
||||
var reconnectData WelcomeMessagePayload
|
||||
err = json.Unmarshal(wsMessage.Payload, &reconnectData)
|
||||
if err != nil {
|
||||
c.logger.Error("eventsub ws decode error", zap.String("message-type", wsMessage.Metadata.MessageType), zap.Error(err))
|
||||
break
|
||||
}
|
||||
c.logger.Info("eventsub ws connection reset requested", zap.String("session-id", reconnectData.Session.Id), zap.String("reconnect-url", reconnectData.Session.ReconnectUrl))
|
||||
|
||||
|
@ -83,6 +86,7 @@ func (c *Client) connectWebsocket(userClient *helix.Client) {
|
|||
newConnection, _, err := websocket.DefaultDialer.Dial(reconnectData.Session.ReconnectUrl, nil)
|
||||
if err != nil {
|
||||
c.logger.Error("eventsub ws reconnect error", zap.Error(err))
|
||||
break
|
||||
} else {
|
||||
_ = connection.Close()
|
||||
connection = newConnection
|
||||
|
|
|
@ -4,22 +4,38 @@ const CallbackRoute = "/twitch/callback"
|
|||
|
||||
const ConfigKey = "twitch/config"
|
||||
|
||||
// Config is the general configuration for the Twitch subsystem
|
||||
type Config struct {
|
||||
Enabled bool `json:"enabled"`
|
||||
EnableBot bool `json:"enable_bot"`
|
||||
APIClientID string `json:"api_client_id"`
|
||||
APIClientSecret string `json:"api_client_secret"`
|
||||
// Enable subsystem
|
||||
Enabled bool `json:"enabled" desc:"Enable subsystem"`
|
||||
|
||||
// Enable the chatbot
|
||||
EnableBot bool `json:"enable_bot" desc:"Enable the chatbot"`
|
||||
|
||||
// Twitch API App Client ID
|
||||
APIClientID string `json:"api_client_id" desc:"Twitch API App Client ID"`
|
||||
|
||||
// Twitch API App Client Secret
|
||||
APIClientSecret string `json:"api_client_secret" desc:"Twitch API App Client Secret"`
|
||||
}
|
||||
|
||||
const StreamInfoKey = "twitch/stream-info"
|
||||
|
||||
const BotConfigKey = "twitch/bot-config"
|
||||
|
||||
// BotConfig is the general configuration for the Twitch chatbot
|
||||
type BotConfig struct {
|
||||
Username string `json:"username"`
|
||||
Token string `json:"oauth"`
|
||||
Channel string `json:"channel"`
|
||||
ChatHistory int `json:"chat_history"`
|
||||
// Chatbot username (for internal use, ignored by Twitch)
|
||||
Username string `json:"username" desc:"Chatbot username (for internal use, ignored by Twitch)"`
|
||||
|
||||
// OAuth key for IRC authentication
|
||||
Token string `json:"oauth" desc:"OAuth key for IRC authentication"`
|
||||
|
||||
// Twitch channel to join and use
|
||||
Channel string `json:"channel" desc:"Twitch channel to join and use"`
|
||||
|
||||
// How many messages to keep in twitch/chat-history
|
||||
ChatHistory int `json:"chat_history" desc:"How many messages to keep in twitch/chat-history"`
|
||||
}
|
||||
|
||||
const (
|
||||
|
@ -28,11 +44,19 @@ const (
|
|||
ChatActivityKey = "twitch/chat-activity"
|
||||
)
|
||||
|
||||
// BotCustomCommand is a definition of a custom command of the chatbot
|
||||
type BotCustomCommand struct {
|
||||
Description string `json:"description"`
|
||||
AccessLevel AccessLevelType `json:"access_level"`
|
||||
Response string `json:"response"`
|
||||
Enabled bool `json:"enabled"`
|
||||
// Command description
|
||||
Description string `json:"description" desc:"Command description"`
|
||||
|
||||
// Minimum access level needed to use the command
|
||||
AccessLevel AccessLevelType `json:"access_level" desc:"Minimum access level needed to use the command"`
|
||||
|
||||
// Response template (in Go templating format)
|
||||
Response string `json:"response" desc:"Response template (in Go templating format)"`
|
||||
|
||||
// Is the command enabled?
|
||||
Enabled bool `json:"enabled" desc:"Is the command enabled?"`
|
||||
}
|
||||
|
||||
const CustomCommandsKey = "twitch/bot-custom-commands"
|
||||
|
|
|
@ -0,0 +1,83 @@
|
|||
package twitch
|
||||
|
||||
import (
|
||||
"reflect"
|
||||
|
||||
irc "github.com/gempir/go-twitch-irc/v4"
|
||||
"github.com/nicklaw5/helix/v2"
|
||||
"github.com/strimertul/strimertul/docs/interfaces"
|
||||
)
|
||||
|
||||
// Documentation stuff, keep updated at all times
|
||||
|
||||
var Keys = interfaces.KeyMap{
|
||||
ConfigKey: interfaces.KeyDef{
|
||||
Description: "General configuration for the Twitch subsystem",
|
||||
Type: reflect.TypeOf(Config{}),
|
||||
},
|
||||
StreamInfoKey: interfaces.KeyDef{
|
||||
Description: "List of active twitch streams (1 element if live, 0 otherwise)",
|
||||
Type: reflect.TypeOf([]helix.Stream{}),
|
||||
},
|
||||
BotConfigKey: interfaces.KeyDef{
|
||||
Description: "General configuration for the Twitch chatbot",
|
||||
Type: reflect.TypeOf(BotConfig{}),
|
||||
},
|
||||
ChatEventKey: interfaces.KeyDef{
|
||||
Description: "On chat message received",
|
||||
Type: reflect.TypeOf(irc.PrivateMessage{}),
|
||||
Tags: []interfaces.KeyTag{interfaces.TagEvent},
|
||||
},
|
||||
ChatHistoryKey: interfaces.KeyDef{
|
||||
Description: "Last chat messages received",
|
||||
Type: reflect.TypeOf([]irc.PrivateMessage{}),
|
||||
Tags: []interfaces.KeyTag{interfaces.TagHistory},
|
||||
},
|
||||
ChatActivityKey: interfaces.KeyDef{
|
||||
Description: "Number of chat messages in the last minute",
|
||||
Type: reflect.TypeOf(0),
|
||||
},
|
||||
CustomCommandsKey: interfaces.KeyDef{
|
||||
Description: "Chatbot custom commands",
|
||||
Type: reflect.TypeOf(map[string]BotCustomCommand{}),
|
||||
},
|
||||
AuthKey: interfaces.KeyDef{
|
||||
Description: "User access token for the twitch subsystem",
|
||||
Type: reflect.TypeOf(AuthResponse{}),
|
||||
},
|
||||
EventSubEventKey: interfaces.KeyDef{
|
||||
Description: "On Eventsub event received",
|
||||
Type: reflect.TypeOf(NotificationMessagePayload{}),
|
||||
Tags: []interfaces.KeyTag{interfaces.TagEvent},
|
||||
},
|
||||
EventSubHistoryKey: interfaces.KeyDef{
|
||||
Description: "Last eventsub notifications received",
|
||||
Type: reflect.TypeOf([]NotificationMessagePayload{}),
|
||||
Tags: []interfaces.KeyTag{interfaces.TagHistory},
|
||||
},
|
||||
BotAlertsKey: interfaces.KeyDef{
|
||||
Description: "Configuration of chat bot alerts",
|
||||
Type: reflect.TypeOf(BotAlertsConfig{}),
|
||||
},
|
||||
BotTimersKey: interfaces.KeyDef{
|
||||
Description: "Configuration of chat bot timers",
|
||||
Type: reflect.TypeOf(BotTimersConfig{}),
|
||||
},
|
||||
WriteMessageRPC: interfaces.KeyDef{
|
||||
Description: "Send plain text chat message",
|
||||
Type: reflect.TypeOf(""),
|
||||
Tags: []interfaces.KeyTag{interfaces.TagRPC},
|
||||
},
|
||||
}
|
||||
|
||||
var Enums = interfaces.EnumMap{
|
||||
"AccessLevelType": interfaces.Enum{
|
||||
Values: []any{
|
||||
ALTEveryone,
|
||||
ALTSubscribers,
|
||||
ALTVIP,
|
||||
ALTModerators,
|
||||
ALTStreamer,
|
||||
},
|
||||
},
|
||||
}
|
Loading…
Reference in New Issue