mirror of
https://github.com/cjdenio/jia.git
synced 2024-11-21 15:13:40 +00:00
Events system
This commit is contained in:
parent
ad7207c15f
commit
4dec84e9a9
7 changed files with 147 additions and 1 deletions
|
@ -16,6 +16,6 @@ func main() {
|
|||
config := jia.NewConfig()
|
||||
|
||||
// Start receiving messages
|
||||
fmt.Println(fmt.Sprintf("Listening on port %d", config.Port))
|
||||
fmt.Printf("Listening on port %d\n", config.Port)
|
||||
jia.StartServer(config)
|
||||
}
|
||||
|
|
6
events.yaml
Normal file
6
events.yaml
Normal file
|
@ -0,0 +1,6 @@
|
|||
- name: Test Event
|
||||
start: 8:00 May 2, 2021 EDT
|
||||
end: 7:59 May 3, 2021 EDT
|
||||
- name: May Counting
|
||||
start: 8:00 May 3, 2021 EDT
|
||||
end: 20:00 May 31, 2021 EDT
|
1
go.mod
1
go.mod
|
@ -7,4 +7,5 @@ require (
|
|||
github.com/joho/godotenv v1.3.0
|
||||
github.com/pkg/errors v0.9.1 // indirect
|
||||
github.com/slack-go/slack v0.6.5
|
||||
gopkg.in/yaml.v2 v2.4.0 // indirect
|
||||
)
|
||||
|
|
3
go.sum
3
go.sum
|
@ -18,3 +18,6 @@ github.com/slack-go/slack v0.6.4/go.mod h1:sGRjv3w+ERAUMMMbldHObQPBcNSyVB7KLKYfn
|
|||
github.com/slack-go/slack v0.6.5 h1:IkDKtJ2IROJNoe3d6mW870/NRKvq2fhLB/Q5XmzWk00=
|
||||
github.com/slack-go/slack v0.6.5/go.mod h1:FGqNzJBmxIsZURAxh2a8D21AnOVvvXZvGligs4npPUM=
|
||||
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY=
|
||||
gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=
|
||||
|
|
|
@ -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…
Reference in a new issue