Documentation
¶
Overview ¶
Package driver defines the notification driver interface and registry.
Each notification provider (SMTP, Twilio, FCM, etc.) implements the Driver interface. The Registry manages available drivers by name.
Index ¶
Constants ¶
const ( PushKindShow = "show" PushKindWithdraw = "withdraw" )
Push kinds: show a notification, or withdraw one shown earlier.
Variables ¶
var ErrAddressGone = errors.New("herald: address gone")
ErrAddressGone means the provider says the recipient address no longer exists, so the caller should stop sending to it.
var ErrDriverNotFound = errors.New("herald: driver not found")
ErrDriverNotFound is returned when a driver is not registered.
Functions ¶
func DataPayload ¶
DataPayload returns the provider settings meant for the recipient's payload: keys starting with "data.", with the prefix removed. Nothing else in the merged credentials-and-settings map (API keys, tokens, from addresses) is ever forwarded. It returns nil when there are none.
func HTTPClient ¶
HTTPClient returns the *http.Client a driver uses to call its vendor. It behaves like &http.Client{Timeout: timeout}: the same default transport, connection pool, HTTP/2 support and redirect policy, and the error a failed request returns is the transport's own, unwrapped.
On top of that, every request it sends is an OpenTelemetry client span under the span in the request's context. The span is named after the method and ep.URLTemplate ("POST /v3/mail/send", or "POST" with no template) and carries http.request.method, server.address and server.port (unless ep.HideHost), url.template, herald.driver and http.response.status_code. It never carries the URL, its path or its query, or any header. A 4xx or 5xx response, or a transport failure, marks it failed with error.type set to the status code or to timeout, canceled, dns, tls, connection or other; the error's message never reaches it.
The request goes out with exactly the headers the driver set: no traceparent, tracestate or baggage. Vendors are third parties, and the inbound request's baggage is not theirs to see.
Types ¶
type DeliveryResult ¶
type DeliveryResult struct {
ProviderMessageID string `json:"provider_message_id,omitempty"`
Status message.Status `json:"status"`
}
DeliveryResult contains the outcome of a delivery attempt.
type Describer ¶
type Describer interface {
Fields() []Field
}
Describer is optional. A driver that implements it gets a form built from its fields; one that doesn't gets free-form key/value editing.
type Driver ¶
type Driver interface {
// Name returns the driver identifier (e.g., "smtp", "twilio", "fcm").
Name() string
// Channel returns which notification channel this driver handles.
Channel() string
// Send delivers a message and returns a delivery result.
Send(ctx context.Context, msg *OutboundMessage) (*DeliveryResult, error)
// Validate checks if the provided credentials and settings are valid.
Validate(credentials, settings map[string]string) error
}
Driver is the interface that notification provider drivers must implement.
type Endpoint ¶
type Endpoint struct {
// Driver is the driver's name, recorded as herald.driver.
Driver string
// URLTemplate is the request path with its variable parts named, such
// as "/2010-04-01/Accounts/{account_sid}/Messages.json". It is recorded
// as url.template and names the span. Leave it empty when the driver
// can't know the path, such as a webhook URL the user supplies whole.
URLTemplate string
// HideHost keeps server.address and server.port off the span. Set it
// when the user supplies the whole URL, since the host is then theirs
// (a customer's endpoint) rather than the vendor's.
HideHost bool
}
Endpoint describes a vendor call for the client span HTTPClient records. None of it is read from the request URL, which is why a span can't leak a token, a device token or an account ID that sits in the URL.
type Field ¶
type Field struct {
Key string `json:"key"`
Label string `json:"label"`
Help string `json:"help,omitempty"`
Required bool `json:"required"`
Secret bool `json:"secret"`
Placement Placement `json:"placement"`
}
Field describes one value a driver reads from a provider.
func SenderFields ¶
func SenderFields() []Field
SenderFields are the settings Herald reads itself for email: the from address and display name, used when no scoped config supplies them.
type OutboundMessage ¶
type OutboundMessage struct {
To string `json:"to"`
From string `json:"from,omitempty"`
FromName string `json:"from_name,omitempty"`
Subject string `json:"subject,omitempty"`
HTML string `json:"html,omitempty"`
Text string `json:"text,omitempty"`
Title string `json:"title,omitempty"`
Data map[string]string `json:"data,omitempty"`
// Push holds per-message push options. Nil means the v1.8 behaviour.
Push *PushOptions `json:"-"`
// PublicKey is the recipient device's X25519 public key. Push fan-out only.
PublicKey []byte `json:"-"`
}
OutboundMessage is the normalized message format passed to drivers.
type Placement ¶
type Placement string
Placement says which provider map a field lives in. Credentials are encrypted at rest when a key is configured and never echoed back; settings are plain configuration.
type PushOptions ¶
type PushOptions struct {
// Urgency is the delivery priority. Empty means UrgencyActive.
Urgency Urgency
// Kind is PushKindShow or PushKindWithdraw. Empty means PushKindShow.
Kind string
// CollapseID lets a later push replace an earlier one.
CollapseID string
// TTL is how long the provider may hold the push. Zero leaves it to the provider.
TTL time.Duration
// ThreadID groups notifications on the device.
ThreadID string
// Category names the action set the device shows with the notification.
Category string
// Data is extra payload. It wins over provider-level data settings.
Data map[string]string
// DataOnly sends no visible notification block.
DataOnly bool
// MutableContent lets a device extension rewrite the notification.
MutableContent bool
// ContentAvailable wakes the app for a background update.
ContentAvailable bool
}
PushOptions are the per-message push settings a driver honours. A nil *PushOptions means the v1.8 behaviour.
func (*PushOptions) EffectiveKind ¶
func (o *PushOptions) EffectiveKind() string
EffectiveKind returns the kind, defaulting to PushKindShow. It is safe on a nil receiver.
func (*PushOptions) EffectiveUrgency ¶
func (o *PushOptions) EffectiveUrgency() Urgency
EffectiveUrgency returns the urgency, defaulting to UrgencyActive. It is safe on a nil receiver.
type Registry ¶
type Registry struct {
// contains filtered or unexported fields
}
Registry holds all available notification drivers indexed by name.
func (*Registry) Describe ¶
Describe returns a registered driver's fields. The bool is false for an unknown driver and for one that doesn't implement Describer.
func (*Registry) ListByChannel ¶
ListByChannel returns all drivers that handle the given channel.
type Urgency ¶
type Urgency string
Urgency says how hard a push should try to reach the user.
Directories
¶
| Path | Synopsis |
|---|---|
|
Package drivertest provides shared HTTP mock-server helpers for driver unit tests.
|
Package drivertest provides shared HTTP mock-server helpers for driver unit tests. |
|
Package email provides email notification drivers.
|
Package email provides email notification drivers. |
|
Package inapp provides the in-app notification driver.
|
Package inapp provides the in-app notification driver. |
|
Package push provides push notification drivers.
|
Package push provides push notification drivers. |
|
Package sms provides SMS notification drivers.
|
Package sms provides SMS notification drivers. |