залил

This commit is contained in:
2026-04-15 08:00:15 +03:00
commit 5549b3545e
51 changed files with 8073 additions and 0 deletions
+166
View File
@@ -0,0 +1,166 @@
package events
import (
"stream-bot/internal/audio"
"stream-bot/internal/db"
"stream-bot/internal/hotkey"
"stream-bot/internal/logger"
"stream-bot/internal/webservices"
"strings"
)
type Processor struct {
sendMessageFunc func(platform, text string) error
webSrvMgr *webservices.Manager
}
// NewProcessor создаёт обработчик событий с функцией отправки сообщений и менеджером веб-сервисов
func NewProcessor(sendMessageFunc func(platform, text string) error, webSrvMgr *webservices.Manager) *Processor {
return &Processor{
sendMessageFunc: sendMessageFunc,
webSrvMgr: webSrvMgr,
}
}
func (p *Processor) ProcessEvent(platform, eventName string, params map[string]string) {
// 1. Выполняем действия, сохранённые в БД (send_message, play_sound, press_hotkey)
actions, err := db.GetEventActions(platform, eventName)
if err != nil {
logger.Error("Failed to get event actions: %v", err)
} else {
for _, action := range actions {
switch action.Type {
case "send_message":
if p.sendMessageFunc == nil {
logger.Error("sendMessageFunc is nil, cannot send message")
continue
}
text := action.Text
for k, v := range params {
placeholder := "{{" + k + "}}"
text = strings.ReplaceAll(text, placeholder, v)
}
if err := p.sendMessageFunc(platform, text); err != nil {
logger.Error("Send message error: %v", err)
}
case "play_sound":
if err := audio.PlaySound(action.SoundFile); err != nil {
logger.Error("Play sound error: %v", err)
}
case "press_hotkey":
if err := hotkey.PressCombination(action.Keys); err != nil {
logger.Error("Hotkey error: %v", err)
}
case "http_request":
logger.Info("[Event] HTTP request to %s", action.URL)
}
}
}
//// 2. Отправляем уведомление во все запущенные alert-сервисы (если есть)
//if p.webSrvMgr == nil {
// return
//}
//
//// Формируем заголовок и текст уведомления на основе типа события
//title, text := p.formatEventNotification(eventName, params)
//if title == "" && text == "" {
// // Если событие не требует уведомления, не отправляем
// return
//}
//
//// Получаем звук для события (можно настроить позже, пока используем стандартные)
//soundFile := p.getSoundForEvent(eventName)
//
//payload := map[string]interface{}{
// "title": title,
// "text": text,
// "duration": 5,
// "image": "",
// "sound": soundFile,
//}
//
//// Отправляем во все alert-сервисы
//services := p.webSrvMgr.GetAllServices()
//for _, srv := range services {
// if srv.GetType() != "alert" {
// continue
// }
// port := srv.GetPort()
// url := fmt.Sprintf("http://localhost:%d/notify", port)
// body, _ := json.Marshal(payload)
// go func(url string, body []byte) {
// resp, err := http.Post(url, "application/json", bytes.NewReader(body))
// if err != nil {
// logger.Error("Failed to send alert to service %s: %v", url, err)
// } else {
// _ = resp.Body.Close()
// }
// }(url, body)
//}
}
// formatEventNotification формирует заголовок и текст уведомления для события
func (p *Processor) formatEventNotification(eventName string, params map[string]string) (title, text string) {
switch eventName {
case "follow":
username := params["username"]
title = "Новый фолловер!"
text = username + " теперь с нами"
case "subscribe":
username := params["username"]
tier := params["tier"]
tierName := ""
switch tier {
case "1000":
tierName = "1 уровень"
case "2000":
tierName = "2 уровень"
case "3000":
tierName = "3 уровень"
default:
tierName = tier
}
title = "Спасибо за подписку!"
text = username + " подписался на " + tierName
case "gift_sub":
gifter := params["gifter"]
recipient := params["recipient"]
total := params["cumulative_total"]
title = "Подарочная подписка!"
if recipient != "" {
text = gifter + " подарил подписку для " + recipient
} else {
text = gifter + " подарил " + total + " подписок"
}
case "raid":
from := params["from"]
viewers := params["viewers"]
title = "Рейд!"
text = from + " привёл " + viewers + " зрителей"
case "reward_redemption":
username := params["username"]
reward := params["reward_title"]
title = "Активирована награда!"
text = username + " активировал " + reward
default:
return "", ""
}
return title, text
}
// getSoundForEvent возвращает путь к звуковому файлу для события (можно вынести в настройки)
func (p *Processor) getSoundForEvent(eventName string) string {
// Здесь можно читать настройки из БД, пока используем заглушку
sounds := map[string]string{
"follow": "/sounds/follow.mp3",
"subscribe": "/sounds/sub.mp3",
"gift_sub": "/sounds/gift.mp3",
"raid": "/sounds/raid.mp3",
"reward_redemption": "/sounds/reward.mp3",
}
if s, ok := sounds[eventName]; ok {
return s
}
return "/sounds/default.mp3"
}