96 lines
2.5 KiB
Go
96 lines
2.5 KiB
Go
package events
|
|
|
|
import (
|
|
"context"
|
|
"log"
|
|
"strconv"
|
|
|
|
"velox-bot/internal/db/repos/schedulerepo"
|
|
"velox-bot/internal/db/services"
|
|
|
|
"github.com/bwmarrin/discordgo"
|
|
)
|
|
|
|
// HandleMessageReactionAdd reacts to emoji on schedule DM messages:
|
|
// ✅ accept, ❌ decline, 🔁 request reschedule.
|
|
func HandleMessageReactionAdd(s *discordgo.Session, r *discordgo.MessageReactionAdd, svc *services.Services) {
|
|
if svc == nil || svc.Schedule == nil {
|
|
return
|
|
}
|
|
if r == nil || r.UserID == "" || r.MessageID == "" {
|
|
return
|
|
}
|
|
|
|
// Ignore bot reactions.
|
|
if r.Member != nil && r.Member.User != nil && r.Member.User.Bot {
|
|
return
|
|
}
|
|
|
|
msgID64, err := strconv.ParseInt(r.MessageID, 10, 64)
|
|
if err != nil || msgID64 == 0 {
|
|
return
|
|
}
|
|
|
|
ctx := context.Background()
|
|
sch, err := svc.Schedule.GetByMessageID(ctx, msgID64)
|
|
if err != nil || sch == nil {
|
|
return
|
|
}
|
|
|
|
// Only invitee can react to change status.
|
|
if r.UserID != strconv.FormatInt(sch.InviteeID, 10) {
|
|
return
|
|
}
|
|
|
|
// Only pending can be transitioned by reaction.
|
|
if sch.Status != schedulerepo.StatusPending {
|
|
return
|
|
}
|
|
|
|
var newStatus schedulerepo.ScheduleStatus
|
|
switch r.Emoji.Name {
|
|
case "✅":
|
|
newStatus = schedulerepo.StatusAccepted
|
|
case "❌":
|
|
newStatus = schedulerepo.StatusDeclined
|
|
case "🔁":
|
|
newStatus = schedulerepo.StatusRescheduleRequested
|
|
default:
|
|
return
|
|
}
|
|
|
|
if err := svc.Schedule.UpdateStatus(ctx, sch.ID, newStatus); err != nil {
|
|
log.Printf("schedule: failed to update status id=%d: %v", sch.ID, err)
|
|
return
|
|
}
|
|
|
|
statusText := map[schedulerepo.ScheduleStatus]string{
|
|
schedulerepo.StatusAccepted: "accepted ✅",
|
|
schedulerepo.StatusDeclined: "declined ❌",
|
|
schedulerepo.StatusRescheduleRequested: "requested rescheduling 🔁",
|
|
}[newStatus]
|
|
|
|
utcStr := sch.ScheduledAt.UTC().Format("2006-01-02 15:04")
|
|
|
|
// Notify requester with local time if configured.
|
|
if svc.UserSettings != nil {
|
|
loc, zone, _, err := svc.UserSettings.GetTimezone(ctx, sch.RequesterID)
|
|
if err != nil {
|
|
loc = sch.ScheduledAt.UTC().Location()
|
|
zone = "UTC"
|
|
}
|
|
localStr := sch.ScheduledAt.In(loc).Format("2006-01-02 15:04")
|
|
content := "Your session request with <@" + strconv.FormatInt(sch.InviteeID, 10) + "> for " +
|
|
utcStr + " UTC (" + localStr + " " + zone + ") has been " + statusText + "."
|
|
|
|
requesterID := strconv.FormatInt(sch.RequesterID, 10)
|
|
dmCh, err := s.UserChannelCreate(requesterID)
|
|
if err == nil {
|
|
if _, err := s.ChannelMessageSend(dmCh.ID, content); err != nil {
|
|
log.Printf("schedule: failed to DM requester about status change: %v", err)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|