TTW_Bot_GO/internal/platforms/twitch.go

235 lines
5.9 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

package platforms
import (
"fmt"
"stream-bot/internal/db"
"stream-bot/internal/logger"
"stream-bot/internal/twitchapi"
"strings"
"sync"
"github.com/gempir/go-twitch-irc/v4"
)
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, clientID, clientSecret string) *TwitchPlatform {
twitchAPI := twitchapi.New(clientID, clientSecret)
return &TwitchPlatform{
manager: mgr,
twitchAPI: twitchAPI,
}
}
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 func() {
_ = t.client.Connect()
}()
t.mu.Lock()
t.connected = true
t.mu.Unlock()
// EventSub использует уже существующий twitchAPI
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))
}
// GetClientID удалён используем t.twitchAPI.GetClientID() при необходимости
func (t *TwitchPlatform) EventSubStatus() (connected bool, subscriptions []string) {
if t.eventSub == nil {
return false, nil
}
return t.eventSub.IsConnected(), t.eventSub.GetSubscriptions()
}
// TimeoutUserViaAPI таймаут через API
func (t *TwitchPlatform) TimeoutUserViaAPI(username string, seconds int) error {
broadcasterID, err := t.twitchAPI.GetBroadcasterID()
if err != nil {
return err
}
moderatorID := broadcasterID
userID, err := t.twitchAPI.GetUserID(username)
if err != nil {
return err
}
return t.twitchAPI.TimeoutUser(broadcasterID, moderatorID, userID, seconds)
}
// BanUserViaAPI бан через API
func (t *TwitchPlatform) BanUserViaAPI(username string) error {
broadcasterID, err := t.twitchAPI.GetBroadcasterID()
if err != nil {
return err
}
userID, err := t.twitchAPI.GetUserID(username)
if err != nil {
return err
}
return t.twitchAPI.BanUser(broadcasterID, broadcasterID, userID)
}
// UnbanUserViaAPI разбан через API
func (t *TwitchPlatform) UnbanUserViaAPI(username string) error {
broadcasterID, err := t.twitchAPI.GetBroadcasterID()
if err != nil {
return err
}
userID, err := t.twitchAPI.GetUserID(username)
if err != nil {
return err
}
return t.twitchAPI.UnbanUser(broadcasterID, broadcasterID, userID)
}
// AddVipViaAPI добавить VIP
func (t *TwitchPlatform) AddVipViaAPI(username string) error {
broadcasterID, err := t.twitchAPI.GetBroadcasterID()
if err != nil {
return err
}
userID, err := t.twitchAPI.GetUserID(username)
if err != nil {
return err
}
return t.twitchAPI.AddVip(broadcasterID, userID)
}
// RemoveVipViaAPI удалить VIP
func (t *TwitchPlatform) RemoveVipViaAPI(username string) error {
broadcasterID, err := t.twitchAPI.GetBroadcasterID()
if err != nil {
return err
}
userID, err := t.twitchAPI.GetUserID(username)
if err != nil {
return err
}
return t.twitchAPI.RemoveVip(broadcasterID, userID)
}
// AddModViaAPI добавить модератора
func (t *TwitchPlatform) AddModViaAPI(username string) error {
broadcasterID, err := t.twitchAPI.GetBroadcasterID()
if err != nil {
return err
}
userID, err := t.twitchAPI.GetUserID(username)
if err != nil {
return err
}
return t.twitchAPI.AddMod(broadcasterID, userID)
}
// RemoveModViaAPI удалить модератора
func (t *TwitchPlatform) RemoveModViaAPI(username string) error {
broadcasterID, err := t.twitchAPI.GetBroadcasterID()
if err != nil {
return err
}
userID, err := t.twitchAPI.GetUserID(username)
if err != nil {
return err
}
return t.twitchAPI.RemoveMod(broadcasterID, userID)
}