TTW_Bot_GO/internal/platforms/twitch.go

146 lines
3.8 KiB
Go

package platforms
import (
"fmt"
"stream-bot/internal/db"
"stream-bot/internal/logger"
"sync"
"strings"
"github.com/gempir/go-twitch-irc/v4"
"stream-bot/internal/twitchapi"
)
type TwitchPlatform struct {
client *twitch.Client
manager *Manager
channel string
botLogin string
connected bool
mu sync.RWMutex
eventSub *TwitchEventSub
twitchAPI *twitchapi.TwitchAPI
}
func NewTwitchPlatform(mgr *Manager) *TwitchPlatform {
return &TwitchPlatform{
manager: mgr,
twitchAPI: twitchapi.New(),
}
}
func (t *TwitchPlatform) GetName() string {
return "twitch"
}
func (t *TwitchPlatform) Connect() error {
tokens, err := db.GetPlatformTokens("twitch")
if err != nil || tokens == nil || tokens.BotToken == "" {
logger.Warn("Twitch bot token not set, skipping connection")
return fmt.Errorf("no bot token")
}
t.botLogin = tokens.BotLogin
if t.botLogin == "" {
t.botLogin = "justinfan123"
}
t.channel = tokens.UserLogin
if t.channel == "" {
logger.Warn("Twitch user login not set, cannot join channel")
return fmt.Errorf("no channel name")
}
t.client = twitch.NewClient(t.botLogin, "oauth:"+tokens.BotToken)
t.client.OnPrivateMessage(func(msg twitch.PrivateMessage) {
// Извлекаем значки
badges := msg.Tags["badges"]
isMod := strings.Contains(badges, "moderator/1")
isVip := strings.Contains(badges, "vip/1")
isSubscriber := strings.Contains(badges, "subscriber/")
isBroadcaster := strings.Contains(badges, "broadcaster/1")
t.manager.OnChatMessage("twitch", msg.Channel, msg.User.Name, msg.Message, isMod, isBroadcaster, isVip, isSubscriber)
})
t.client.Join(t.channel)
go t.client.Connect()
t.mu.Lock()
t.connected = true
t.mu.Unlock()
t.twitchAPI = twitchapi.New()
t.eventSub = NewTwitchEventSub(t.manager, t.twitchAPI)
if err := t.eventSub.Start(); err != nil {
logger.Warn("Failed to start EventSub: %v", err)
}
return nil
}
func (t *TwitchPlatform) Disconnect() {
t.mu.Lock()
defer t.mu.Unlock()
if t.eventSub != nil {
t.eventSub.Stop()
}
if t.client != nil {
t.client.Disconnect()
}
t.connected = false
}
func (t *TwitchPlatform) IsConnected() bool {
t.mu.RLock()
defer t.mu.RUnlock()
return t.connected
}
func (t *TwitchPlatform) SendMessage(text string) error {
if t.client == nil {
return fmt.Errorf("not connected")
}
t.client.Say(t.channel, text)
return nil
}
func (t *TwitchPlatform) TimeoutUser(username string, seconds int) {
t.client.Say(t.channel, fmt.Sprintf("/timeout %s %d", username, seconds))
}
func (t *TwitchPlatform) BanUser(username string) {
t.client.Say(t.channel, fmt.Sprintf("/ban %s", username))
}
func (t *TwitchPlatform) UnbanUser(username string) {
t.client.Say(t.channel, fmt.Sprintf("/unban %s", username))
}
func (t *TwitchPlatform) AddVip(username string) {
t.client.Say(t.channel, fmt.Sprintf("/vip %s", username))
}
func (t *TwitchPlatform) RemoveVip(username string) {
t.client.Say(t.channel, fmt.Sprintf("/unvip %s", username))
}
func (t *TwitchPlatform) AddMod(username string) {
t.client.Say(t.channel, fmt.Sprintf("/mod %s", username))
}
func (t *TwitchPlatform) RemoveMod(username string) {
t.client.Say(t.channel, fmt.Sprintf("/unmod %s", username))
}
func GetClientID() string {
tokens, _ := db.GetPlatformTokens("twitch")
if tokens != nil && tokens.ClientID != "" {
return tokens.ClientID
}
return "0xc6mhgsuxpkvze0gi70ywjno6l2jw"
}
func (t *TwitchPlatform) EventSubStatus() (connected bool, subscriptions []string) {
if t.eventSub == nil {
return false, nil
}
return t.eventSub.IsConnected(), t.eventSub.GetSubscriptions()
}