235 lines
5.9 KiB
Go
235 lines
5.9 KiB
Go
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)
|
||
}
|