mirror of
https://github.com/cjdenio/jia.git
synced 2025-05-14 17:33:05 +00:00
Events system
This commit is contained in:
parent
ad7207c15f
commit
4dec84e9a9
7 changed files with 147 additions and 1 deletions
|
@ -3,23 +3,67 @@ package jia
|
|||
import (
|
||||
"os"
|
||||
"strconv"
|
||||
"time"
|
||||
|
||||
"gopkg.in/yaml.v2"
|
||||
)
|
||||
|
||||
type Event struct {
|
||||
Name string `yaml:"name"`
|
||||
StartTime time.Time
|
||||
EndTime time.Time
|
||||
|
||||
StartString string `yaml:"start"`
|
||||
EndString string `yaml:"end"`
|
||||
}
|
||||
|
||||
type Config struct {
|
||||
BotToken string
|
||||
ChannelID string
|
||||
Port int
|
||||
RedisURL string
|
||||
VerificationToken string
|
||||
|
||||
Events []Event
|
||||
}
|
||||
|
||||
func (c Config) GetRunningEvents() []Event {
|
||||
var running_events []Event
|
||||
|
||||
for _, event := range c.Events {
|
||||
if time.Since(event.StartTime) > 0 && time.Until(event.EndTime) > 0 {
|
||||
running_events = append(running_events, event)
|
||||
}
|
||||
}
|
||||
|
||||
return running_events
|
||||
}
|
||||
|
||||
func NewConfig() *Config {
|
||||
events_file, err := os.ReadFile("events.yaml")
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
var events []Event
|
||||
|
||||
err = yaml.Unmarshal(events_file, &events)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
for i, event := range events {
|
||||
events[i].StartTime, _ = time.Parse("15:04 Jan 2, 2006 MST", event.StartString)
|
||||
events[i].EndTime, _ = time.Parse("15:04 Jan 2, 2006 MST", event.EndString)
|
||||
}
|
||||
|
||||
return &Config{
|
||||
BotToken: getEnv("SLACK_BOT_TOKEN", ""),
|
||||
ChannelID: getEnv("SLACK_CHANNEL_ID", ""),
|
||||
Port: getEnvAsInt("PORT", 3000),
|
||||
RedisURL: getEnv("REDIS_URL", "redis://localhost:6379/0"),
|
||||
VerificationToken: getEnv("SLACK_VERIFICATION_TOKEN", ""),
|
||||
Events: events,
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -94,6 +94,11 @@ func onMessage(slackClient *slack.Client, event *slackevents.MessageEvent) {
|
|||
|
||||
// Increment the person's monthly count
|
||||
redisClient.Incr(fmt.Sprintf("leaderboard:%d-%d:%s", year, month, event.User))
|
||||
|
||||
// Increment the person's count for any running events
|
||||
for _, counting_event := range jiaConfig.GetRunningEvents() {
|
||||
redisClient.Incr(fmt.Sprintf("event:%s:%s", counting_event.Name, event.User))
|
||||
}
|
||||
}
|
||||
|
||||
func HandleLeaderboardSlashCommand(w http.ResponseWriter, r *http.Request) {
|
||||
|
@ -171,6 +176,76 @@ func HandleLeaderboardSlashCommand(w http.ResponseWriter, r *http.Request) {
|
|||
w.Write(resp)
|
||||
}
|
||||
|
||||
func HandleEventsSlashCommand(w http.ResponseWriter, r *http.Request) {
|
||||
events := jiaConfig.GetRunningEvents()
|
||||
|
||||
var blocks []slack.Block
|
||||
|
||||
if len(events) == 0 {
|
||||
blocks = append(blocks, slack.NewSectionBlock(slack.NewTextBlockObject("mrkdwn", "There aren't any counting events running right now.", false, false), nil, nil))
|
||||
} else if len(events) == 1 {
|
||||
blocks = append(blocks, slack.NewSectionBlock(slack.NewTextBlockObject("mrkdwn", fmt.Sprintf(":calendar: Counting stats for event *%s*:", events[0].Name), false, false), nil, nil))
|
||||
|
||||
scan := redisClient.Scan(0, fmt.Sprintf("event:%s:*", events[0].Name), 10)
|
||||
scanIterator := scan.Iterator()
|
||||
|
||||
type Entry struct {
|
||||
Number int
|
||||
User string
|
||||
}
|
||||
|
||||
entries := []Entry{}
|
||||
|
||||
for scanIterator.Next() {
|
||||
entry := redisClient.Get(scanIterator.Val())
|
||||
entryInt, err := entry.Int()
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
if _, user, ok := parseEventEntry(scanIterator.Val()); ok {
|
||||
entries = append(entries, Entry{
|
||||
Number: entryInt,
|
||||
User: user,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
// Sort entries
|
||||
sort.Slice(entries, func(i, j int) bool {
|
||||
return entries[i].Number > entries[j].Number
|
||||
})
|
||||
|
||||
for i, v := range entries {
|
||||
emoji := ""
|
||||
if i == 0 {
|
||||
emoji = ":first_place_medal:"
|
||||
} else if i == 1 {
|
||||
emoji = ":second_place_medal:"
|
||||
} else if i == 2 {
|
||||
emoji = ":third_place_medal:"
|
||||
}
|
||||
|
||||
blocks = append(blocks, slack.NewSectionBlock(slack.NewTextBlockObject("mrkdwn", fmt.Sprintf("%s <@%s> has counted *%d* so far", emoji, v.User, v.Number), false, false), nil, nil))
|
||||
}
|
||||
|
||||
if len(entries) > 10 {
|
||||
entries = entries[:10]
|
||||
}
|
||||
blocks = append(blocks, slack.NewContextBlock("", slack.NewTextBlockObject("mrkdwn", fmt.Sprintf("Event will end at *<!date^%d^{time} on {date}|some date>*, your time", events[0].EndTime.Unix()), false, false)))
|
||||
} else {
|
||||
blocks = append(blocks, slack.NewSectionBlock(slack.NewTextBlockObject("mrkdwn", "Something went wrong fetching the events leaderboard :cry:", false, false), nil, nil))
|
||||
}
|
||||
|
||||
resp, _ := json.Marshal(map[string]interface{}{
|
||||
"blocks": blocks,
|
||||
"response_type": "ephemeral",
|
||||
})
|
||||
|
||||
w.Header().Add("Content-Type", "application/json")
|
||||
w.Write(resp)
|
||||
}
|
||||
|
||||
func parseLeaderboardEntry(key string) (string, bool) {
|
||||
re := regexp.MustCompile(`leaderboard:\d+-\d+:(\w+)`)
|
||||
|
||||
|
@ -180,3 +255,19 @@ func parseLeaderboardEntry(key string) (string, bool) {
|
|||
}
|
||||
return match[1], true
|
||||
}
|
||||
|
||||
func parseEventEntry(key string) (event_name string, user_id string, ok bool) {
|
||||
re := regexp.MustCompile(`event:(.+):(\w+)`)
|
||||
|
||||
match := re.FindStringSubmatch(key)
|
||||
if match == nil {
|
||||
ok = false
|
||||
return
|
||||
}
|
||||
|
||||
ok = true
|
||||
event_name = match[1]
|
||||
user_id = match[2]
|
||||
|
||||
return
|
||||
}
|
||||
|
|
|
@ -36,6 +36,7 @@ func StartServer(config *Config) {
|
|||
// Start receiving events
|
||||
http.HandleFunc("/slack/events", handleSlackEvents)
|
||||
http.HandleFunc("/slack/leaderboard", HandleLeaderboardSlashCommand)
|
||||
http.HandleFunc("/slack/eventsCommand", HandleEventsSlashCommand)
|
||||
http.ListenAndServe(fmt.Sprintf("0.0.0.0:%d", config.Port), nil)
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue