mirror of
https://github.com/Dvorinka/Dash.git
synced 2026-10-28 07:41:27 +00:00
feat: webhook alerts for monitor + domain events (merge plan M2)
Generic webhook notification delivery configured via the notify_webhook settings key — no new schema. Fires on monitor up/down transitions (pending stays silent), domain expiry, domain expiring, and TLS cert expiring; dispatch is async and failures are logged, never fatal. POST /api/notify/test verifies configuration; Settings dialog gains a webhook URL field with save + send-test. Payload carries event/name/text/content/message so Slack, Discord, ntfy, and custom receivers all work. Generated with [Devin](https://devin.ai) Co-Authored-By: Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com>
This commit is contained in:
1 parent
f9fd1d9cf2
commit
2f3e8a1879
7 files changed
+255
-4
No files matched your search
@@ -5,6 +5,7 @@ import (
|
||||
"database/sql"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"net/http"
|
||||
"strconv"
|
||||
"time"
|
||||
@@ -318,16 +319,36 @@ func (s *Server) deleteDomain(c *gin.Context) {
|
||||
c.Status(http.StatusNoContent)
|
||||
}
|
||||
|
||||
// refreshDomain re-runs the full lookup and writes a snapshot row.
|
||||
// refreshDomain re-runs the full lookup and writes a snapshot row. Expiry
|
||||
// threshold crossings fire notify events on the edge (only when a state
|
||||
// newly becomes true, not on every refresh).
|
||||
func (s *Server) refreshDomain(id string) {
|
||||
row, err := s.loadDomain(id)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
prev := viewOf(row)
|
||||
ctx, cancel := context.WithTimeout(context.Background(), 45*time.Second)
|
||||
defer cancel()
|
||||
r := s.lookup(ctx, row.Name)
|
||||
s.applyResult(id, r)
|
||||
|
||||
next, err := s.loadDomain(id)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
nv := viewOf(next)
|
||||
switch {
|
||||
case nv.DaysUntilExpiry != nil && *nv.DaysUntilExpiry < 0 && !(prev.DaysUntilExpiry != nil && *prev.DaysUntilExpiry < 0):
|
||||
s.notify("domain.expired", next.Name, fmt.Sprintf("Domain %s has expired", next.Name))
|
||||
case nv.Expiring && !prev.Expiring:
|
||||
s.notify("domain.expiring", next.Name,
|
||||
fmt.Sprintf("Domain %s expires in %d days", next.Name, *nv.DaysUntilExpiry))
|
||||
}
|
||||
if nv.SSLExpiring && !prev.SSLExpiring && nv.SSLDaysUntilExpiry != nil {
|
||||
s.notify("domain.sslExpiring", next.Name,
|
||||
fmt.Sprintf("TLS certificate for %s expires in %d days", next.Name, *nv.SSLDaysUntilExpiry))
|
||||
}
|
||||
}
|
||||
|
||||
func (s *Server) refreshDomainH(c *gin.Context) {
|
||||
|
||||
Reference in new issue
Block a user