181 lines
4.2 KiB
Go
181 lines
4.2 KiB
Go
|
package chatbot
|
||
|
|
||
|
import (
|
||
|
"bufio"
|
||
|
"cmp"
|
||
|
"crypto/rand"
|
||
|
"encoding/json"
|
||
|
"fmt"
|
||
|
"math/big"
|
||
|
"os"
|
||
|
"slices"
|
||
|
"strconv"
|
||
|
"strings"
|
||
|
"time"
|
||
|
|
||
|
"github.com/tylertravisty/rum-goggles/v1/internal/models"
|
||
|
)
|
||
|
|
||
|
func SortRules(rules []Rule) {
|
||
|
slices.SortFunc(rules, func(a, b Rule) int {
|
||
|
return cmp.Compare(strings.ToLower(a.Display), strings.ToLower(b.Display))
|
||
|
})
|
||
|
}
|
||
|
|
||
|
type Rule struct {
|
||
|
ID *int64 `json:"id"`
|
||
|
ChatbotID *int64 `json:"chatbot_id"`
|
||
|
Display string `json:"display"`
|
||
|
Parameters *RuleParameters `json:"parameters"`
|
||
|
Running bool `json:"running"`
|
||
|
}
|
||
|
|
||
|
type RuleParameters struct {
|
||
|
Message *RuleMessage `json:"message"`
|
||
|
SendAs *RuleSender `json:"send_as"`
|
||
|
Trigger *RuleTrigger `json:"trigger"`
|
||
|
}
|
||
|
|
||
|
type RuleMessage struct {
|
||
|
FromFile *RuleMessageFile `json:"from_file"`
|
||
|
FromText string `json:"from_text"`
|
||
|
}
|
||
|
|
||
|
func (rm *RuleMessage) String() (string, error) {
|
||
|
if rm.FromFile == nil {
|
||
|
return rm.FromText, nil
|
||
|
}
|
||
|
|
||
|
s, err := rm.FromFile.string()
|
||
|
if err != nil {
|
||
|
return "", fmt.Errorf("error reading from file: %v", err)
|
||
|
}
|
||
|
|
||
|
return s, nil
|
||
|
}
|
||
|
|
||
|
func (rmf *RuleMessageFile) string() (string, error) {
|
||
|
if rmf.Filepath == "" {
|
||
|
return "", fmt.Errorf("filepath is empty")
|
||
|
}
|
||
|
|
||
|
if len(rmf.lines) == 0 {
|
||
|
file, err := os.Open(rmf.Filepath)
|
||
|
if err != nil {
|
||
|
return "", fmt.Errorf("error opening file: %v", err)
|
||
|
}
|
||
|
defer file.Close()
|
||
|
|
||
|
scanner := bufio.NewScanner(file)
|
||
|
for scanner.Scan() {
|
||
|
line := strings.TrimSpace(scanner.Text())
|
||
|
if line == "" {
|
||
|
continue
|
||
|
}
|
||
|
rmf.lines = append(rmf.lines, line)
|
||
|
}
|
||
|
|
||
|
if len(rmf.lines) == 0 {
|
||
|
return "", fmt.Errorf("no lines read")
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if rmf.RandomRead {
|
||
|
n, err := rand.Int(rand.Reader, big.NewInt(int64(len(rmf.lines))))
|
||
|
if err != nil {
|
||
|
return "", fmt.Errorf("error generating random line number: %v", err)
|
||
|
}
|
||
|
|
||
|
return rmf.lines[n.Int64()], nil
|
||
|
}
|
||
|
|
||
|
line := rmf.lines[rmf.lineNum]
|
||
|
rmf.lineNum = rmf.lineNum + 1
|
||
|
if rmf.lineNum >= len(rmf.lines) {
|
||
|
rmf.lineNum = 0
|
||
|
}
|
||
|
|
||
|
return line, nil
|
||
|
}
|
||
|
|
||
|
type RuleMessageFile struct {
|
||
|
Filepath string `json:"filepath"`
|
||
|
RandomRead bool `json:"random_read"`
|
||
|
lines []string
|
||
|
lineNum int
|
||
|
}
|
||
|
|
||
|
type RuleSender struct {
|
||
|
ChannelID *string `json:"channel_id"`
|
||
|
Display string `json:"display"`
|
||
|
Username string `json:"username"`
|
||
|
}
|
||
|
|
||
|
func (rs *RuleSender) ChannelIDInt() (*int, error) {
|
||
|
if rs.ChannelID == nil {
|
||
|
return nil, nil
|
||
|
}
|
||
|
|
||
|
i64, err := strconv.ParseInt(*rs.ChannelID, 10, 64)
|
||
|
if err != nil {
|
||
|
return nil, pkgErr("error parsing channel ID", err)
|
||
|
}
|
||
|
i := int(i64)
|
||
|
|
||
|
return &i, nil
|
||
|
}
|
||
|
|
||
|
type RuleTrigger struct {
|
||
|
OnCommand *RuleTriggerCommand `json:"on_command"`
|
||
|
OnEvent *RuleTriggerEvent `json:"on_event"`
|
||
|
OnTimer *time.Duration `json:"on_timer"`
|
||
|
}
|
||
|
|
||
|
type RuleTriggerCommand struct {
|
||
|
Command string `json:"command"`
|
||
|
Restrict *RuleTriggerCommandRestriction `json:"restrict"`
|
||
|
Timeout time.Duration `json:"timeout"`
|
||
|
}
|
||
|
|
||
|
type RuleTriggerCommandRestriction struct {
|
||
|
Bypass *RuleTriggerCommandRestrictionBypass `json:"bypass"`
|
||
|
ToAdmin bool `json:"to_admin"`
|
||
|
ToFollower bool `json:"to_follower"`
|
||
|
ToMod bool `json:"to_mod"`
|
||
|
ToStreamer bool `json:"to_streamer"`
|
||
|
ToSubscriber bool `json:"to_subscriber"`
|
||
|
ToRant int `json:"to_rant"`
|
||
|
}
|
||
|
|
||
|
type RuleTriggerCommandRestrictionBypass struct {
|
||
|
IfAdmin bool `json:"if_admin"`
|
||
|
IfMod bool `json:"if_mod"`
|
||
|
IfStreamer bool `json:"if_streamer"`
|
||
|
}
|
||
|
|
||
|
type RuleTriggerEvent struct {
|
||
|
OnFollow bool `json:"on_follow"`
|
||
|
OnSubscribe bool `json:"on_subscribe"`
|
||
|
OnRaid bool `json:"on_raid"`
|
||
|
OnRant int `json:"on_rant"`
|
||
|
}
|
||
|
|
||
|
func (rule *Rule) ToModelsChatbotRule() (*models.ChatbotRule, error) {
|
||
|
modelsRule := &models.ChatbotRule{
|
||
|
ID: rule.ID,
|
||
|
ChatbotID: rule.ChatbotID,
|
||
|
}
|
||
|
|
||
|
if rule.Parameters != nil {
|
||
|
paramsB, err := json.Marshal(rule.Parameters)
|
||
|
if err != nil {
|
||
|
return nil, fmt.Errorf("error marshaling parameters into json: %v", err)
|
||
|
}
|
||
|
|
||
|
paramsS := string(paramsB)
|
||
|
modelsRule.Parameters = ¶msS
|
||
|
}
|
||
|
|
||
|
return modelsRule, nil
|
||
|
}
|