1
0
Fork 0
mirror of https://git.sr.ht/~ashkeel/strimertul synced 2024-09-20 02:00:49 +00:00
strimertul/modules/twitch/commands.go

224 lines
6.2 KiB
Go
Raw Normal View History

package twitch
2021-05-02 12:29:43 +00:00
import (
"fmt"
"strconv"
2021-05-02 12:29:43 +00:00
"strings"
"time"
2021-05-02 12:29:43 +00:00
irc "github.com/gempir/go-twitch-irc/v2"
"github.com/strimertul/strimertul/modules/loyalty"
2021-05-02 12:29:43 +00:00
)
type AccessLevelType string
const (
ALTEveryone AccessLevelType = "everyone"
ALTVIP AccessLevelType = "vip"
ALTModerators AccessLevelType = "moderators"
ALTStreamer AccessLevelType = "streamer"
)
type BotCommandHandler func(bot *Bot, message irc.PrivateMessage)
2021-05-02 12:29:43 +00:00
type BotCommand struct {
Description string
Usage string
AccessLevel AccessLevelType
Handler BotCommandHandler
}
var commands = map[string]BotCommand{
"!redeem": {
Description: "Redeem a reward with loyalty points",
2021-05-18 13:29:21 +00:00
Usage: "!redeem <reward-id> [request text]",
2021-05-02 12:29:43 +00:00
AccessLevel: ALTEveryone,
Handler: cmdRedeemReward,
2021-05-02 12:29:43 +00:00
},
2021-05-03 08:35:11 +00:00
"!balance": {
Description: "See your current point balance",
Usage: "!balance",
AccessLevel: ALTEveryone,
Handler: cmdBalance,
},
"!goals": {
Description: "Check currently active community goals",
Usage: "!goals",
AccessLevel: ALTEveryone,
Handler: cmdGoalList,
},
"!contribute": {
Description: "Contribute points to a community goal",
Usage: "!contribute <points> [<goal-id>]",
AccessLevel: ALTEveryone,
Handler: cmdContributeGoal,
},
2021-05-03 08:35:11 +00:00
}
func cmdBalance(bot *Bot, message irc.PrivateMessage) {
2021-05-03 08:35:11 +00:00
// Get user balance
balance := bot.Loyalty.GetPoints(message.User.Name)
bot.Client.Say(message.Channel, fmt.Sprintf("%s: You have %d %s!", message.User.DisplayName, balance, bot.Loyalty.Config().Currency))
2021-05-02 12:29:43 +00:00
}
func cmdRedeemReward(bot *Bot, message irc.PrivateMessage) {
2021-05-02 12:29:43 +00:00
parts := strings.Fields(message.Message)
if len(parts) < 2 {
return
}
redeemID := parts[1]
// Find reward
2021-05-18 13:50:58 +00:00
reward := bot.Loyalty.GetReward(redeemID)
if reward.ID == "" {
return
}
2021-05-02 12:29:43 +00:00
2021-05-18 13:50:58 +00:00
// Reward not active, return early
if !reward.Enabled {
return
}
2021-05-02 12:29:43 +00:00
2021-05-18 13:50:58 +00:00
// Get user balance
balance := bot.Loyalty.GetPoints(message.User.Name)
config := bot.Loyalty.Config()
2021-05-18 13:29:21 +00:00
2021-05-18 13:50:58 +00:00
// Check if user can afford the reward
if balance-reward.Price < 0 {
bot.Client.Say(message.Channel, fmt.Sprintf("I'm sorry %s but you cannot afford this (have %d %s, need %d)", message.User.DisplayName, balance, config.Currency, reward.Price))
return
}
2021-05-18 13:50:58 +00:00
text := ""
if len(parts) > 2 {
text = strings.Join(parts[2:], " ")
}
2021-05-18 13:50:58 +00:00
// Perform redeem
if err := bot.Loyalty.PerformRedeem(loyalty.Redeem{
Username: message.User.Name,
DisplayName: message.User.DisplayName,
When: time.Now(),
Reward: reward,
RequestText: text,
}); err != nil {
2021-07-11 13:34:39 +00:00
switch err {
case loyalty.ErrRedeemInCooldown:
nextAvailable := bot.Loyalty.GetRewardCooldown(reward.ID)
bot.Client.Say(message.Channel, fmt.Sprintf("%s: That reward is in cooldown (available in %s)", message.User.DisplayName,
time.Until(nextAvailable).Truncate(time.Second)))
default:
bot.logger.WithError(err).Error("error while performing redeem")
}
return
}
2021-05-18 13:50:58 +00:00
bot.Client.Say(message.Channel, fmt.Sprintf("HolidayPresent %s has redeemed %s! (new balance: %d %s)", message.User.DisplayName, reward.Name, bot.Loyalty.GetPoints(message.User.Name), config.Currency))
}
func cmdGoalList(bot *Bot, message irc.PrivateMessage) {
goals := bot.Loyalty.Goals()
if len(goals) < 1 {
bot.Client.Say(message.Channel, fmt.Sprintf("%s: There are no active community goals right now :(!", message.User.DisplayName))
return
}
msg := "Current goals: "
for _, goal := range goals {
if !goal.Enabled {
continue
}
msg += fmt.Sprintf("%s (%d/%d %s) [id: %s] | ", goal.Name, goal.Contributed, goal.TotalGoal, bot.Loyalty.Config().Currency, goal.ID)
}
msg += " Contribute with <!contribute POINTS GOALID>"
bot.Client.Say(message.Channel, msg)
}
func cmdContributeGoal(bot *Bot, message irc.PrivateMessage) {
goals := bot.Loyalty.Goals()
// Set defaults if user doesn't provide them
points := int64(100)
goalIndex := -1
hasGoals := false
// Get first unreached goal for default
for index, goal := range goals {
if !goal.Enabled {
continue
}
hasGoals = true
if goal.Contributed < goal.TotalGoal {
goalIndex = index
break
2021-05-02 12:29:43 +00:00
}
}
2021-05-02 12:29:43 +00:00
// Do we not have any goal we can contribute to? Hooray I guess?
if goalIndex < 0 {
if hasGoals {
bot.Client.Say(message.Channel, fmt.Sprintf("%s: All active community goals have been reached already! ShowOfHands", message.User.DisplayName))
} else {
bot.Client.Say(message.Channel, fmt.Sprintf("%s: There are no active community goals right now :(!", message.User.DisplayName))
}
return
}
// Parse parameters if provided
parts := strings.Fields(message.Message)
if len(parts) > 1 {
newpoints, err := strconv.ParseInt(parts[1], 10, 64)
if err == nil {
if newpoints <= 0 {
bot.Client.Say(message.Channel, fmt.Sprintf("Nice try %s SoBayed", message.User.DisplayName))
return
}
points = newpoints
}
if len(parts) > 2 {
found := false
goalID := parts[2]
// Find Goal index
for index, goal := range goals {
if !goal.Enabled {
continue
}
if goal.ID == goalID {
goalIndex = index
found = true
break
}
}
// Invalid goal ID provided
if !found {
bot.Client.Say(message.Channel, fmt.Sprintf("%s: I couldn't find that goal ID :(", message.User.DisplayName))
return
}
}
}
// Get goal
selectedGoal := goals[goalIndex]
// Check if goal was reached already
if selectedGoal.Contributed >= selectedGoal.TotalGoal {
bot.Client.Say(message.Channel, fmt.Sprintf("%s: This goal was already reached! ヾ(•ω•`)o", message.User.DisplayName))
return
}
// Add points to goal
2021-05-18 13:50:58 +00:00
if err := bot.Loyalty.PerformContribution(selectedGoal, message.User.Name, points); err != nil {
bot.logger.WithError(err).Error("error while contributing to goal")
return
}
config := bot.Loyalty.Config()
newRemaining := selectedGoal.TotalGoal - selectedGoal.Contributed
bot.Client.Say(message.Channel, fmt.Sprintf("ShowOfHands %s contributed %d %s to \"%s\"!! Only %d %s left!", message.User.DisplayName, points, config.Currency, selectedGoal.Name, newRemaining, config.Currency))
// Check if goal was reached!
// TODO Replace this with sub from loyalty system or something?
if newRemaining <= 0 {
bot.Client.Say(message.Channel, fmt.Sprintf("ShowOfHands The community goal \"%s\" was reached! ShowOfHands", selectedGoal.Name))
}
2021-05-02 12:29:43 +00:00
}