Add twitchat module and dup finder handler
This commit is contained in:
parent
5352ef8434
commit
601747352a
8 changed files with 152 additions and 4 deletions
|
@ -1,5 +1,10 @@
|
||||||
# Changelog
|
# Changelog
|
||||||
|
|
||||||
|
## 4.0.0 - 2019-06-23
|
||||||
|
### Added
|
||||||
|
- Twitch chat module
|
||||||
|
- Twitch chat handler that calculates duplicates in chat
|
||||||
|
|
||||||
## 3.0.2 - 2019-06-03
|
## 3.0.2 - 2019-06-03
|
||||||
### Added
|
### Added
|
||||||
- Command !subhistory
|
- Command !subhistory
|
||||||
|
|
1
go.mod
1
go.mod
|
@ -2,6 +2,7 @@ module galched-bot
|
||||||
|
|
||||||
require (
|
require (
|
||||||
github.com/bwmarrin/discordgo v0.19.0
|
github.com/bwmarrin/discordgo v0.19.0
|
||||||
|
github.com/gempir/go-twitch-irc v1.1.0
|
||||||
github.com/pkg/errors v0.8.1
|
github.com/pkg/errors v0.8.1
|
||||||
github.com/stretchr/testify v1.3.0 // indirect
|
github.com/stretchr/testify v1.3.0 // indirect
|
||||||
go.uber.org/atomic v1.3.2 // indirect
|
go.uber.org/atomic v1.3.2 // indirect
|
||||||
|
|
2
go.sum
2
go.sum
|
@ -2,6 +2,8 @@ github.com/bwmarrin/discordgo v0.19.0 h1:kMED/DB0NR1QhRcalb85w0Cu3Ep2OrGAqZH1R5a
|
||||||
github.com/bwmarrin/discordgo v0.19.0/go.mod h1:O9S4p+ofTFwB02em7jkpkV8M3R0/PUVOwN61zSZ0r4Q=
|
github.com/bwmarrin/discordgo v0.19.0/go.mod h1:O9S4p+ofTFwB02em7jkpkV8M3R0/PUVOwN61zSZ0r4Q=
|
||||||
github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8=
|
github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8=
|
||||||
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||||
|
github.com/gempir/go-twitch-irc v1.1.0 h1:Q9gQGI/3yJzYwlYDlFsGJzWfpaqubMExfmBXNpOC6W0=
|
||||||
|
github.com/gempir/go-twitch-irc v1.1.0/go.mod h1:Pc661rsUSmkQXvI9W2bNyLt4ZrMAgHZPnVwMQEJ0fdo=
|
||||||
github.com/gorilla/websocket v1.4.0 h1:WDFjx/TMzVgy9VdMMQi2K2Emtwi2QcUQsztZ/zLaH/Q=
|
github.com/gorilla/websocket v1.4.0 h1:WDFjx/TMzVgy9VdMMQi2K2Emtwi2QcUQsztZ/zLaH/Q=
|
||||||
github.com/gorilla/websocket v1.4.0/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ=
|
github.com/gorilla/websocket v1.4.0/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ=
|
||||||
github.com/pkg/errors v0.8.1 h1:iURUrRGxPUNPdy5/HRSm+Yj6okJ6UtLINN0Q9M4+h3I=
|
github.com/pkg/errors v0.8.1 h1:iURUrRGxPUNPdy5/HRSm+Yj6okJ6UtLINN0Q9M4+h3I=
|
||||||
|
|
20
main.go
20
main.go
|
@ -8,6 +8,7 @@ import (
|
||||||
"galched-bot/modules/grace"
|
"galched-bot/modules/grace"
|
||||||
"galched-bot/modules/settings"
|
"galched-bot/modules/settings"
|
||||||
"galched-bot/modules/subday"
|
"galched-bot/modules/subday"
|
||||||
|
"galched-bot/modules/twitchat"
|
||||||
|
|
||||||
"go.uber.org/fx"
|
"go.uber.org/fx"
|
||||||
)
|
)
|
||||||
|
@ -21,6 +22,7 @@ type (
|
||||||
Context context.Context
|
Context context.Context
|
||||||
Discord *discord.Discord
|
Discord *discord.Discord
|
||||||
Settings *settings.Settings
|
Settings *settings.Settings
|
||||||
|
Chat *twitchat.TwitchIRC
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -35,14 +37,26 @@ func start(p appParam) error {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Print("discord: cannot start instance", err)
|
log.Print("discord: cannot start instance", err)
|
||||||
return err
|
return err
|
||||||
|
|
||||||
}
|
}
|
||||||
log.Printf("main: discord instance running")
|
log.Printf("main: discord instance running")
|
||||||
log.Printf("main: — — —")
|
|
||||||
|
|
||||||
|
err = p.Chat.Start()
|
||||||
|
if err != nil {
|
||||||
|
log.Print("chat: cannot start instance", err)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
log.Printf("main: twitch chat instance running")
|
||||||
|
|
||||||
|
log.Printf("main: — — —")
|
||||||
<-p.Context.Done()
|
<-p.Context.Done()
|
||||||
log.Print("main: stopping galched-bot")
|
log.Print("main: stopping galched-bot")
|
||||||
|
|
||||||
|
err = p.Chat.Stop()
|
||||||
|
if err != nil {
|
||||||
|
log.Print("chat: cannot stop instance", err)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
err = p.Discord.Stop()
|
err = p.Discord.Stop()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Print("discord: cannot stop instance", err)
|
log.Print("discord: cannot stop instance", err)
|
||||||
|
@ -57,7 +71,7 @@ func main() {
|
||||||
var err error
|
var err error
|
||||||
app := fx.New(
|
app := fx.New(
|
||||||
fx.Logger(new(silentPrinter)),
|
fx.Logger(new(silentPrinter)),
|
||||||
fx.Provide(settings.New, grace.New, discord.New, subday.New),
|
fx.Provide(settings.New, grace.New, discord.New, subday.New, twitchat.New),
|
||||||
fx.Invoke(start))
|
fx.Invoke(start))
|
||||||
|
|
||||||
err = app.Start(context.Background())
|
err = app.Start(context.Background())
|
||||||
|
|
|
@ -6,8 +6,11 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
version = "3.0.2"
|
version = "4.0.0"
|
||||||
|
twitchUser = "galchedbot"
|
||||||
|
twitchIRCRoom = "galched"
|
||||||
discordTokenPath = "./tokens/.discordtoken"
|
discordTokenPath = "./tokens/.discordtoken"
|
||||||
|
twitchTokenPath = "./tokens/.twitchtoken"
|
||||||
subdayDataPath = "./backups/subday"
|
subdayDataPath = "./backups/subday"
|
||||||
|
|
||||||
// Permitted roles in discord for subday
|
// Permitted roles in discord for subday
|
||||||
|
@ -21,6 +24,9 @@ type (
|
||||||
Settings struct {
|
Settings struct {
|
||||||
Version string
|
Version string
|
||||||
DiscordToken string
|
DiscordToken string
|
||||||
|
TwitchUser string
|
||||||
|
TwitchIRCRoom string
|
||||||
|
TwitchToken string
|
||||||
SubdayDataPath string
|
SubdayDataPath string
|
||||||
PermittedRoles []string
|
PermittedRoles []string
|
||||||
}
|
}
|
||||||
|
@ -31,10 +37,17 @@ func New() (*Settings, error) {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Print("settings: cannot read discord token file", err)
|
log.Print("settings: cannot read discord token file", err)
|
||||||
}
|
}
|
||||||
|
twitchToken, err := ioutil.ReadFile(twitchTokenPath)
|
||||||
|
if err != nil {
|
||||||
|
log.Print("settings: cannot read twitch token file", err)
|
||||||
|
}
|
||||||
|
|
||||||
return &Settings{
|
return &Settings{
|
||||||
Version: version,
|
Version: version,
|
||||||
DiscordToken: string(discordToken),
|
DiscordToken: string(discordToken),
|
||||||
|
TwitchToken: string(twitchToken),
|
||||||
|
TwitchUser: twitchUser,
|
||||||
|
TwitchIRCRoom: twitchIRCRoom,
|
||||||
SubdayDataPath: subdayDataPath,
|
SubdayDataPath: subdayDataPath,
|
||||||
PermittedRoles: []string{subRole1, subRole2, galchedRole, smorcRole},
|
PermittedRoles: []string{subRole1, subRole2, galchedRole, smorcRole},
|
||||||
}, nil
|
}, nil
|
||||||
|
|
48
modules/twitchat/duphandler.go
Normal file
48
modules/twitchat/duphandler.go
Normal file
|
@ -0,0 +1,48 @@
|
||||||
|
package twitchat
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"log"
|
||||||
|
"strings"
|
||||||
|
|
||||||
|
"github.com/gempir/go-twitch-irc"
|
||||||
|
)
|
||||||
|
|
||||||
|
type (
|
||||||
|
dupHandler struct {
|
||||||
|
lastMessage string
|
||||||
|
counter int
|
||||||
|
dupMinimal int
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
const DupMinimal = 3
|
||||||
|
|
||||||
|
func DupHandler() MessageHandler {
|
||||||
|
return &dupHandler{
|
||||||
|
lastMessage: "",
|
||||||
|
counter: 0,
|
||||||
|
dupMinimal: DupMinimal,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (h *dupHandler) IsValid(m string) bool {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
func (h *dupHandler) Handle(ch string, u *twitch.User, m *twitch.Message, client *twitch.Client) {
|
||||||
|
data := strings.Fields(m.Text)
|
||||||
|
for i := range data {
|
||||||
|
if data[i] == h.lastMessage {
|
||||||
|
h.counter++
|
||||||
|
} else {
|
||||||
|
if h.counter >= h.dupMinimal {
|
||||||
|
msg := fmt.Sprintf("%d %s подряд", h.counter, h.lastMessage)
|
||||||
|
client.Say(ch, msg)
|
||||||
|
log.Print("chat: ", msg)
|
||||||
|
}
|
||||||
|
h.counter = 1
|
||||||
|
h.lastMessage = data[i]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
12
modules/twitchat/handlers.go
Normal file
12
modules/twitchat/handlers.go
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
package twitchat
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/gempir/go-twitch-irc"
|
||||||
|
)
|
||||||
|
|
||||||
|
type (
|
||||||
|
MessageHandler interface {
|
||||||
|
IsValid(string) bool
|
||||||
|
Handle(ch string, u *twitch.User, m *twitch.Message, client *twitch.Client)
|
||||||
|
}
|
||||||
|
)
|
53
modules/twitchat/twitchat.go
Normal file
53
modules/twitchat/twitchat.go
Normal file
|
@ -0,0 +1,53 @@
|
||||||
|
package twitchat
|
||||||
|
|
||||||
|
import (
|
||||||
|
"galched-bot/modules/settings"
|
||||||
|
|
||||||
|
"github.com/gempir/go-twitch-irc"
|
||||||
|
_ "github.com/gempir/go-twitch-irc"
|
||||||
|
)
|
||||||
|
|
||||||
|
type (
|
||||||
|
TwitchIRC struct {
|
||||||
|
username string
|
||||||
|
chat *twitch.Client
|
||||||
|
handlers []MessageHandler
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
func New(s *settings.Settings) (*TwitchIRC, error) {
|
||||||
|
var irc = new(TwitchIRC)
|
||||||
|
|
||||||
|
irc.username = s.TwitchUser
|
||||||
|
|
||||||
|
irc.handlers = append(irc.handlers, DupHandler())
|
||||||
|
|
||||||
|
irc.chat = twitch.NewClient(s.TwitchUser, s.TwitchToken)
|
||||||
|
irc.chat.OnNewMessage(irc.MessageHandler)
|
||||||
|
irc.chat.Join(s.TwitchIRCRoom)
|
||||||
|
|
||||||
|
return irc, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *TwitchIRC) Start() error {
|
||||||
|
go func() {
|
||||||
|
err := c.chat.Connect()
|
||||||
|
_ = err // no point in error because disconnect will be called anyway
|
||||||
|
}()
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *TwitchIRC) Stop() error {
|
||||||
|
return c.chat.Disconnect()
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *TwitchIRC) MessageHandler(ch string, u twitch.User, m twitch.Message) {
|
||||||
|
if u.Username == c.username {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
for i := range c.handlers {
|
||||||
|
if c.handlers[i].IsValid(m.Text) {
|
||||||
|
c.handlers[i].Handle(ch, &u, &m, c.chat)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in a new issue