mirror of
https://github.com/cjdenio/jia.git
synced 2024-11-22 07:33:39 +00:00
Move stuff out of main package (wip)
This commit is contained in:
parent
558803a0de
commit
dbb0a90706
6 changed files with 109 additions and 65 deletions
63
cmd/jia.go
63
cmd/jia.go
|
@ -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! That’s 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
2
go.mod
|
@ -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
2
go.sum
|
@ -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=
|
||||||
|
|
|
@ -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
17
pkg/jia/handlers.go
Normal 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
66
pkg/jia/server.go
Normal 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
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in a new issue