catbase/plugins/twitch/bridge.go

143 lines
3.7 KiB
Go
Raw Permalink Normal View History

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")
}
}