diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index e356e26125..f94d010966 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -26,7 +26,7 @@ Patches are welcome, but we ask that any significant change start as an [issue]( More information is available for [complex features](./docs/complex-features.md). -Be sure to run `make check` and tests before opening a PR to catch common errors. +Be sure to run `make check` and `make test` before opening a PR to catch common errors. ### UI Change Guidelines diff --git a/engine/sendmessage.go b/engine/sendmessage.go index 1a530dc8d9..c050748a86 100644 --- a/engine/sendmessage.go +++ b/engine/sendmessage.go @@ -104,6 +104,14 @@ func (p *Engine) sendMessage(ctx context.Context, msg *message.Message) (*notifi if stat == nil { return nil, fmt.Errorf("could not find original notification for alert %d to %s", msg.AlertID, msg.Dest.String()) } + name, _, err := p.a.ServiceInfo(ctx, a.ServiceID) + if err != nil { + return nil, errors.Wrap(err, "lookup service info") + } + meta, err := p.a.Metadata(ctx, p.b.db, msg.AlertID) + if err != nil { + return nil, errors.Wrap(err, "lookup alert metadata") + } var status notification.AlertState switch e.Type() { @@ -124,6 +132,8 @@ func (p *Engine) sendMessage(ctx context.Context, msg *message.Message) (*notifi Details: a.Details, NewAlertState: status, OriginalStatus: *stat, + ServiceName: name, + Meta: meta, } case notification.MessageTypeTest: notifMsg = notification.Test{ diff --git a/notification/nfymsg/msgalertstatus.go b/notification/nfymsg/msgalertstatus.go index 9728e523f7..2805b157da 100644 --- a/notification/nfymsg/msgalertstatus.go +++ b/notification/nfymsg/msgalertstatus.go @@ -14,18 +14,27 @@ const ( type AlertStatus struct { Base - AlertID int - LogEntry string - ServiceID string + AlertID int // Summary of the alert that this status is in regards to. Summary string + // Details of the alert that this status is in regards to. Details string + ServiceID string + + // ServiceName of the alert that this status is in regards to. + ServiceName string + + // Meta contains key/value pairs associated with the alert. + Meta map[string]string + // OriginalStatus is the status of the first Alert notification to this Dest for this AlertID. OriginalStatus SendResult // NewAlertState contains the most recent state of the alert. NewAlertState AlertState + + LogEntry string } diff --git a/notification/webhook/sender.go b/notification/webhook/sender.go index d555a9ef55..e0f1809ecc 100644 --- a/notification/webhook/sender.go +++ b/notification/webhook/sender.go @@ -6,6 +6,7 @@ import ( "encoding/json" "fmt" "net/http" + "strings" "time" "github.com/target/goalert/config" @@ -27,6 +28,7 @@ type POSTDataAlert struct { ServiceID string ServiceName string Meta map[string]string + AlertURL string } // POSTDataAlertBundle represents fields in outgoing alert bundle notification. @@ -36,14 +38,21 @@ type POSTDataAlertBundle struct { ServiceID string ServiceName string Count int + AlertURL string } // POSTDataAlertStatus represents fields in outgoing alert status notification. type POSTDataAlertStatus struct { - AppName string - Type string - AlertID int - LogEntry string + AppName string + Type string + AlertID int + Summary string + Details string + ServiceID string + ServiceName string + Meta map[string]string + LogEntry string + AlertURL string } // POSTDataAlertStatusBundle represents fields in outgoing alert status bundle notification. @@ -53,6 +62,7 @@ type POSTDataAlertStatusBundle struct { AlertID int LogEntry string Count int + AlertURL string } // POSTDataVerification represents fields in outgoing verification notification. @@ -97,6 +107,7 @@ var _ nfydest.MessageSender = &Sender{} func (s *Sender) SendMessage(ctx context.Context, msg notification.Message) (*notification.SentMessage, error) { cfg := config.FromContext(ctx) var payload interface{} + pubURL := strings.TrimSuffix(cfg.PublicURL(), "/") switch m := msg.(type) { case notification.Test: payload = POSTDataTest{ @@ -119,6 +130,7 @@ func (s *Sender) SendMessage(ctx context.Context, msg notification.Message) (*no ServiceID: m.ServiceID, ServiceName: m.ServiceName, Meta: m.Meta, + AlertURL: cfg.CallbackURL(fmt.Sprintf("/alerts/%d", m.AlertID)), } case notification.AlertBundle: payload = POSTDataAlertBundle{ @@ -127,13 +139,20 @@ func (s *Sender) SendMessage(ctx context.Context, msg notification.Message) (*no ServiceID: m.ServiceID, ServiceName: m.ServiceName, Count: m.Count, + AlertURL: cfg.CallbackURL(fmt.Sprintf("/services/%s/alerts", m.ServiceID)), } case notification.AlertStatus: payload = POSTDataAlertStatus{ - AppName: cfg.ApplicationName(), - Type: "AlertStatus", - AlertID: m.AlertID, - LogEntry: m.LogEntry, + AppName: cfg.ApplicationName(), + Type: "AlertStatus", + Details: m.Details, + AlertID: m.AlertID, + Summary: m.Summary, + ServiceID: m.ServiceID, + ServiceName: m.ServiceName, + Meta: m.Meta, + LogEntry: m.LogEntry, + AlertURL: cfg.CallbackURL(fmt.Sprintf("/alerts/%d", m.AlertID)), } case notification.ScheduleOnCallUsers: // We use types defined in this package to insulate against unintended API