mirror of https://github.com/velour/catbase.git
143 lines
3.7 KiB
Go
143 lines
3.7 KiB
Go
package twitch
|
|
|
|
import (
|
|
"fmt"
|
|
"github.com/cenkalti/backoff/v4"
|
|
"github.com/rs/zerolog/log"
|
|
"github.com/velour/catbase/bot"
|
|
"github.com/velour/catbase/connectors/discord"
|
|
"strings"
|
|
)
|
|
|
|
func (t *Twitch) mkBridge(r bot.Request) bool {
|
|
ircCh := "#" + r.Values["twitchChannel"]
|
|
if err := t.startConn(); err != nil {
|
|
t.b.Send(r.Conn, bot.Message, r.Msg.Channel, fmt.Sprintf("Could not connect to IRC: %s", err))
|
|
}
|
|
t.irc.Join(ircCh)
|
|
t.bridgeMap[r.Msg.Channel] = ircCh
|
|
t.b.Send(r.Conn, bot.Message, r.Msg.Channel, fmt.Sprintf("This post is tracking %s", ircCh))
|
|
return true
|
|
}
|
|
|
|
func (t *Twitch) rmBridge(r bot.Request) bool {
|
|
ch, ok := t.bridgeMap[r.Msg.Channel]
|
|
if ok {
|
|
delete(t.bridgeMap, r.Msg.Channel)
|
|
t.b.Send(r.Conn, bot.Message, r.Msg.Channel, fmt.Sprintf("No longer tracking %s.", ch))
|
|
return true
|
|
}
|
|
t.b.Send(r.Conn, bot.Message, r.Msg.Channel, "This is not a connected bridge channel.")
|
|
return true
|
|
}
|
|
|
|
func (t *Twitch) bridgeMsg(r bot.Request) bool {
|
|
if ircCh := t.bridgeMap[r.Msg.Channel]; ircCh != "" {
|
|
if t.irc == nil {
|
|
if err := t.startConn(); err != nil {
|
|
t.b.Send(r.Conn, bot.Message, r.Msg.Channel, fmt.Sprintf("Could not connect to IRC: %s", err))
|
|
}
|
|
t.irc.Join(ircCh)
|
|
}
|
|
replaceSet := t.c.Get("twitch.replaceset", "\"'-")
|
|
who := r.Msg.User.Name
|
|
for _, c := range replaceSet {
|
|
who = strings.ReplaceAll(who, string(c), "")
|
|
}
|
|
who = strings.Split(who, " ")[0][:9]
|
|
msg := fmt.Sprintf("%s: %s", who, r.Msg.Body)
|
|
t.irc.sendMessage(ircCh, msg)
|
|
}
|
|
return false
|
|
}
|
|
|
|
func (t *Twitch) ircMsg(channel, who, body string) {
|
|
for thread, ircCh := range t.bridgeMap {
|
|
if ircCh == channel {
|
|
t.b.Send(t.b.DefaultConnector(), bot.Message, thread, fmt.Sprintf("%s: %s", who, body))
|
|
}
|
|
}
|
|
}
|
|
|
|
func (t *Twitch) startBridgeMsg(threadName, twitchChannel, msg string) error {
|
|
if !strings.HasPrefix(twitchChannel, "#") {
|
|
twitchChannel = "#" + twitchChannel
|
|
}
|
|
if err := t.startConn(); err != nil {
|
|
return err
|
|
}
|
|
|
|
chID, err := t.mkForumPost(threadName, msg)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
log.Debug().Msgf("Opened thread %s", chID)
|
|
|
|
err = t.irc.Join(twitchChannel)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
t.bridgeMap[chID] = twitchChannel
|
|
return nil
|
|
}
|
|
|
|
func (t *Twitch) startBridge(threadName, twitchChannel string) error {
|
|
if !strings.HasPrefix(twitchChannel, "#") {
|
|
twitchChannel = "#" + twitchChannel
|
|
}
|
|
msg := fmt.Sprintf("This post is tracking %s", twitchChannel)
|
|
return t.startBridgeMsg(threadName, twitchChannel, msg)
|
|
}
|
|
|
|
func (t *Twitch) startConn() error {
|
|
if t.irc == nil {
|
|
err := backoff.Retry(func() error {
|
|
err := t.connect()
|
|
if err != nil {
|
|
log.Error().Err(err).Msg("could not connect to IRC")
|
|
return err
|
|
}
|
|
return nil
|
|
}, backoff.WithMaxRetries(backoff.NewExponentialBackOff(), 5))
|
|
if err != nil {
|
|
return err
|
|
}
|
|
}
|
|
return nil
|
|
}
|
|
|
|
func (t *Twitch) connect() error {
|
|
t.ircLock.Lock()
|
|
defer t.ircLock.Unlock()
|
|
twitchServer := t.c.Get("twitch.ircserver", "irc.chat.twitch.tv:6697")
|
|
twitchNick := t.c.Get("twitch.nick", "")
|
|
twitchPass := t.c.Get("twitch.pass", "")
|
|
twitchIRC, err := t.ConnectIRC(twitchServer, twitchNick, twitchPass, t.ircMsg, func() {
|
|
t.ircLock.Lock()
|
|
defer t.ircLock.Unlock()
|
|
t.irc = nil
|
|
})
|
|
if err != nil {
|
|
return err
|
|
}
|
|
t.irc = twitchIRC
|
|
return nil
|
|
}
|
|
|
|
func (t *Twitch) mkForumPost(name, msg string) (string, error) {
|
|
forum := t.c.Get("twitch.forum", "")
|
|
if forum == "" {
|
|
return "", fmt.Errorf("no forum available")
|
|
}
|
|
switch c := t.b.DefaultConnector().(type) {
|
|
case *discord.Discord:
|
|
chID, err := c.CreateRoom(name, msg, forum, t.c.GetInt("twitch.threadduration", 60))
|
|
if err != nil {
|
|
return "", err
|
|
}
|
|
return chID, nil
|
|
default:
|
|
return "", fmt.Errorf("non-Discord connectors not supported")
|
|
}
|
|
}
|