171 lines
4.5 KiB
Go
171 lines
4.5 KiB
Go
package reminder
|
|
|
|
import (
|
|
"fmt"
|
|
"regexp"
|
|
"strconv"
|
|
"strings"
|
|
"time"
|
|
|
|
"git.nakama.town/fmartingr/butterrobot/internal/model"
|
|
"git.nakama.town/fmartingr/butterrobot/internal/plugin"
|
|
)
|
|
|
|
// Duration regex patterns to match reminders
|
|
var (
|
|
remindMePattern = regexp.MustCompile(`(?i)^!remindme\s(\d+)(y|mo|d|h|m|s)$`)
|
|
)
|
|
|
|
// ReminderCreator is an interface for creating reminders
|
|
type ReminderCreator interface {
|
|
CreateReminder(platform, channelID, messageID, replyToID, userID, username, content string, triggerAt time.Time) (*model.Reminder, error)
|
|
}
|
|
|
|
// Reminder is a plugin that sets reminders for messages
|
|
type Reminder struct {
|
|
plugin.BasePlugin
|
|
creator ReminderCreator
|
|
}
|
|
|
|
// New creates a new Reminder plugin
|
|
func New(creator ReminderCreator) *Reminder {
|
|
return &Reminder{
|
|
BasePlugin: plugin.BasePlugin{
|
|
ID: "reminder.remindme",
|
|
Name: "Remind Me",
|
|
Help: "Reply to a message with `!remindme <duration>` to set a reminder (e.g., `!remindme 2d` for 2 days, `!remindme 1y` for 1 year).",
|
|
ConfigRequired: false,
|
|
},
|
|
creator: creator,
|
|
}
|
|
}
|
|
|
|
// OnMessage processes incoming messages
|
|
func (r *Reminder) OnMessage(msg *model.Message, config map[string]interface{}) []*model.Message {
|
|
// Only process replies to messages
|
|
if msg.ReplyTo == "" {
|
|
return nil
|
|
}
|
|
|
|
// Check if the message is a reminder command
|
|
match := remindMePattern.FindStringSubmatch(msg.Text)
|
|
if match == nil {
|
|
return nil
|
|
}
|
|
|
|
// Parse the duration
|
|
amount, err := strconv.Atoi(match[1])
|
|
if err != nil {
|
|
return []*model.Message{
|
|
{
|
|
Text: "Invalid duration format. Please use a number followed by y (years), mo (months), d (days), h (hours), m (minutes), or s (seconds).",
|
|
Chat: msg.Chat,
|
|
Channel: msg.Channel,
|
|
Author: "bot",
|
|
FromBot: true,
|
|
Date: time.Now(),
|
|
ReplyTo: msg.ID,
|
|
},
|
|
}
|
|
}
|
|
|
|
// Calculate the trigger time
|
|
var duration time.Duration
|
|
unit := match[2]
|
|
switch strings.ToLower(unit) {
|
|
case "y":
|
|
duration = time.Duration(amount) * 365 * 24 * time.Hour
|
|
case "mo":
|
|
duration = time.Duration(amount) * 30 * 24 * time.Hour
|
|
case "d":
|
|
duration = time.Duration(amount) * 24 * time.Hour
|
|
case "h":
|
|
duration = time.Duration(amount) * time.Hour
|
|
case "m":
|
|
duration = time.Duration(amount) * time.Minute
|
|
case "s":
|
|
duration = time.Duration(amount) * time.Second
|
|
default:
|
|
return []*model.Message{
|
|
{
|
|
Text: "Invalid duration unit. Please use y (years), mo (months), d (days), h (hours), m (minutes), or s (seconds).",
|
|
Chat: msg.Chat,
|
|
Channel: msg.Channel,
|
|
Author: "bot",
|
|
FromBot: true,
|
|
Date: time.Now(),
|
|
ReplyTo: msg.ID,
|
|
},
|
|
}
|
|
}
|
|
|
|
triggerAt := time.Now().Add(duration)
|
|
|
|
// Determine the username for the reminder
|
|
username := msg.Author
|
|
if username == "" {
|
|
// Try to extract username from message raw data
|
|
if authorData, ok := msg.Raw["author"].(map[string]interface{}); ok {
|
|
if name, ok := authorData["username"].(string); ok {
|
|
username = name
|
|
} else if name, ok := authorData["name"].(string); ok {
|
|
username = name
|
|
}
|
|
}
|
|
}
|
|
|
|
// Create the reminder
|
|
_, err = r.creator.CreateReminder(
|
|
msg.Channel.Platform,
|
|
msg.Chat,
|
|
msg.ID,
|
|
msg.ReplyTo,
|
|
msg.Author,
|
|
username,
|
|
"", // No additional content for now
|
|
triggerAt,
|
|
)
|
|
|
|
if err != nil {
|
|
return []*model.Message{
|
|
{
|
|
Text: fmt.Sprintf("Failed to create reminder: %v", err),
|
|
Chat: msg.Chat,
|
|
Channel: msg.Channel,
|
|
Author: "bot",
|
|
FromBot: true,
|
|
Date: time.Now(),
|
|
ReplyTo: msg.ID,
|
|
},
|
|
}
|
|
}
|
|
|
|
// Format the acknowledgment message
|
|
var confirmText string
|
|
switch strings.ToLower(unit) {
|
|
case "y":
|
|
confirmText = fmt.Sprintf("I'll remind you about this message in %d year(s) on %s", amount, triggerAt.Format("Mon, Jan 2, 2006 at 15:04"))
|
|
case "mo":
|
|
confirmText = fmt.Sprintf("I'll remind you about this message in %d month(s) on %s", amount, triggerAt.Format("Mon, Jan 2 at 15:04"))
|
|
case "d":
|
|
confirmText = fmt.Sprintf("I'll remind you about this message in %d day(s) on %s", amount, triggerAt.Format("Mon, Jan 2 at 15:04"))
|
|
case "h":
|
|
confirmText = fmt.Sprintf("I'll remind you about this message in %d hour(s) at %s", amount, triggerAt.Format("15:04"))
|
|
case "m":
|
|
confirmText = fmt.Sprintf("I'll remind you about this message in %d minute(s) at %s", amount, triggerAt.Format("15:04"))
|
|
case "s":
|
|
confirmText = fmt.Sprintf("I'll remind you about this message in %d second(s)", amount)
|
|
}
|
|
|
|
return []*model.Message{
|
|
{
|
|
Text: confirmText,
|
|
Chat: msg.Chat,
|
|
Channel: msg.Channel,
|
|
Author: "bot",
|
|
FromBot: true,
|
|
Date: time.Now(),
|
|
ReplyTo: msg.ID,
|
|
},
|
|
}
|
|
}
|