Documentation
¶
Overview ¶
Package notify sends notifications to webhook endpoints.
Teams webhooks receive rich Adaptive Cards (schema v1.4) formatted for display in Teams channels. Generic JSON payloads are also supported for custom receivers such as dashboards and Slack integrations (see SendGenericRelease).
Disabled by default — configure notifications.teams_webhook_url and/or notifications.release_webhook_urls (notifications.*) in forge.yaml.
Index ¶
- Constants
- func FormatWebhookURL(url string) (string, error)
- func SendGenericPRReadyToMerge(ctx context.Context, webhookURL string, payload WebhookPayload, ...)
- func SendGenericRelease(ctx context.Context, webhookURL string, payload WebhookPayload, ...)
- type Config
- type EventType
- type GenericPayload
- type Notifier
- func (n *Notifier) BeadDecomposed(ctx context.Context, anvil, beadID, beadTitle string, subBeads []SubBead)
- func (n *Notifier) BeadFailed(ctx context.Context, anvil, beadID string, retries int, lastError string)
- func (n *Notifier) DailyCost(ctx context.Context, date string, totalCost float64, limit float64, ...)
- func (n *Notifier) PRCreated(ctx context.Context, anvil, beadID string, prNumber int, prURL, title string)
- func (n *Notifier) PRReadyToMerge(ctx context.Context, anvil, beadID string, prNumber int, prURL, title string)
- func (n *Notifier) ReleasePublished(ctx context.Context, version, tag, releaseURL, changelogSummary string)
- func (n *Notifier) ShouldNotify(event EventType) bool
- func (n *Notifier) WorkerDone(ctx context.Context, anvil, beadID, workerID string, duration time.Duration)
- type SubBead
- type WebhookDispatcher
- type WebhookPayload
- type WebhookTarget
Constants ¶
const ( // AdaptiveCardSchema is the schema URL for adaptive cards. AdaptiveCardSchema = "http://adaptivecards.io/schemas/adaptive-card.json" // CardVersion is the adaptive card version. CardVersion = "1.4" )
Variables ¶
This section is empty.
Functions ¶
func FormatWebhookURL ¶
FormatWebhookURL validates and normalises a Teams webhook URL.
func SendGenericPRReadyToMerge ¶ added in v0.4.0
func SendGenericPRReadyToMerge(ctx context.Context, webhookURL string, payload WebhookPayload, logger *slog.Logger)
SendGenericPRReadyToMerge posts a generic JSON pr_ready_to_merge payload to any webhook URL. This is used for non-Teams endpoints such as dashboards or custom receivers. Errors are logged but do not cause a fatal failure.
func SendGenericRelease ¶ added in v0.4.0
func SendGenericRelease(ctx context.Context, webhookURL string, payload WebhookPayload, logger *slog.Logger)
SendGenericRelease posts a generic JSON release payload to any webhook URL. This is used for non-Teams endpoints such as dashboards or custom receivers. Errors are logged but do not cause a fatal failure.
Types ¶
type Config ¶
type Config struct {
WebhookURL string
Enabled bool
Events []string // Filter to these events only; empty = all
}
Config holds notifier settings.
type EventType ¶
type EventType string
EventType identifies a notification event.
const ( EventPRCreated EventType = "pr_created" EventBeadFailed EventType = "bead_failed" EventDailyCost EventType = "daily_cost" EventWorkerDone EventType = "worker_done" EventBeadDecomposed EventType = "bead_decomposed" EventReleasePublished EventType = "release_published" EventPRReadyToMerge EventType = "pr_ready_to_merge" // EventRelease is the event type used in generic webhook event filters for // release notifications. Teams webhooks use EventReleasePublished and // receive Adaptive Cards; generic webhooks use EventRelease and receive a // simple GenericPayload. EventRelease EventType = "release" )
type GenericPayload ¶ added in v0.4.0
type GenericPayload struct {
EventType string `json:"event_type"`
BeadID string `json:"bead_id,omitempty"`
Anvil string `json:"anvil,omitempty"`
Message string `json:"message,omitempty"`
Timestamp time.Time `json:"timestamp"`
}
GenericPayload is the uniform JSON payload sent to generic (non-Teams) webhook targets. Unlike the Teams Adaptive Cards, every event produces the same structure so receivers can handle all events with a single schema.
type Notifier ¶
type Notifier struct {
// contains filtered or unexported fields
}
Notifier sends notifications to Teams.
func NewNotifier ¶
NewNotifier creates a Teams notifier. Returns nil if disabled or no URL.
func (*Notifier) BeadDecomposed ¶
func (n *Notifier) BeadDecomposed(ctx context.Context, anvil, beadID, beadTitle string, subBeads []SubBead)
BeadDecomposed sends a notification when Schematic decomposes a bead into sub-beads. This is significant because it changes the work queue.
func (*Notifier) BeadFailed ¶
func (n *Notifier) BeadFailed(ctx context.Context, anvil, beadID string, retries int, lastError string)
BeadFailed sends a notification when a bead fails after retries.
func (*Notifier) DailyCost ¶
func (n *Notifier) DailyCost(ctx context.Context, date string, totalCost float64, limit float64, inputTokens, outputTokens int64)
DailyCost sends a daily cost summary.
func (*Notifier) PRCreated ¶
func (n *Notifier) PRCreated(ctx context.Context, anvil, beadID string, prNumber int, prURL, title string)
PRCreated sends a notification when a PR is created.
func (*Notifier) PRReadyToMerge ¶ added in v0.4.0
func (n *Notifier) PRReadyToMerge(ctx context.Context, anvil, beadID string, prNumber int, prURL, title string)
PRReadyToMerge sends a notification when a PR is ready to merge (CI passing and warden-approved with no blocking reviews or conflicts).
func (*Notifier) ReleasePublished ¶ added in v0.4.0
func (n *Notifier) ReleasePublished(ctx context.Context, version, tag, releaseURL, changelogSummary string)
ReleasePublished sends a notification when a new Forge release is published.
func (*Notifier) ShouldNotify ¶
ShouldNotify checks if an event type should trigger a notification.
type WebhookDispatcher ¶ added in v0.4.0
type WebhookDispatcher struct {
// contains filtered or unexported fields
}
WebhookDispatcher sends events to configured generic JSON webhook targets. Each target can subscribe to a specific subset of events. A nil WebhookDispatcher is safe to use — all methods become no-ops.
func NewWebhookDispatcher ¶ added in v0.4.0
func NewWebhookDispatcher(targets []WebhookTarget, logger *slog.Logger) *WebhookDispatcher
NewWebhookDispatcher creates a dispatcher from a list of webhook targets. Returns nil if no valid targets are configured (empty list or all URLs empty).
func (*WebhookDispatcher) Dispatch ¶ added in v0.4.0
func (d *WebhookDispatcher) Dispatch(ctx context.Context, event EventType, beadID, anvil, message string)
Dispatch sends a GenericPayload to all webhook targets that subscribe to the given event. Each delivery is dispatched in its own goroutine so the caller is never blocked by a slow or unreachable webhook.
Dispatch detaches from the caller's context via context.WithoutCancel so that goroutines are not cancelled when the caller cancels its own context (e.g. via a deferred cancel()). Context values are preserved for tracing. The HTTP client's Timeout enforces the delivery deadline.
func (*WebhookDispatcher) Wait ¶ added in v0.4.0
func (d *WebhookDispatcher) Wait()
Wait blocks until all dispatched webhooks have completed their HTTP requests.
type WebhookPayload ¶ added in v0.4.0
type WebhookPayload struct {
Source string `json:"source"` // Always "forge"
Summary string `json:"summary"` // Pre-formatted human-readable one-liner for list view
Event string `json:"event"` // Machine-readable event type (snake_case)
Detail string `json:"detail,omitempty"` // Secondary description (changelog, commit message, etc.)
URL string `json:"url,omitempty"` // Relevant link (PR, release, issue, etc.)
Repo string `json:"repo,omitempty"` // Repository / anvil name
Version string `json:"version,omitempty"` // Version string (may differ from Tag, e.g. "2.0.0" vs "v2.0.0")
Tag string `json:"tag,omitempty"` // Git tag if applicable (may include "v" prefix)
Bead string `json:"bead,omitempty"` // Bead ID if the event relates to a bead
PR int `json:"pr,omitempty"` // PR number if applicable
}
WebhookPayload is the canonical generic JSON structure sent to non-Teams webhook URLs. It provides a pre-formatted summary and structured metadata so receivers can display rich notifications without parsing event-specific fields.
All generic/non-Teams Forge webhook POSTs use this schema. Teams webhooks instead receive Adaptive Card JSON. The source field is always "forge" so receivers can identify the origin and apply the appropriate badge or routing.
type WebhookTarget ¶ added in v0.4.0
type WebhookTarget struct {
Name string
URL string
Events []string // Empty = subscribe to all events
}
WebhookTarget represents a single generic JSON webhook target. It is the notify-package counterpart of config.WebhookTargetConfig.