5
5
"encoding/json"
6
6
"fmt"
7
7
"net/http"
8
+ "time"
8
9
9
10
"github.com/google/uuid"
10
11
@@ -132,7 +133,7 @@ func (api *API) notificationTemplatesByKind(rw http.ResponseWriter, r *http.Requ
132
133
templates , err := api .Database .GetNotificationTemplatesByKind (ctx , kind )
133
134
if err != nil {
134
135
httpapi .Write (r .Context (), rw , http .StatusInternalServerError , codersdk.Response {
135
- Message : fmt .Sprintf ("Failed to retrieve '%s' notifications templates." , kind ),
136
+ Message : fmt .Sprintf ("Failed to retrieve %q notifications templates." , kind ),
136
137
Detail : err .Error (),
137
138
})
138
139
return
@@ -386,7 +387,7 @@ func (api *API) postCustomNotification(rw http.ResponseWriter, r *http.Request)
386
387
})
387
388
return
388
389
}
389
- if user .IsSystemUser () {
390
+ if user .IsSystem {
390
391
api .Logger .Error (ctx , "send custom notification: system user is not allowed" ,
391
392
slog .F ("id" , user .ID .String ()), slog .F ("name" , user .Name ))
392
393
httpapi .Write (ctx , rw , http .StatusForbidden , codersdk.Response {
@@ -407,12 +408,12 @@ func (api *API) postCustomNotification(rw http.ResponseWriter, r *http.Request)
407
408
},
408
409
map [string ]any {
409
410
// Current dedupe is done via an hash of (template, user, method, payload, targets, day).
410
- // We intentionally include a timestamp to bypass the per-day dedupe so the caller can
411
- // resend identical content to themselves multiple times in one day.
412
- // TODO(ssncferreira): When we support sending custom notifications to multiple users/roles,
411
+ // Include a minute-bucketed timestamp to bypass per-day dedupe for self-sends,
412
+ // letting the caller resend identical content the same day (but not more than
413
+ // once per minute).
414
+ // TODO(ssncferreira): When custom notifications can target multiple users/roles,
413
415
// enforce proper deduplication across recipients to reduce noise and prevent spam.
414
- // See https://github.com/coder/coder/issues/19768
415
- "dedupe_bypass_ts" : api .Clock .Now ().UTC (),
416
+ "dedupe_bypass_ts" : api .Clock .Now ().UTC ().Truncate (time .Minute ),
416
417
},
417
418
user .ID .String (),
418
419
); err != nil {
0 commit comments