mirror of
https://git.sr.ht/~ashkeel/strimertul
synced 2024-09-30 02:40:33 +00:00
189 lines
5 KiB
Go
189 lines
5 KiB
Go
package twitch
|
|
|
|
import (
|
|
"bytes"
|
|
"math/rand"
|
|
"strconv"
|
|
"strings"
|
|
"text/template"
|
|
"time"
|
|
|
|
"github.com/Masterminds/sprig/v3"
|
|
irc "github.com/gempir/go-twitch-irc/v4"
|
|
"github.com/nicklaw5/helix/v2"
|
|
"go.uber.org/zap"
|
|
)
|
|
|
|
type AccessLevelType string
|
|
|
|
const (
|
|
ALTEveryone AccessLevelType = "everyone"
|
|
ALTSubscribers AccessLevelType = "subscriber"
|
|
ALTVIP AccessLevelType = "vip"
|
|
ALTModerators AccessLevelType = "moderators"
|
|
ALTStreamer AccessLevelType = "streamer"
|
|
)
|
|
|
|
var accessLevels = map[AccessLevelType]int{
|
|
ALTEveryone: 0,
|
|
ALTSubscribers: 1,
|
|
ALTVIP: 2,
|
|
ALTModerators: 3,
|
|
ALTStreamer: 999,
|
|
}
|
|
|
|
type BotCommandHandler func(bot *Bot, message irc.PrivateMessage)
|
|
|
|
type BotCommand struct {
|
|
Description string
|
|
Usage string
|
|
AccessLevel AccessLevelType
|
|
Handler BotCommandHandler
|
|
Enabled bool
|
|
}
|
|
|
|
func cmdCustom(bot *Bot, cmd string, data BotCustomCommand, message irc.PrivateMessage) {
|
|
// Check access level
|
|
accessLevel := getUserAccessLevel(message.User)
|
|
|
|
// Ensure that access level is high enough
|
|
if accessLevels[accessLevel] < accessLevels[data.AccessLevel] {
|
|
return
|
|
}
|
|
|
|
var buf bytes.Buffer
|
|
tpl, ok := bot.customTemplates.GetKey(cmd)
|
|
if !ok {
|
|
return
|
|
}
|
|
if err := tpl.Execute(&buf, message); err != nil {
|
|
bot.logger.Error("Failed to execute custom command template", zap.Error(err))
|
|
return
|
|
}
|
|
|
|
switch data.ResponseType {
|
|
case ResponseTypeDefault, ResponseTypeChat:
|
|
bot.Client.Say(message.Channel, buf.String())
|
|
case ResponseTypeReply:
|
|
bot.Client.Reply(message.Channel, message.ID, buf.String())
|
|
case ResponseTypeWhisper:
|
|
client, err := bot.api.GetUserClient(false)
|
|
if err != nil {
|
|
bot.logger.Error("Failed to retrieve client", zap.Error(err))
|
|
return
|
|
}
|
|
reply, err := client.SendUserWhisper(&helix.SendUserWhisperParams{
|
|
FromUserID: bot.api.User.ID,
|
|
ToUserID: message.User.ID,
|
|
Message: buf.String(),
|
|
})
|
|
if reply.Error != "" {
|
|
bot.logger.Error("Failed to send whisper", zap.String("code", reply.Error), zap.String("message", reply.ErrorMessage))
|
|
}
|
|
if err != nil {
|
|
bot.logger.Error("Failed to send whisper", zap.Error(err))
|
|
}
|
|
|
|
case ResponseTypeAnnounce:
|
|
client, err := bot.api.GetUserClient(false)
|
|
if err != nil {
|
|
bot.logger.Error("Failed to retrieve client", zap.Error(err))
|
|
return
|
|
}
|
|
reply, err := client.SendChatAnnouncement(&helix.SendChatAnnouncementParams{
|
|
BroadcasterID: bot.api.User.ID,
|
|
ModeratorID: bot.api.User.ID,
|
|
Message: buf.String(),
|
|
})
|
|
if reply.Error != "" {
|
|
bot.logger.Error("Failed to send announcement", zap.String("code", reply.Error), zap.String("message", reply.ErrorMessage))
|
|
}
|
|
if err != nil {
|
|
bot.logger.Error("Failed to send announcement", zap.Error(err))
|
|
}
|
|
}
|
|
}
|
|
|
|
func (b *Bot) MakeTemplate(message string) (*template.Template, error) {
|
|
return template.New("").Funcs(sprig.TxtFuncMap()).Funcs(b.customFunctions).Parse(message)
|
|
}
|
|
|
|
var TestMessageData = irc.PrivateMessage{
|
|
User: irc.User{
|
|
ID: "603448316",
|
|
Name: "ashkeelvt",
|
|
DisplayName: "AshKeelVT",
|
|
Color: "#EC2B87",
|
|
Badges: map[string]int{
|
|
"subscriber": 0,
|
|
"moments": 1,
|
|
"broadcaster": 1,
|
|
},
|
|
},
|
|
Type: 1,
|
|
Tags: map[string]string{
|
|
"emotes": "",
|
|
"first-msg": "0",
|
|
"id": "e6b80ab3-d068-4226-83b2-a991da9c0cc3",
|
|
"turbo": "0",
|
|
"user-id": "603448316",
|
|
"badges": "broadcaster/1,subscriber/0,moments/1",
|
|
"color": "#EC2B87",
|
|
"user-type": "",
|
|
"room-id": "603448316",
|
|
"tmi-sent-ts": "1684345559394",
|
|
"flags": "",
|
|
"mod": "0",
|
|
"returning-chatter": "0",
|
|
"badge-info": "subscriber/21",
|
|
"display-name": "AshKeelVT",
|
|
"subscriber": "1",
|
|
},
|
|
Message: "!test",
|
|
Channel: "ashkeelvt",
|
|
RoomID: "603448316",
|
|
ID: "e6b80ab3-d068-4226-83b2-a991da9c0cc3",
|
|
Time: time.Now(),
|
|
Emotes: nil,
|
|
Bits: 0,
|
|
Action: false,
|
|
}
|
|
|
|
func (b *Bot) setupFunctions() {
|
|
b.customFunctions = template.FuncMap{
|
|
"user": func(message irc.PrivateMessage) string {
|
|
return message.User.DisplayName
|
|
},
|
|
"param": func(num int, message irc.PrivateMessage) string {
|
|
parts := strings.Split(message.Message, " ")
|
|
if num >= len(parts) {
|
|
return parts[len(parts)-1]
|
|
}
|
|
return parts[num]
|
|
},
|
|
"randomInt": func(min int, max int) int {
|
|
return rand.Intn(max-min) + min
|
|
},
|
|
"game": func(channel string) string {
|
|
channel = strings.TrimLeft(channel, "@")
|
|
info, err := b.api.API.SearchChannels(&helix.SearchChannelsParams{Channel: channel, First: 1, LiveOnly: false})
|
|
if err != nil {
|
|
return "unknown"
|
|
}
|
|
return info.Data.Channels[0].GameName
|
|
},
|
|
"count": func(name string) int {
|
|
counterKey := BotCounterPrefix + name
|
|
counter := 0
|
|
if byt, err := b.api.db.GetKey(counterKey); err == nil {
|
|
counter, _ = strconv.Atoi(byt)
|
|
}
|
|
counter++
|
|
err := b.api.db.PutKey(counterKey, strconv.Itoa(counter))
|
|
if err != nil {
|
|
b.logger.Error("Error saving key", zap.Error(err), zap.String("key", counterKey))
|
|
}
|
|
return counter
|
|
},
|
|
}
|
|
}
|