mirror of https://git.sr.ht/~ashkeel/strimertul
refactor: remove jsoniter
This commit is contained in:
parent
edcc4fb7f9
commit
ce2ce81768
12
app.go
12
app.go
|
@ -3,6 +3,7 @@ package main
|
|||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
|
@ -15,6 +16,11 @@ import (
|
|||
|
||||
"git.sr.ht/~ashkeel/containers/sync"
|
||||
kv "git.sr.ht/~ashkeel/kilovolt/v12"
|
||||
"github.com/nicklaw5/helix/v2"
|
||||
"github.com/urfave/cli/v2"
|
||||
"github.com/wailsapp/wails/v2/pkg/options"
|
||||
"github.com/wailsapp/wails/v2/pkg/runtime"
|
||||
|
||||
"git.sr.ht/~ashkeel/strimertul/database"
|
||||
"git.sr.ht/~ashkeel/strimertul/docs"
|
||||
"git.sr.ht/~ashkeel/strimertul/loyalty"
|
||||
|
@ -22,10 +28,6 @@ import (
|
|||
"git.sr.ht/~ashkeel/strimertul/twitch"
|
||||
"git.sr.ht/~ashkeel/strimertul/twitch/client"
|
||||
"git.sr.ht/~ashkeel/strimertul/webserver"
|
||||
"github.com/nicklaw5/helix/v2"
|
||||
"github.com/urfave/cli/v2"
|
||||
"github.com/wailsapp/wails/v2/pkg/options"
|
||||
"github.com/wailsapp/wails/v2/pkg/runtime"
|
||||
)
|
||||
|
||||
// App struct
|
||||
|
@ -155,7 +157,7 @@ func (a *App) initializeComponents() error {
|
|||
}
|
||||
|
||||
// Initialize loyalty system
|
||||
a.loyaltyManager, err = loyalty.NewManager(a.db)
|
||||
a.loyaltyManager, err = loyalty.NewManager(a.db, a.twitchManager)
|
||||
if err != nil {
|
||||
return fmt.Errorf("could not initialize loyalty manager: %w", err)
|
||||
}
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"log/slog"
|
||||
"os"
|
||||
|
||||
|
|
|
@ -1,13 +1,12 @@
|
|||
package database
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
kv "git.sr.ht/~ashkeel/kilovolt/v12"
|
||||
|
||||
jsoniter "github.com/json-iterator/go"
|
||||
)
|
||||
|
||||
func TestLocalDBClientPutKey(t *testing.T) {
|
||||
|
@ -60,7 +59,7 @@ func TestLocalDBClientPutJSON(t *testing.T) {
|
|||
}
|
||||
|
||||
var testStored test
|
||||
err = jsoniter.ConfigFastest.UnmarshalFromString(stored, &testStored)
|
||||
err = json.Unmarshal([]byte(stored), &testStored)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
@ -107,13 +106,13 @@ func TestLocalDBClientPutJSONBulk(t *testing.T) {
|
|||
}
|
||||
|
||||
var testStored1 test
|
||||
err = jsoniter.ConfigFastest.UnmarshalFromString(keys["test"], &testStored1)
|
||||
err = json.Unmarshal([]byte(keys["test"]), &testStored1)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
var testStored2 test
|
||||
err = jsoniter.ConfigFastest.UnmarshalFromString(keys["test2"], &testStored2)
|
||||
err = json.Unmarshal([]byte(keys["test2"]), &testStored2)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
@ -171,12 +170,12 @@ func TestLocalDBClientGetJSON(t *testing.T) {
|
|||
|
||||
// Store a key directly in the store
|
||||
key := "test"
|
||||
byt, err := jsoniter.ConfigFastest.MarshalToString(testStruct)
|
||||
byt, err := json.Marshal(testStruct)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
err = store.Set(key, byt)
|
||||
err = store.Set(key, string(byt))
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
|
|
@ -1,14 +1,14 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"os"
|
||||
|
||||
"git.sr.ht/~ashkeel/strimertul/docs"
|
||||
jsoniter "github.com/json-iterator/go"
|
||||
)
|
||||
|
||||
func main() {
|
||||
enc := jsoniter.ConfigFastest.NewEncoder(os.Stdout)
|
||||
enc := json.NewEncoder(os.Stdout)
|
||||
enc.SetIndent("", " ")
|
||||
_ = enc.Encode(docs.Keys)
|
||||
}
|
||||
|
|
3
go.mod
3
go.mod
|
@ -13,7 +13,6 @@ require (
|
|||
github.com/cockroachdb/pebble v1.1.0
|
||||
github.com/gorilla/websocket v1.5.1
|
||||
github.com/hashicorp/golang-lru/v2 v2.0.7
|
||||
github.com/json-iterator/go v1.1.12
|
||||
github.com/nicklaw5/helix/v2 v2.28.1
|
||||
github.com/samber/slog-multi v1.0.2
|
||||
github.com/urfave/cli/v2 v2.27.1
|
||||
|
@ -59,8 +58,6 @@ require (
|
|||
github.com/matttproud/golang_protobuf_extensions v1.0.2-0.20181231171920-c182affec369 // indirect
|
||||
github.com/mitchellh/copystructure v1.0.0 // indirect
|
||||
github.com/mitchellh/reflectwalk v1.0.0 // indirect
|
||||
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
|
||||
github.com/modern-go/reflect2 v1.0.2 // indirect
|
||||
github.com/pkg/browser v0.0.0-20210911075715-681adbf594b8 // indirect
|
||||
github.com/pkg/errors v0.9.1 // indirect
|
||||
github.com/prometheus/client_golang v1.12.0 // indirect
|
||||
|
|
3
go.sum
3
go.sum
|
@ -193,7 +193,6 @@ github.com/jpillora/backoff v1.0.0/go.mod h1:J/6gKK9jxlEcS3zixgDgUAsiuZ7yrSoa/FX
|
|||
github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU=
|
||||
github.com/json-iterator/go v1.1.10/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
|
||||
github.com/json-iterator/go v1.1.11/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
|
||||
github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM=
|
||||
github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo=
|
||||
github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU=
|
||||
github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/XSXhF0NWZEnDohbsk=
|
||||
|
@ -245,11 +244,9 @@ github.com/mitchellh/copystructure v1.0.0/go.mod h1:SNtv71yrdKgLRyLFxmLdkAbkKEFW
|
|||
github.com/mitchellh/reflectwalk v1.0.0 h1:9D+8oIskB4VJBN5SFlmc27fSlIBZaov1Wpk/IfikLNY=
|
||||
github.com/mitchellh/reflectwalk v1.0.0/go.mod h1:mSTlrgnPZtwu0c4WaC2kGObEpuNDbx0jmZXqmk4esnw=
|
||||
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
|
||||
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg=
|
||||
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
|
||||
github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
|
||||
github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
|
||||
github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M=
|
||||
github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk=
|
||||
github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U=
|
||||
github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U=
|
||||
|
|
|
@ -2,6 +2,7 @@ package main
|
|||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"log/slog"
|
||||
"math/rand"
|
||||
|
@ -66,7 +67,7 @@ func (core *LogStorage) Handle(_ context.Context, record slog.Record) error {
|
|||
attributes[attrs.Key] = attrs.Value.Any()
|
||||
return true
|
||||
})
|
||||
attrJSON, _ := json.MarshalToString(attributes)
|
||||
attrJSON, _ := json.Marshal(attributes)
|
||||
|
||||
// Generate unique log ID
|
||||
id := fmt.Sprintf("%d-%d", time.Now().UnixNano(), rand.Int31())
|
||||
|
@ -76,7 +77,7 @@ func (core *LogStorage) Handle(_ context.Context, record slog.Record) error {
|
|||
Time: record.Time.Format(time.RFC3339),
|
||||
Level: record.Level.String(),
|
||||
Message: record.Message,
|
||||
Data: attrJSON,
|
||||
Data: string(attrJSON),
|
||||
}
|
||||
lastLogs.Push(logEntry)
|
||||
if lastLogs.Size() > LogHistory {
|
||||
|
|
|
@ -1,19 +1,19 @@
|
|||
package chat
|
||||
package loyalty
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
"log/slog"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"git.sr.ht/~ashkeel/strimertul/twitch"
|
||||
"github.com/nicklaw5/helix/v2"
|
||||
|
||||
"git.sr.ht/~ashkeel/containers/sync"
|
||||
|
||||
"git.sr.ht/~ashkeel/strimertul/loyalty"
|
||||
"github.com/nicklaw5/helix/v2"
|
||||
"git.sr.ht/~ashkeel/strimertul/twitch"
|
||||
"git.sr.ht/~ashkeel/strimertul/twitch/chat"
|
||||
)
|
||||
|
||||
const (
|
||||
|
@ -23,49 +23,49 @@ const (
|
|||
commandContribute = "!contribute"
|
||||
)
|
||||
|
||||
type loyaltyIntegration struct {
|
||||
type twitchIntegration struct {
|
||||
ctx context.Context
|
||||
manager *loyalty.Manager
|
||||
module *Module
|
||||
manager *Manager
|
||||
module *chat.Module
|
||||
|
||||
activeUsers *sync.Map[string, bool]
|
||||
}
|
||||
|
||||
func setupLoyaltyIntegration(ctx context.Context, mod *Module, manager *loyalty.Manager) *loyaltyIntegration {
|
||||
li := &loyaltyIntegration{
|
||||
func setupTwitchIntegration(ctx context.Context, m *Manager, mod *chat.Module) *twitchIntegration {
|
||||
li := &twitchIntegration{
|
||||
ctx: ctx,
|
||||
manager: manager,
|
||||
manager: m,
|
||||
module: mod,
|
||||
|
||||
activeUsers: sync.NewMap[string, bool](),
|
||||
}
|
||||
|
||||
// Add loyalty-based commands
|
||||
mod.commands.SetKey(commandRedeem, Command{
|
||||
mod.RegisterCommand(commandRedeem, chat.Command{
|
||||
Description: "Redeem a reward with loyalty points",
|
||||
Usage: fmt.Sprintf("%s <reward-id> [request text]", commandRedeem),
|
||||
AccessLevel: ALTEveryone,
|
||||
AccessLevel: chat.ALTEveryone,
|
||||
Handler: li.cmdRedeemReward,
|
||||
Enabled: true,
|
||||
})
|
||||
mod.commands.SetKey(commandBalance, Command{
|
||||
mod.RegisterCommand(commandBalance, chat.Command{
|
||||
Description: "See your current point balance",
|
||||
Usage: commandBalance,
|
||||
AccessLevel: ALTEveryone,
|
||||
AccessLevel: chat.ALTEveryone,
|
||||
Handler: li.cmdBalance,
|
||||
Enabled: true,
|
||||
})
|
||||
mod.commands.SetKey(commandGoals, Command{
|
||||
mod.RegisterCommand(commandGoals, chat.Command{
|
||||
Description: "Check currently active community goals",
|
||||
Usage: commandGoals,
|
||||
AccessLevel: ALTEveryone,
|
||||
AccessLevel: chat.ALTEveryone,
|
||||
Handler: li.cmdGoalList,
|
||||
Enabled: true,
|
||||
})
|
||||
mod.commands.SetKey(commandContribute, Command{
|
||||
mod.RegisterCommand(commandContribute, chat.Command{
|
||||
Description: "Contribute points to a community goal",
|
||||
Usage: fmt.Sprintf("%s <points> [<goal-id>]", commandContribute),
|
||||
AccessLevel: ALTEveryone,
|
||||
AccessLevel: chat.ALTEveryone,
|
||||
Handler: li.cmdContributeGoal,
|
||||
Enabled: true,
|
||||
})
|
||||
|
@ -87,9 +87,9 @@ func setupLoyaltyIntegration(ctx context.Context, mod *Module, manager *loyalty.
|
|||
|
||||
// If stream is confirmed offline, don't give points away!
|
||||
var streamInfos []helix.Stream
|
||||
err := mod.db.GetJSON(twitch.StreamInfoKey, &streamInfos)
|
||||
err := m.db.GetJSON(twitch.StreamInfoKey, &streamInfos)
|
||||
if err != nil {
|
||||
mod.logger.Error("Error retrieving stream info", "error", err)
|
||||
slog.Error("Error retrieving stream info", "error", err)
|
||||
continue
|
||||
}
|
||||
if len(streamInfos) < 1 {
|
||||
|
@ -97,32 +97,7 @@ func setupLoyaltyIntegration(ctx context.Context, mod *Module, manager *loyalty.
|
|||
}
|
||||
|
||||
// Get user list
|
||||
cursor := ""
|
||||
var users []string
|
||||
for {
|
||||
userClient, err := twitch.GetUserClient(mod.db, false)
|
||||
if err != nil {
|
||||
mod.logger.Error("Could not get user api client for list of chatters", "error", err)
|
||||
return
|
||||
}
|
||||
res, err := userClient.GetChannelChatChatters(&helix.GetChatChattersParams{
|
||||
BroadcasterID: mod.user.ID,
|
||||
ModeratorID: mod.user.ID,
|
||||
First: "1000",
|
||||
After: cursor,
|
||||
})
|
||||
if err != nil {
|
||||
mod.logger.Error("Could not retrieve list of chatters", "error", err)
|
||||
return
|
||||
}
|
||||
for _, user := range res.Data.Chatters {
|
||||
users = append(users, user.UserLogin)
|
||||
}
|
||||
cursor = res.Data.Pagination.Cursor
|
||||
if cursor == "" {
|
||||
break
|
||||
}
|
||||
}
|
||||
users := mod.GetChatters()
|
||||
|
||||
// Iterate for each user in the list
|
||||
pointsToGive := make(map[string]int64)
|
||||
|
@ -148,48 +123,48 @@ func setupLoyaltyIntegration(ctx context.Context, mod *Module, manager *loyalty.
|
|||
if len(users) > 0 {
|
||||
err := li.manager.GivePoints(pointsToGive)
|
||||
if err != nil {
|
||||
mod.logger.Error("Error awarding loyalty points to user", "error", err)
|
||||
slog.Error("Error awarding loyalty points to user", "error", err)
|
||||
}
|
||||
}
|
||||
}
|
||||
}()
|
||||
|
||||
mod.logger.Info("Loyalty system integration with Twitch is ready")
|
||||
slog.Info("Loyalty system integration with Twitch is ready")
|
||||
|
||||
return li
|
||||
}
|
||||
|
||||
func (li *loyaltyIntegration) Close() {
|
||||
li.module.commands.DeleteKey(commandRedeem)
|
||||
li.module.commands.DeleteKey(commandBalance)
|
||||
li.module.commands.DeleteKey(commandGoals)
|
||||
li.module.commands.DeleteKey(commandContribute)
|
||||
func (li *twitchIntegration) Close() {
|
||||
li.module.UnregisterCommand(commandRedeem)
|
||||
li.module.UnregisterCommand(commandBalance)
|
||||
li.module.UnregisterCommand(commandGoals)
|
||||
li.module.UnregisterCommand(commandContribute)
|
||||
}
|
||||
|
||||
func (li *loyaltyIntegration) HandleMessage(message helix.EventSubChannelChatMessageEvent) {
|
||||
func (li *twitchIntegration) HandleMessage(message helix.EventSubChannelChatMessageEvent) {
|
||||
li.activeUsers.SetKey(message.ChatterUserLogin, true)
|
||||
}
|
||||
|
||||
func (li *loyaltyIntegration) IsActive(user string) bool {
|
||||
func (li *twitchIntegration) IsActive(user string) bool {
|
||||
active, ok := li.activeUsers.GetKey(user)
|
||||
return ok && active
|
||||
}
|
||||
|
||||
func (li *loyaltyIntegration) ResetActivity() {
|
||||
func (li *twitchIntegration) ResetActivity() {
|
||||
li.activeUsers = sync.NewMap[string, bool]()
|
||||
}
|
||||
|
||||
func (li *loyaltyIntegration) cmdBalance(message helix.EventSubChannelChatMessageEvent) {
|
||||
func (li *twitchIntegration) cmdBalance(message helix.EventSubChannelChatMessageEvent) {
|
||||
// Get user balance
|
||||
balance := li.manager.GetPoints(message.ChatterUserLogin)
|
||||
|
||||
li.module.WriteMessage(WriteMessageRequest{
|
||||
li.module.WriteMessage(chat.WriteMessageRequest{
|
||||
Message: fmt.Sprintf("You have %d %s!", balance, li.manager.Config.Get().Currency),
|
||||
ReplyTo: message.MessageID,
|
||||
})
|
||||
}
|
||||
|
||||
func (li *loyaltyIntegration) cmdRedeemReward(message helix.EventSubChannelChatMessageEvent) {
|
||||
func (li *twitchIntegration) cmdRedeemReward(message helix.EventSubChannelChatMessageEvent) {
|
||||
parts := strings.Fields(message.Message.Text)
|
||||
if len(parts) < 2 {
|
||||
return
|
||||
|
@ -213,7 +188,7 @@ func (li *loyaltyIntegration) cmdRedeemReward(message helix.EventSubChannelChatM
|
|||
|
||||
// Check if user can afford the reward
|
||||
if balance-reward.Price < 0 {
|
||||
li.module.WriteMessage(WriteMessageRequest{
|
||||
li.module.WriteMessage(chat.WriteMessageRequest{
|
||||
Message: fmt.Sprintf("I'm sorry but you cannot afford this (have %d %s, need %d)", balance, config.Currency, reward.Price),
|
||||
ReplyTo: message.MessageID,
|
||||
})
|
||||
|
@ -226,36 +201,36 @@ func (li *loyaltyIntegration) cmdRedeemReward(message helix.EventSubChannelChatM
|
|||
}
|
||||
|
||||
// Perform redeem
|
||||
if err := li.manager.PerformRedeem(loyalty.Redeem{
|
||||
if err := li.manager.PerformRedeem(Redeem{
|
||||
Username: message.ChatterUserLogin,
|
||||
DisplayName: message.ChatterUserName,
|
||||
When: time.Now(),
|
||||
Reward: reward,
|
||||
RequestText: text,
|
||||
}); err != nil {
|
||||
if errors.Is(err, loyalty.ErrRedeemInCooldown) {
|
||||
if errors.Is(err, ErrRedeemInCooldown) {
|
||||
nextAvailable := li.manager.GetRewardCooldown(reward.ID)
|
||||
li.module.WriteMessage(WriteMessageRequest{
|
||||
li.module.WriteMessage(chat.WriteMessageRequest{
|
||||
Message: fmt.Sprintf("That reward is in cooldown (available in %s)",
|
||||
time.Until(nextAvailable).Truncate(time.Second)),
|
||||
ReplyTo: message.MessageID,
|
||||
})
|
||||
return
|
||||
}
|
||||
li.module.logger.Error("Error while performing redeem", "error", err)
|
||||
slog.Error("Error while performing redeem", "error", err)
|
||||
return
|
||||
}
|
||||
|
||||
li.module.WriteMessage(WriteMessageRequest{
|
||||
li.module.WriteMessage(chat.WriteMessageRequest{
|
||||
Message: fmt.Sprintf("HolidayPresent %s has redeemed %s! (new balance: %d %s)",
|
||||
message.ChatterUserName, reward.Name, li.manager.GetPoints(message.ChatterUserLogin), config.Currency),
|
||||
})
|
||||
}
|
||||
|
||||
func (li *loyaltyIntegration) cmdGoalList(message helix.EventSubChannelChatMessageEvent) {
|
||||
func (li *twitchIntegration) cmdGoalList(message helix.EventSubChannelChatMessageEvent) {
|
||||
goals := li.manager.Goals.Get()
|
||||
if len(goals) < 1 {
|
||||
li.module.WriteMessage(WriteMessageRequest{
|
||||
li.module.WriteMessage(chat.WriteMessageRequest{
|
||||
Message: "There are no active community goals right now :(!",
|
||||
ReplyTo: message.MessageID,
|
||||
})
|
||||
|
@ -269,12 +244,12 @@ func (li *loyaltyIntegration) cmdGoalList(message helix.EventSubChannelChatMessa
|
|||
msg += fmt.Sprintf("%s (%d/%d %s) [id: %s] | ", goal.Name, goal.Contributed, goal.TotalGoal, li.manager.Config.Get().Currency, goal.ID)
|
||||
}
|
||||
msg += " Contribute with <!contribute POINTS GOALID>"
|
||||
li.module.WriteMessage(WriteMessageRequest{
|
||||
li.module.WriteMessage(chat.WriteMessageRequest{
|
||||
Message: msg,
|
||||
})
|
||||
}
|
||||
|
||||
func (li *loyaltyIntegration) cmdContributeGoal(message helix.EventSubChannelChatMessageEvent) {
|
||||
func (li *twitchIntegration) cmdContributeGoal(message helix.EventSubChannelChatMessageEvent) {
|
||||
goals := li.manager.Goals.Get()
|
||||
|
||||
// Set defaults if user doesn't provide them
|
||||
|
@ -297,12 +272,12 @@ func (li *loyaltyIntegration) cmdContributeGoal(message helix.EventSubChannelCha
|
|||
// Do we not have any goal we can contribute to? Hooray I guess?
|
||||
if goalIndex < 0 {
|
||||
if hasGoals {
|
||||
li.module.WriteMessage(WriteMessageRequest{
|
||||
li.module.WriteMessage(chat.WriteMessageRequest{
|
||||
Message: "All active community goals have been reached already! NewRecord",
|
||||
ReplyTo: message.MessageID,
|
||||
})
|
||||
} else {
|
||||
li.module.WriteMessage(WriteMessageRequest{
|
||||
li.module.WriteMessage(chat.WriteMessageRequest{
|
||||
Message: "There are no active community goals right now :(!",
|
||||
ReplyTo: message.MessageID,
|
||||
})
|
||||
|
@ -316,7 +291,7 @@ func (li *loyaltyIntegration) cmdContributeGoal(message helix.EventSubChannelCha
|
|||
newPoints, err := strconv.ParseInt(parts[1], 10, 64)
|
||||
if err == nil {
|
||||
if newPoints <= 0 {
|
||||
li.module.WriteMessage(WriteMessageRequest{
|
||||
li.module.WriteMessage(chat.WriteMessageRequest{
|
||||
Message: "Nice try SoBayed",
|
||||
ReplyTo: message.MessageID,
|
||||
})
|
||||
|
@ -340,7 +315,7 @@ func (li *loyaltyIntegration) cmdContributeGoal(message helix.EventSubChannelCha
|
|||
}
|
||||
// Invalid goal ID provided
|
||||
if !found {
|
||||
li.module.WriteMessage(WriteMessageRequest{
|
||||
li.module.WriteMessage(chat.WriteMessageRequest{
|
||||
Message: "I couldn't find that goal ID :(",
|
||||
ReplyTo: message.MessageID,
|
||||
})
|
||||
|
@ -354,7 +329,7 @@ func (li *loyaltyIntegration) cmdContributeGoal(message helix.EventSubChannelCha
|
|||
|
||||
// Check if goal was reached already
|
||||
if selectedGoal.Contributed >= selectedGoal.TotalGoal {
|
||||
li.module.WriteMessage(WriteMessageRequest{
|
||||
li.module.WriteMessage(chat.WriteMessageRequest{
|
||||
Message: "This goal was already reached! ヾ(•ω•`)o",
|
||||
ReplyTo: message.MessageID,
|
||||
})
|
||||
|
@ -364,11 +339,11 @@ func (li *loyaltyIntegration) cmdContributeGoal(message helix.EventSubChannelCha
|
|||
// Add points to goal
|
||||
points, err := li.manager.PerformContribution(selectedGoal, message.ChatterUserLogin, points)
|
||||
if err != nil {
|
||||
li.module.logger.Error("Error while contributing to goal", "error", err)
|
||||
slog.Error("Error while contributing to goal", "error", err)
|
||||
return
|
||||
}
|
||||
if points == 0 {
|
||||
li.module.WriteMessage(WriteMessageRequest{
|
||||
li.module.WriteMessage(chat.WriteMessageRequest{
|
||||
Message: "Sorry but you're broke",
|
||||
ReplyTo: message.MessageID,
|
||||
})
|
||||
|
@ -378,13 +353,13 @@ func (li *loyaltyIntegration) cmdContributeGoal(message helix.EventSubChannelCha
|
|||
selectedGoal = li.manager.Goals.Get()[goalIndex]
|
||||
config := li.manager.Config.Get()
|
||||
newRemaining := selectedGoal.TotalGoal - selectedGoal.Contributed
|
||||
li.module.WriteMessage(WriteMessageRequest{
|
||||
li.module.WriteMessage(chat.WriteMessageRequest{
|
||||
Message: fmt.Sprintf("NewRecord %s contributed %d %s to \"%s\"!! Only %d %s left!", message.ChatterUserName, points, config.Currency, selectedGoal.Name, newRemaining, config.Currency),
|
||||
})
|
||||
|
||||
// Check if goal was reached!
|
||||
if newRemaining <= 0 {
|
||||
li.module.WriteMessage(WriteMessageRequest{
|
||||
li.module.WriteMessage(chat.WriteMessageRequest{
|
||||
Message: fmt.Sprintf("FallWinning The community goal \"%s\" was reached! FallWinning", selectedGoal.Name),
|
||||
Announce: true,
|
||||
})
|
|
@ -2,6 +2,7 @@ package loyalty
|
|||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"log/slog"
|
||||
|
@ -10,12 +11,10 @@ import (
|
|||
|
||||
"git.sr.ht/~ashkeel/containers/sync"
|
||||
"git.sr.ht/~ashkeel/strimertul/database"
|
||||
twitchclient "git.sr.ht/~ashkeel/strimertul/twitch/client"
|
||||
"git.sr.ht/~ashkeel/strimertul/utils"
|
||||
jsoniter "github.com/json-iterator/go"
|
||||
)
|
||||
|
||||
var json = jsoniter.ConfigFastest
|
||||
|
||||
var (
|
||||
ErrRedeemNotFound = errors.New("redeem not found")
|
||||
ErrRedeemInCooldown = errors.New("redeem is on cooldown")
|
||||
|
@ -36,9 +35,11 @@ type Manager struct {
|
|||
cancelFn context.CancelFunc
|
||||
cancelSub database.CancelFunc
|
||||
restartTwitchHandler chan struct{}
|
||||
twitchManager *twitchclient.Manager
|
||||
twitchIntegration *twitchIntegration
|
||||
}
|
||||
|
||||
func NewManager(db database.Database) (*Manager, error) {
|
||||
func NewManager(db database.Database, twitchManager *twitchclient.Manager) (*Manager, error) {
|
||||
ctx, cancelFn := context.WithCancel(context.Background())
|
||||
loyalty := &Manager{
|
||||
Config: sync.NewRWSync(Config{Enabled: false}),
|
||||
|
@ -53,6 +54,7 @@ func NewManager(db database.Database) (*Manager, error) {
|
|||
ctx: ctx,
|
||||
cancelFn: cancelFn,
|
||||
restartTwitchHandler: make(chan struct{}),
|
||||
twitchManager: twitchManager,
|
||||
}
|
||||
// Get data from DB
|
||||
var config Config
|
||||
|
@ -103,7 +105,7 @@ func NewManager(db database.Database) (*Manager, error) {
|
|||
|
||||
for k, v := range points {
|
||||
var entry PointsEntry
|
||||
err := json.UnmarshalFromString(v, &entry)
|
||||
err := json.Unmarshal([]byte(v), &entry)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
@ -119,10 +121,20 @@ func NewManager(db database.Database) (*Manager, error) {
|
|||
|
||||
loyalty.SetBanList(config.BanList)
|
||||
|
||||
// Start twitch handler
|
||||
if twitchManager.Client() != nil {
|
||||
loyalty.twitchIntegration = setupTwitchIntegration(ctx, loyalty, twitchManager.Client().Chat)
|
||||
}
|
||||
|
||||
return loyalty, nil
|
||||
}
|
||||
|
||||
func (m *Manager) Close() error {
|
||||
// Disable twitch integration
|
||||
if m.twitchIntegration != nil {
|
||||
m.twitchIntegration.Close()
|
||||
}
|
||||
|
||||
// Stop subscription
|
||||
if m.cancelSub != nil {
|
||||
m.cancelSub()
|
||||
|
@ -152,13 +164,13 @@ func (m *Manager) update(key, value string) {
|
|||
err = utils.LoadJSONToWrapped[[]Redeem](value, m.Queue)
|
||||
case CreateRedeemRPC:
|
||||
var redeem Redeem
|
||||
err = json.UnmarshalFromString(value, &redeem)
|
||||
err = json.Unmarshal([]byte(value), &redeem)
|
||||
if err == nil {
|
||||
err = m.AddRedeem(redeem)
|
||||
}
|
||||
case RemoveRedeemRPC:
|
||||
var redeem Redeem
|
||||
err = json.UnmarshalFromString(value, &redeem)
|
||||
err = json.Unmarshal([]byte(value), &redeem)
|
||||
if err == nil {
|
||||
err = m.RemoveRedeem(redeem)
|
||||
}
|
||||
|
@ -168,7 +180,7 @@ func (m *Manager) update(key, value string) {
|
|||
// User point changed
|
||||
case strings.HasPrefix(key, PointsPrefix):
|
||||
var entry PointsEntry
|
||||
err = json.UnmarshalFromString(value, &entry)
|
||||
err = json.Unmarshal([]byte(value), &entry)
|
||||
user := key[len(PointsPrefix):]
|
||||
m.points.SetKey(user, entry)
|
||||
}
|
||||
|
|
3
main.go
3
main.go
|
@ -12,7 +12,6 @@ import (
|
|||
|
||||
"git.sr.ht/~ashkeel/strimertul/utils"
|
||||
"github.com/apenwarr/fixconsole"
|
||||
jsoniter "github.com/json-iterator/go"
|
||||
"github.com/urfave/cli/v2"
|
||||
"github.com/wailsapp/wails/v2"
|
||||
"github.com/wailsapp/wails/v2/pkg/options"
|
||||
|
@ -20,8 +19,6 @@ import (
|
|||
"github.com/wailsapp/wails/v2/pkg/runtime"
|
||||
)
|
||||
|
||||
var json = jsoniter.ConfigFastest
|
||||
|
||||
const devVersionMarker = "v0.0.0-UNKNOWN"
|
||||
|
||||
var appVersion = devVersionMarker
|
||||
|
|
|
@ -1,7 +1,8 @@
|
|||
package alerts
|
||||
|
||||
import (
|
||||
jsoniter "github.com/json-iterator/go"
|
||||
"encoding/json"
|
||||
|
||||
"github.com/nicklaw5/helix/v2"
|
||||
)
|
||||
|
||||
|
@ -10,7 +11,7 @@ const ConfigKey = "twitch/alerts/config"
|
|||
type eventSubNotification struct {
|
||||
Subscription helix.EventSubSubscription `json:"subscription"`
|
||||
Challenge string `json:"challenge"`
|
||||
Event jsoniter.RawMessage `json:"event" desc:"Event payload, as JSON object"`
|
||||
Event json.RawMessage `json:"event" desc:"Event payload, as JSON object"`
|
||||
}
|
||||
|
||||
type subscriptionVariation struct {
|
||||
|
|
|
@ -2,23 +2,23 @@ package chat
|
|||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"log/slog"
|
||||
"strings"
|
||||
textTemplate "text/template"
|
||||
"time"
|
||||
|
||||
"github.com/nicklaw5/helix/v2"
|
||||
|
||||
"git.sr.ht/~ashkeel/containers/sync"
|
||||
"git.sr.ht/~ashkeel/strimertul/database"
|
||||
"git.sr.ht/~ashkeel/strimertul/twitch"
|
||||
"git.sr.ht/~ashkeel/strimertul/twitch/eventsub"
|
||||
"git.sr.ht/~ashkeel/strimertul/twitch/template"
|
||||
"git.sr.ht/~ashkeel/strimertul/utils"
|
||||
jsoniter "github.com/json-iterator/go"
|
||||
"github.com/nicklaw5/helix/v2"
|
||||
)
|
||||
|
||||
var json = jsoniter.ConfigFastest
|
||||
|
||||
type Module struct {
|
||||
Config Config
|
||||
|
||||
|
@ -97,8 +97,8 @@ func (mod *Module) onChatMessage(newValue string) {
|
|||
var chatMessage struct {
|
||||
Event helix.EventSubChannelChatMessageEvent `json:"event"`
|
||||
}
|
||||
if err := json.UnmarshalFromString(newValue, &chatMessage); err != nil {
|
||||
mod.logger.Error("Failed to decode incoming chat message", "error", err)
|
||||
if err := json.Unmarshal([]byte(newValue), &chatMessage); err != nil {
|
||||
mod.logger.Error("Failed to decode incoming chat message", slog.String("error", err.Error()))
|
||||
return
|
||||
}
|
||||
|
||||
|
@ -222,3 +222,39 @@ func (mod *Module) updateTemplates() error {
|
|||
func (mod *Module) WriteMessage(request WriteMessageRequest) {
|
||||
WriteMessage(mod.db, mod.logger, request)
|
||||
}
|
||||
|
||||
func (mod *Module) RegisterCommand(name string, command Command) {
|
||||
mod.commands.SetKey(name, command)
|
||||
}
|
||||
|
||||
func (mod *Module) UnregisterCommand(name string) {
|
||||
mod.commands.DeleteKey(name)
|
||||
}
|
||||
|
||||
func (mod *Module) GetChatters() (users []string) {
|
||||
cursor := ""
|
||||
for {
|
||||
userClient, err := twitch.GetUserClient(mod.db, false)
|
||||
if err != nil {
|
||||
slog.Error("Could not get user api client for list of chatters", "error", err)
|
||||
return
|
||||
}
|
||||
res, err := userClient.GetChannelChatChatters(&helix.GetChatChattersParams{
|
||||
BroadcasterID: mod.user.ID,
|
||||
ModeratorID: mod.user.ID,
|
||||
First: "1000",
|
||||
After: cursor,
|
||||
})
|
||||
if err != nil {
|
||||
mod.logger.Error("Could not retrieve list of chatters", "error", err)
|
||||
return
|
||||
}
|
||||
for _, user := range res.Data.Chatters {
|
||||
users = append(users, user.UserLogin)
|
||||
}
|
||||
cursor = res.Data.Pagination.Cursor
|
||||
if cursor == "" {
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,6 +2,7 @@ package eventsub
|
|||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"log/slog"
|
||||
"time"
|
||||
|
@ -10,12 +11,9 @@ import (
|
|||
"git.sr.ht/~ashkeel/strimertul/utils"
|
||||
"github.com/gorilla/websocket"
|
||||
lru "github.com/hashicorp/golang-lru/v2"
|
||||
jsoniter "github.com/json-iterator/go"
|
||||
"github.com/nicklaw5/helix/v2"
|
||||
)
|
||||
|
||||
var json = jsoniter.ConfigFastest
|
||||
|
||||
const websocketEndpoint = "wss://eventsub.wss.twitch.tv/ws"
|
||||
|
||||
type Client struct {
|
||||
|
@ -259,8 +257,8 @@ func topicCondition(topic string, id string) helix.EventSubCondition {
|
|||
}
|
||||
|
||||
type WebsocketMessage struct {
|
||||
Metadata Metadata `json:"metadata"`
|
||||
Payload jsoniter.RawMessage `json:"payload"`
|
||||
Metadata Metadata `json:"metadata"`
|
||||
Payload json.RawMessage `json:"payload"`
|
||||
}
|
||||
|
||||
type WelcomeMessagePayload struct {
|
||||
|
@ -275,7 +273,7 @@ type WelcomeMessagePayload struct {
|
|||
|
||||
type NotificationMessagePayload struct {
|
||||
Subscription helix.EventSubSubscription `json:"subscription"`
|
||||
Event jsoniter.RawMessage `json:"event"`
|
||||
Event json.RawMessage `json:"event"`
|
||||
Date time.Time `json:"date,omitempty"`
|
||||
}
|
||||
|
||||
|
|
|
@ -2,6 +2,7 @@ package timers
|
|||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"log/slog"
|
||||
"math/rand"
|
||||
"time"
|
||||
|
@ -9,11 +10,8 @@ import (
|
|||
"git.sr.ht/~ashkeel/containers/sync"
|
||||
"git.sr.ht/~ashkeel/strimertul/database"
|
||||
"git.sr.ht/~ashkeel/strimertul/twitch/chat"
|
||||
jsoniter "github.com/json-iterator/go"
|
||||
)
|
||||
|
||||
var json = jsoniter.ConfigFastest
|
||||
|
||||
const AverageMessageWindow = 5
|
||||
|
||||
type Module struct {
|
||||
|
@ -56,7 +54,7 @@ func Setup(ctx context.Context, db database.Database, logger *slog.Logger) *Modu
|
|||
}
|
||||
|
||||
if err := db.SubscribeKeyContext(ctx, ConfigKey, func(value string) {
|
||||
if err := json.UnmarshalFromString(value, &mod.Config); err != nil {
|
||||
if err := json.Unmarshal([]byte(value), &mod.Config); err != nil {
|
||||
logger.Warn("Error reloading timer config", "error", err)
|
||||
return
|
||||
}
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
package utils
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"testing"
|
||||
|
||||
"git.sr.ht/~ashkeel/containers/sync"
|
||||
jsoniter "github.com/json-iterator/go"
|
||||
)
|
||||
|
||||
func TestLoadJSONToWrapped(t *testing.T) {
|
||||
|
@ -17,7 +17,7 @@ func TestLoadJSONToWrapped(t *testing.T) {
|
|||
}
|
||||
|
||||
// Encode test object to JSON
|
||||
testStr, err := jsoniter.ConfigFastest.MarshalToString(testObj)
|
||||
testByt, err := json.Marshal(testObj)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
@ -26,7 +26,7 @@ func TestLoadJSONToWrapped(t *testing.T) {
|
|||
wrapped := sync.NewSync[test](test{})
|
||||
|
||||
// Load JSON to wrapped
|
||||
err = LoadJSONToWrapped[test](testStr, wrapped)
|
||||
err = LoadJSONToWrapped[test](string(testByt), wrapped)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue