feat: notify on direct messages; store DMs under sender nick; respect quiet hours and rate limit for DMs

This commit is contained in:
Thomas Cravey 2025-08-16 12:36:01 -05:00
parent 00ddd9e460
commit 26ae405e9b

View file

@ -8,6 +8,7 @@ import (
"net/http"
"os"
"os/signal"
"strings"
"sync"
"sync/atomic"
"syscall"
@ -136,8 +137,15 @@ func main() {
}
alert := func(channel, author, text, msgid string, at time.Time) {
logger.Debug("ingest", "ts", at.UTC(), "channel", channel, "author", author, "body", text, "msgid", msgid)
// Determine storage channel: for DMs to me, store under sender nick
storeChan := channel
isChannel := strings.HasPrefix(channel, "#") || strings.HasPrefix(channel, "&")
isDMToMe := !isChannel && strings.EqualFold(channel, cfg.Nick)
if isDMToMe {
storeChan = author
}
if err := st.InsertMessage(ctx, store.Message{
Channel: channel,
Channel: storeChan,
Author: author,
Body: text,
Time: at.UTC(),
@ -147,26 +155,52 @@ func main() {
} else {
atomic.AddInt64(&metrics.MessagesIngested, 1)
}
if mentionChecker(text) && allowedChannel(channel) {
// Notify on direct messages to me (bypass channel allow/deny; respect quiet hours)
if isDMToMe && !strings.EqualFold(author, cfg.Nick) {
if nt != nil {
if !cfg.NotifyBackfill && time.Since(at) > 5*time.Minute {
logger.Debug("mention suppressed", "reason", "backfill", "channel", channel, "author", author)
logger.Debug("dm suppressed", "reason", "backfill", "from", author)
return
}
if config.WithinQuietHours(at, cfg.QuietHours) && !isUrgent(text) {
logger.Debug("mention suppressed", "reason", "quiet_hours", "channel", channel, "author", author)
logger.Debug("dm suppressed", "reason", "quiet_hours", "from", author)
return
}
key := channel + "|" + cfg.Nick
key := "dm|" + author
if !rl.allow(key, cfg.MentionMinInterval) {
logger.Debug("mention suppressed", "reason", "rate_limit", "channel", channel, "author", author)
logger.Debug("dm suppressed", "reason", "rate_limit", "from", author)
return
}
if err := nt.Notify(ctx, "IRC mention in "+channel, author+": "+text); err != nil {
if err := nt.Notify(ctx, "Direct message from "+author, text); err != nil {
logger.Error("dm notify", "err", err)
} else {
atomic.AddInt64(&metrics.NotificationsSent, 1)
logger.Debug("dm notified", "from", author)
}
}
return
}
// Mentions in channels
if mentionChecker(text) && allowedChannel(storeChan) {
if nt != nil {
if !cfg.NotifyBackfill && time.Since(at) > 5*time.Minute {
logger.Debug("mention suppressed", "reason", "backfill", "channel", storeChan, "author", author)
return
}
if config.WithinQuietHours(at, cfg.QuietHours) && !isUrgent(text) {
logger.Debug("mention suppressed", "reason", "quiet_hours", "channel", storeChan, "author", author)
return
}
key := storeChan + "|" + cfg.Nick
if !rl.allow(key, cfg.MentionMinInterval) {
logger.Debug("mention suppressed", "reason", "rate_limit", "channel", storeChan, "author", author)
return
}
if err := nt.Notify(ctx, "IRC mention in "+storeChan, author+": "+text); err != nil {
logger.Error("mention notify", "err", err)
} else {
atomic.AddInt64(&metrics.NotificationsSent, 1)
logger.Debug("mention notified", "channel", channel, "author", author)
logger.Debug("mention notified", "channel", storeChan, "author", author)
}
}
}