Move stuff out of main package (wip)

This commit is contained in:
Victor Truong 2020-07-27 02:41:00 -07:00
parent 558803a0de
commit dbb0a90706
6 changed files with 109 additions and 65 deletions

View file

@ -2,13 +2,9 @@ package main
import ( import (
"fmt" "fmt"
"log"
"regexp"
"strconv"
"github.com/ifvictr/jia/pkg/jia" "github.com/ifvictr/jia/pkg/jia"
"github.com/joho/godotenv" "github.com/joho/godotenv"
"github.com/slack-go/slack"
) )
func init() { func init() {
@ -19,60 +15,7 @@ func main() {
fmt.Println("Starting Jia…") fmt.Println("Starting Jia…")
config := jia.NewConfig() config := jia.NewConfig()
api := slack.New(config.BotToken) // Start receiving messages
rtm := api.NewRTM() fmt.Println(fmt.Sprintf("Listening on port %d", config.Port))
jia.StartServer(config)
lastValidNumber := 0
var lastSender string
go rtm.ManageConnection()
for event := range rtm.IncomingEvents {
switch ev := event.Data.(type) {
case *slack.MessageEvent:
// Ignore messages that aren't in the target channel, or are non-user messages
if ev.Channel != config.ChannelId || ev.User == "USLACKBOT" || ev.User == "" {
continue
}
// Attempt to extract a positive number from the beginning of a string
countPattern := regexp.MustCompile(`^\d+`)
matchedNumber, err := strconv.Atoi(countPattern.FindString(ev.Text))
log.Println(matchedNumber)
// Ignore messages that don't have numbers
if err != nil {
log.Println("Failed to retrieve number, skipping…")
continue
}
// Reject if sender also sent the previous message
if ev.User == lastSender {
api.AddReaction("bangbang", slack.ItemRef{
Channel: ev.Channel,
Timestamp: ev.Timestamp,
})
api.PostEphemeral(ev.Channel, ev.User, slack.MsgOptionText("You counted consecutively! Thats not allowed.", false))
continue
}
// Ignore numbers that aren't in order
if matchedNumber != lastValidNumber+1 {
api.AddReaction("bangbang", slack.ItemRef{
Channel: ev.Channel,
Timestamp: ev.Timestamp,
})
api.PostEphemeral(ev.Channel, ev.User, slack.MsgOptionText("You counted incorrectly! The next valid number is "+strconv.Itoa(lastValidNumber+1), false))
continue
}
// Finally!
lastValidNumber = matchedNumber
lastSender = ev.User
api.AddReaction("+1", slack.ItemRef{
Channel: ev.Channel,
Timestamp: ev.Timestamp,
})
}
}
} }

2
go.mod
View file

@ -3,7 +3,7 @@ module github.com/ifvictr/jia
go 1.14 go 1.14
require ( require (
github.com/gorilla/websocket v1.4.2 // indirect github.com/go-redis/redis v6.15.8+incompatible
github.com/joho/godotenv v1.3.0 github.com/joho/godotenv v1.3.0
github.com/pkg/errors v0.9.1 // indirect github.com/pkg/errors v0.9.1 // indirect
github.com/slack-go/slack v0.6.5 github.com/slack-go/slack v0.6.5

2
go.sum
View file

@ -1,4 +1,6 @@
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/go-redis/redis v6.15.8+incompatible h1:BKZuG6mCnRj5AOaWJXoCgf6rqTYnYJLe4en2hxT7r9o=
github.com/go-redis/redis v6.15.8+incompatible/go.mod h1:NAIEuMOZ/fxfXJIrKDQDz8wamY7mA7PouImQ2Jvg6kA=
github.com/go-test/deep v1.0.4/go.mod h1:wGDj63lr65AM2AQyKZd/NYHGb0R+1RLqB8NKt3aSFNA= github.com/go-test/deep v1.0.4/go.mod h1:wGDj63lr65AM2AQyKZd/NYHGb0R+1RLqB8NKt3aSFNA=
github.com/gorilla/websocket v1.2.0 h1:VJtLvh6VQym50czpZzx07z/kw9EgAxI3x1ZB8taTMQQ= github.com/gorilla/websocket v1.2.0 h1:VJtLvh6VQym50czpZzx07z/kw9EgAxI3x1ZB8taTMQQ=
github.com/gorilla/websocket v1.2.0/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ= github.com/gorilla/websocket v1.2.0/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ=

View file

@ -2,17 +2,24 @@ package jia
import ( import (
"os" "os"
"strconv"
) )
type Config struct { type Config struct {
BotToken string BotToken string
ChannelId string ChannelID string
Port int
RedisURL string
VerificationToken string
} }
func NewConfig() *Config { func NewConfig() *Config {
return &Config{ return &Config{
BotToken: getEnv("SLACK_CLIENT_BOT_TOKEN", ""), BotToken: getEnv("SLACK_CLIENT_BOT_TOKEN", ""),
ChannelId: getEnv("SLACK_CHANNEL_ID", ""), ChannelID: getEnv("SLACK_CHANNEL_ID", ""),
Port: getEnvAsInt("PORT", 3000),
RedisURL: getEnv("REDIS_URL", "redis://localhost:6379/0"),
VerificationToken: getEnv("SLACK_VERIFICATION_TOKEN", ""),
} }
} }
@ -24,3 +31,12 @@ func getEnv(key string, defaultValue string) string {
return defaultValue return defaultValue
} }
func getEnvAsInt(key string, defaultValue int) int {
valueStr := getEnv(key, "")
if value, err := strconv.Atoi(valueStr); err == nil {
return value
}
return defaultValue
}

17
pkg/jia/handlers.go Normal file
View file

@ -0,0 +1,17 @@
package jia
import (
"github.com/slack-go/slack"
"github.com/slack-go/slack/slackevents"
)
func HandleInnerEvent(slackClient *slack.Client, innerEvent *slackevents.EventsAPIInnerEvent) {
switch e := innerEvent.Data.(type) {
case *slackevents.MessageEvent:
onMessage(slackClient, e)
break
}
}
func onMessage(slackClient *slack.Client, event *slackevents.MessageEvent) {
}

66
pkg/jia/server.go Normal file
View file

@ -0,0 +1,66 @@
package jia
import (
"bytes"
"encoding/json"
"fmt"
"net/http"
"github.com/go-redis/redis"
"github.com/slack-go/slack"
"github.com/slack-go/slack/slackevents"
)
var (
jiaConfig *Config
redisClient *redis.Client
slackClient *slack.Client
)
func StartServer(config *Config) {
jiaConfig = config
// Set up Redis connection
options, err := redis.ParseURL(config.RedisURL)
if err != nil {
panic(err)
}
redisClient = redis.NewClient(options)
// Initialize Slack app
slackClient = slack.New(config.BotToken)
// Start receiving events
http.HandleFunc("/slack/events", handleSlackEvents)
http.ListenAndServe(fmt.Sprintf("127.0.0.1:%d", config.Port), nil)
}
func handleSlackEvents(w http.ResponseWriter, r *http.Request) {
// Verify the payload was sent by Slack.
buf := new(bytes.Buffer)
buf.ReadFrom(r.Body)
body := buf.String()
apiEvent, err := slackevents.ParseEvent(json.RawMessage(body),
slackevents.OptionVerifyToken(
&slackevents.TokenComparator{VerificationToken: jiaConfig.VerificationToken}))
if err != nil {
w.WriteHeader(http.StatusInternalServerError)
return
}
// Handle the event that came through
switch apiEvent.Type {
case slackevents.URLVerification:
var r *slackevents.ChallengeResponse
err := json.Unmarshal([]byte(body), &r)
if err != nil {
w.WriteHeader(http.StatusInternalServerError)
}
w.Header().Set("Content-Type", "text")
w.Write([]byte(r.Challenge))
break
case slackevents.CallbackEvent:
HandleInnerEvent(slackClient, &apiEvent.InnerEvent)
break
}
}