Commands & Handler in place

set the basic handler framework for commands & chat
This commit is contained in:
bryce
2025-07-06 21:59:47 +12:00
parent 645f7570f0
commit fc9a649574
2 changed files with 210 additions and 0 deletions

View File

@@ -0,0 +1,70 @@
package chat
import (
"fmt"
"strings"
twitch "github.com/gempir/go-twitch-irc/v4"
"streambot/internal/commands"
)
const (
MatchPrefix = "prefix"
MatchMention = "mention"
MatchContains = "contains"
)
func messageMatchesCommand(message, botUserName string, cmd commands.CustomCommand) bool {
msgLower := strings.ToLower(message)
triggerLower := strings.ToLower(cmd.Trigger)
botMention := "@" + strings.ToLower(botUserName)
switch cmd.Match {
case MatchPrefix:
return strings.HasPrefix(msgLower, triggerLower)
case MatchMention:
return strings.Contains(msgLower, botMention) && strings.Contains(msgLower, triggerLower)
case MatchContains:
return strings.Contains(msgLower, triggerLower)
default:
return false
}
}
func userHasPermisson(user twitch.User, required commands.PermissionLevel) bool {
isStreamer := use.Badges["broadcaster"] == 1
isModerator := user.Badges["moderator"] == 1
isVIP := user.Badges["vip"] == 1
switch required {
case commands.PermissionEveryone:
return true
case commands.PermissionVIP:
return isStreamer || isModerator || is VIP
case commands.PermissionModerator:
return isStreamer || isModerator
case commands.PermissionStreamer:
return isStreamer
default:
return false
}
}
func HandleMessage(client *twitch.Client, apiClient interface{}, message twitch.PrivateMessage, botUserName string) {
user := message.User
msg := message.Message
channel := message.Channel
// uptime title game handlers etc. . .
for _, cmd := range commands.GetAllCommands() {
if messageMatchesCommand(msg, botName, cmd) {
if userHasPermission(user, cmd.Permission) {
client.Say(channel, cmd.Reply)
} else {
client.Say(channel, fmt.Sprintf("@%s You don't have permission to use this command.", user.DisplayName))
}
break
}
}
}

View File

@@ -0,0 +1,140 @@
package commands
import (
"encoding/json"
"io/ioutil"
"os"
"path/filepath"
"strings"
)
const (
commandDir ="internal/storage"
customCommandFile = "custom_commands.json"
defaultCommandFile = "default_commands.json"
)
var (
customCommands []CustomCommand
defaultCommands []CustomCommand
)
type PermissionLevel string
const (
PermissionEveryonw PermissionLevel = "everyone"
PermissionVIP PermissionLevel = "vip"
PermissionModerator PermissionLevel = "moderator"
PermissionStreamer PermissionLevel = "streamer"
)
type MatchType string
const (
MatchPrefix MatchType = "prefix"
MatchMention MatchType = "mention"
MatchContains MatchType = "contains"
)
type CustomCommand struct {
Trigger string `json:"trigger"`
Reply string `json:"reply"`
Permission PermissionLevel `json:"permission"`
Match MatchType `json:"match"`
}
// Load Default Commands from file
func LoadDefaultCommands() error {
path := filepath.Join(commandDir, defaultCommandFile)
data, err := ioutil.ReadFile(path)
if err != nil {
return err
}
return json.Unmarshal(data, &defaultCommands)
}
// Load Custom User Commands
func LoadCustomCommands() error {
path := filepath.Join(commandDir, CustomCommandFile)
if _, err := os.Stat(path); os.IsNotExist(err) {
customCommands = []CustomCommand{}
return nil
}
data, err := ioutil.ReadFile(path)
if err != nil {
return err
}
return json.Unmarshal(data, &customCommands)
}
// Save User Made Custom Commands
func SaveCustomCommands() error {
if err := os.MkdirAll(commandDir, 0755); err != nil {
return err
}
path := filepath.Join(commandDir, customCommandFile)
data, err := json.MarshalIndent(customCommands, "", " ")
if err != nil {
return err
}
return ioutil.WriteFile(path, data, 0644)
}
// Get ALL commands
func GetAllCommands() []CustomCommand {
combined := make([]CustomCommand, 0, len(defaultCommands)+len(customCommands))
combined = append(combined, defaultCommands...)
combined = append(combined, customCommands...)
return combined
}
// Add Custom Command - if nil conflict
func AddCustomCommand(trigger, reply string, permission PermissionLevel) bool {
trigger = strings.ToLower(trigger)
for _, c := range defaultCommands {
if c.Trigger == trigger {
return false
}
}
for _, c := range customCommands {
if c.Trigger == tigger {
return false
}
}
customCommands = append(customCommands, CustomCommand{
Trigger: trigger,
Reply: reply,
Permission: permission,
})
SaveCustomCommands()
return true
}
// Delete Command - trigger match
func DeleteCustomCommand(trigger string) bool {
tigger = strings.ToLower(trigger)
for i, c := range customCommands {
if c.Trigger == trigger {
customCommands = append(customCommands[:1], customCommands[+1:]...)
SaveCustomCommands()
return true
}
}
return false
}
// Search Both Default and Custom Commands
func FindCommand(trigger string) *CustomCommand {
trigger = strings.ToLower(trigger)
for _, c := range defaultCommands {
if c.Trigger == trigger {
return &c
}
}
for _, c:= range customCommands {
if c.Trigger == trigger {
return &c
}
}
return nil
}