2022-10-27 09:56:40 +00:00
|
|
|
package discord
|
|
|
|
|
|
|
|
import (
|
|
|
|
"context"
|
|
|
|
"sync"
|
2023-06-30 05:09:52 +00:00
|
|
|
"text/template"
|
2022-10-27 09:56:40 +00:00
|
|
|
"time"
|
|
|
|
|
2023-06-30 05:09:52 +00:00
|
|
|
"gitea.dwysokinski.me/twhelp/dcbot/internal/discord/internal/discordi18n"
|
2022-10-27 09:56:40 +00:00
|
|
|
"gitea.dwysokinski.me/twhelp/dcbot/internal/domain"
|
|
|
|
"github.com/bwmarrin/discordgo"
|
2023-06-30 05:09:52 +00:00
|
|
|
"github.com/nicksnyder/go-i18n/v2/i18n"
|
2022-10-29 10:44:11 +00:00
|
|
|
"go.uber.org/zap"
|
2022-10-27 09:56:40 +00:00
|
|
|
)
|
|
|
|
|
|
|
|
const (
|
|
|
|
executeMonitorsJobTimeout = 2 * time.Minute
|
|
|
|
colorGreen = 0x00ff00
|
|
|
|
colorRed = 0xff0000
|
|
|
|
)
|
|
|
|
|
|
|
|
type executeMonitorsJob struct {
|
2023-06-30 05:09:52 +00:00
|
|
|
s *discordgo.Session
|
|
|
|
svc GroupService
|
|
|
|
localizer *discordi18n.Localizer
|
|
|
|
logger *zap.Logger
|
2022-10-27 09:56:40 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
func (e *executeMonitorsJob) Run() {
|
|
|
|
ctx, cancel := context.WithTimeout(context.Background(), executeMonitorsJobTimeout)
|
|
|
|
defer cancel()
|
|
|
|
|
2022-10-29 10:44:11 +00:00
|
|
|
start := time.Now()
|
2022-10-27 09:56:40 +00:00
|
|
|
notifications, err := e.svc.Execute(ctx)
|
|
|
|
if err != nil {
|
2023-06-30 05:09:52 +00:00
|
|
|
e.logger.Error(
|
|
|
|
"something went wrong while executing monitors",
|
|
|
|
zap.Error(err),
|
|
|
|
zap.Duration("duration", time.Since(start)),
|
|
|
|
)
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
convertedNotifications, err := (ennoblementNotificationToMessageEmbedConverter{notifications, e.localizer}).convert()
|
|
|
|
if err != nil {
|
|
|
|
e.logger.Error("couldn't convert []domain.EnnoblementNotification to []*discordgo.MessageEmbed", zap.Error(err))
|
2022-10-27 09:56:40 +00:00
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
var wg sync.WaitGroup
|
|
|
|
|
2023-06-30 05:09:52 +00:00
|
|
|
for ch, embeds := range convertedNotifications {
|
2022-10-27 09:56:40 +00:00
|
|
|
wg.Add(1)
|
|
|
|
|
|
|
|
go func(ch string, embeds []*discordgo.MessageEmbed) {
|
|
|
|
defer wg.Done()
|
|
|
|
for _, embed := range embeds {
|
2023-06-30 05:09:52 +00:00
|
|
|
_, sendErr := e.s.ChannelMessageSendEmbed(ch, embed)
|
|
|
|
if sendErr != nil {
|
|
|
|
e.logger.Warn("couldn't send notification", zap.String("channel", ch), zap.Error(sendErr))
|
|
|
|
}
|
2022-10-27 09:56:40 +00:00
|
|
|
}
|
|
|
|
}(ch, embeds)
|
|
|
|
}
|
|
|
|
|
|
|
|
wg.Wait()
|
2022-10-29 10:44:11 +00:00
|
|
|
|
|
|
|
e.logger.Info(
|
|
|
|
"notifications sent",
|
|
|
|
zap.Int("notifications", len(notifications)),
|
|
|
|
zap.Duration("duration", time.Since(start)),
|
|
|
|
)
|
2022-10-27 09:56:40 +00:00
|
|
|
}
|
|
|
|
|
2023-06-20 04:14:16 +00:00
|
|
|
type ennoblementNotificationToMessageEmbedConverter struct {
|
2023-06-30 05:09:52 +00:00
|
|
|
ns []domain.EnnoblementNotification
|
|
|
|
localizer *discordi18n.Localizer
|
2023-06-20 04:14:16 +00:00
|
|
|
}
|
|
|
|
|
2023-06-30 05:09:52 +00:00
|
|
|
func (c ennoblementNotificationToMessageEmbedConverter) convert() (map[string][]*discordgo.MessageEmbed, error) {
|
2022-10-27 09:56:40 +00:00
|
|
|
m := make(map[string]map[domain.EnnoblementNotificationType][]*discordgo.MessageEmbed)
|
|
|
|
timestamp := formatTimestamp(time.Now())
|
2023-06-20 04:14:16 +00:00
|
|
|
for _, n := range c.ns {
|
2022-10-27 09:56:40 +00:00
|
|
|
if _, ok := m[n.ChannelID]; !ok {
|
|
|
|
m[n.ChannelID] = make(map[domain.EnnoblementNotificationType][]*discordgo.MessageEmbed)
|
|
|
|
}
|
|
|
|
|
|
|
|
embeds := m[n.ChannelID][n.Type]
|
|
|
|
|
2023-06-30 05:09:52 +00:00
|
|
|
description, err := c.buildDescription(n)
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
if l := len(embeds); l == 0 || len(embeds[l-1].Description)+len(description) > embedDescriptionCharLimit {
|
2022-10-27 09:56:40 +00:00
|
|
|
embeds = append(embeds, &discordgo.MessageEmbed{
|
2023-06-20 04:14:16 +00:00
|
|
|
Color: c.mapNotificationTypeToColor(n.Type),
|
2022-10-27 09:56:40 +00:00
|
|
|
Type: discordgo.EmbedTypeRich,
|
|
|
|
Timestamp: timestamp,
|
|
|
|
})
|
|
|
|
}
|
|
|
|
if len(embeds[len(embeds)-1].Description) > 0 {
|
2023-06-30 05:09:52 +00:00
|
|
|
description = "\n" + description
|
2022-10-27 09:56:40 +00:00
|
|
|
}
|
2023-06-30 05:09:52 +00:00
|
|
|
embeds[len(embeds)-1].Description += description
|
2022-10-27 09:56:40 +00:00
|
|
|
|
|
|
|
m[n.ChannelID][n.Type] = embeds
|
|
|
|
}
|
|
|
|
|
|
|
|
res := make(map[string][]*discordgo.MessageEmbed, len(m))
|
|
|
|
for ch, innerMap := range m {
|
|
|
|
cnt := 0
|
|
|
|
for _, embeds := range innerMap {
|
|
|
|
cnt += len(embeds)
|
|
|
|
}
|
|
|
|
|
|
|
|
res[ch] = make([]*discordgo.MessageEmbed, 0, cnt)
|
|
|
|
for _, embeds := range innerMap {
|
|
|
|
res[ch] = append(res[ch], embeds...)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-06-30 05:09:52 +00:00
|
|
|
return res, nil
|
2022-10-27 09:56:40 +00:00
|
|
|
}
|
|
|
|
|
2023-06-30 05:09:52 +00:00
|
|
|
func (c ennoblementNotificationToMessageEmbedConverter) buildDescription(n domain.EnnoblementNotification) (string, error) {
|
|
|
|
return c.localizer.Localize(n.LanguageTag, &i18n.LocalizeConfig{
|
|
|
|
MessageID: "job.execute-monitors.embed.description",
|
|
|
|
TemplateData: map[string]any{
|
|
|
|
"Ennoblement": n.Ennoblement,
|
|
|
|
},
|
|
|
|
Funcs: template.FuncMap{
|
2023-07-13 04:22:52 +00:00
|
|
|
"buildPlayerMarkdown": buildPlayerMarkdown,
|
2023-06-30 05:09:52 +00:00
|
|
|
"buildLink": buildLink,
|
|
|
|
},
|
|
|
|
})
|
2022-10-27 09:56:40 +00:00
|
|
|
}
|
|
|
|
|
2023-06-20 04:14:16 +00:00
|
|
|
func (c ennoblementNotificationToMessageEmbedConverter) mapNotificationTypeToColor(t domain.EnnoblementNotificationType) int {
|
2022-10-27 09:56:40 +00:00
|
|
|
switch t {
|
|
|
|
case domain.EnnoblementNotificationTypeGain:
|
|
|
|
return colorGreen
|
|
|
|
case domain.EnnoblementNotificationTypeLoss:
|
|
|
|
fallthrough
|
|
|
|
default:
|
|
|
|
return colorRed
|
|
|
|
}
|
|
|
|
}
|