Skip to content

Commit

Permalink
added twitch draw command
Browse files Browse the repository at this point in the history
  • Loading branch information
Kesuaheli committed Jan 1, 2024
1 parent 5834504 commit 2619e1e
Show file tree
Hide file tree
Showing 6 changed files with 83 additions and 3 deletions.
2 changes: 2 additions & 0 deletions config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,8 @@ event:
twitch_giveaway:
# The amount of points a single giveaway ticket costs.
ticket_cost: 1000
# the filepath for of the json giveaway prizes
prizes: twitch/prizes.json

webserver:
favicon: webserver/favicon.png
Expand Down
7 changes: 6 additions & 1 deletion data/lang/de.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -147,4 +147,9 @@ twitch.command:

join:
msg.too_few_points: "@%s du nicht genügend Punkte(%d)! Du brauchst noch %d mehr um den Preis von %d zu bezahlen."
msg.success: "@%s Du hast dir erfolgreich ein Ticket für %d Punkte gekauft. Du hast nun %d Tickets und noch %d Punkte über."
msg.success: "@%s du hast dir erfolgreich ein Ticket für %d Punkte gekauft. Du hast nun %d Tickets und noch %d Punkte über."

draw:
msg.no_prizes: "@%s es gibt momentan keine Preise zu gewinnen. Du kannst diesen Befehl momentan nicht ausführen."
msg.no_entries: "@%s es gibt momentan keine Einträge und somit kann kein Gewinner gezogen werden."
msg.winner: Glückwunsch! @%s hat %s gewonnen. Du hattest %d/10 Tickets und eine Gewinnchance von %.2f%%.
7 changes: 6 additions & 1 deletion data/lang/en.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -147,4 +147,9 @@ twitch.command:

join:
msg.too_few_points: "@%s you don't have enough points (%d)! You need %d more to pay the costs of %d points."
msg.success: "@%s You successfully bought a ticket for %d points. Now you have %d tickets and still %d points."
msg.success: "@%s you successfully bought a ticket for %d points. Now you have %d tickets and still %d points."

draw:
msg.no_prizes: "@%s There're currently no prizes available. You can't perfrom this command now."
msg.no_entries: "@%s There're currently no entries and therefore no winner can be drawn."
msg.winner: Congratulations! @%s won %s. You had %d/10 tickets and a win probability of %.2f%%.
18 changes: 18 additions & 0 deletions database/giveaway.go
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,19 @@ func GetGiveawayEntry(prefix, userID string) GiveawayEntry {
return GiveawayEntry{userID, weight, lastEntry}
}

// DeleteGiveawayEntry deletes the giveaway entry for the given user identifier from the database.
//
// If an error occours it will be returned. However if no datbase entry matched it returns err ==
// nil, not err == sql.ErrNoRows. Because sql.ErrNoRows also results in the non-existence of the
// requested row and therefore is treated as a successful call.
func DeleteGiveawayEntry(userID string) error {
_, err := Exec("DELETE FROM giveaway WHERE id=?", userID)
if err == sql.ErrNoRows {
return nil
}
return err
}

// AddGiveawayWeight adds amount to the given user identifier.
//
// However if their last entry wasn't prefixed with prefix, their weight will be resetted and starts
Expand Down Expand Up @@ -182,6 +195,11 @@ func GetAllGiveawayEntries(prefix string) []GiveawayEntry {
// DrawGiveawayWinner takes one of the given entries and draw one winner of them. The probability
// is based on their Weight value. A higher Weight means a higher probability.
func DrawGiveawayWinner(e []GiveawayEntry) (winner GiveawayEntry, totalTickets int) {
// skip randomizing when there is only one entry
if len(e) == 1 {
return e[0], e[0].Weight
}

var entries []GiveawayEntry
for _, e := range e {
for i := 0; i < e.Weight; i++ {
Expand Down
1 change: 1 addition & 0 deletions main.go
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,7 @@ func main() {

client := twitchgo.New(viper.GetString("twitch.name"), viper.GetString("twitch.token"))
client.OnChannelCommandMessage("join", twitch.HandleCmdJoin)
client.OnChannelCommandMessage("draw", twitch.HandleCmdDraw)
client.OnChannelMessage(twitch.MessageHandler)
err = client.Connect()
if err != nil {
Expand Down
51 changes: 50 additions & 1 deletion twitch/messageHandler.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ import (
"github.com/spf13/viper"
)

const tp string = "twitch.command.join."
const tp string = "twitch.command."

var log logger.Logger = *logger.New(logger.Writer(), "[Twitch] ", logger.LstdFlags|logger.Lmsgprefix)
var se *streamelements.Streamelements
Expand All @@ -40,6 +40,8 @@ func MessageHandler(t *twitchgo.Twitch, channel string, user *twitchgo.User, mes
// and removes the configured cost amount for a ticket.
func HandleCmdJoin(t *twitchgo.Twitch, channel string, user *twitchgo.User, args []string) {
channel, _ = strings.CutPrefix(channel, "#")
const tp = tp + "join."

log.Printf("[%s@%s] executed join command with %d args: %v", user.Nickname, channel, len(args), args)
seChannel, err := se.GetChannel(channel)
if err != nil {
Expand Down Expand Up @@ -73,3 +75,50 @@ func HandleCmdJoin(t *twitchgo.Twitch, channel string, user *twitchgo.User, args
}
t.SendMessagef(channel, lang.GetDefault(tp+"msg.success"), user.Nickname, joinCost, entry.Weight, sePoints.Points-joinCost)
}

// HandleCmdDraw is the handler for the draw command in a twitch chat. This handler selects a random
// winner and removes their tickets.
func HandleCmdDraw(t *twitchgo.Twitch, channel string, user *twitchgo.User, args []string) {
channel, _ = strings.CutPrefix(channel, "#")
const tp = tp + "draw."

//only accept broadcaster
if channel != user.Nickname {
return
}

p, err := database.NewGiveawayPrize(viper.GetString("event.twitch_giveaway.prizes"))
if err != nil {
log.Printf("Error reading prizes file: %v", err)
t.SendMessagef(channel, lang.GetDefault("twitch.command.generic.error"))
return
}
prize, ok := p.GetNextPrize()
if !ok {
t.SendMessagef(channel, lang.GetDefault(tp+"msg.no_prizes"), user.Nickname)
return
}

winner, totalTickets := database.DrawGiveawayWinner(database.GetAllGiveawayEntries("tw11"))
if totalTickets == 0 {
t.SendMessagef(channel, lang.GetDefault(tp+"msg.no_entries"), user.Nickname)
return
}

t.SendMessagef(channel, lang.GetDefault(tp+"msg.winner"), winner.UserID, prize.Name, winner.Weight, float64(winner.Weight*100)/float64(totalTickets))

err = database.DeleteGiveawayEntry(winner.UserID)
if err != nil {
log.Printf("Error deleting database giveaway entry: %v", err)
t.SendMessagef(channel, lang.GetDefault("twitch.command.generic.error"))
return
}

prize.Winner = winner.UserID
err = p.SaveFile()
if err != nil {
log.Printf("Error saving prizes file: %v", err)
t.SendMessagef(channel, lang.GetDefault("twitch.command.generic.error"))
return
}
}

0 comments on commit 2619e1e

Please sign in to comment.