notifypost

package
v1.134.1 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Sep 22, 2026 License: Apache-2.0 Imports: 9 Imported by: 0

Documentation

Overview

Package notifypost is the transport half of notification channels: one Sender per chat or webhook kind, turning a document into a post on its upstream.

It is separate from notifychannel, which persists the operator's channel records, because the two share nothing: a record is read and written by the admin surface, a post is made by the send worker, and neither needs the other's machinery. What they share is the Channel value, which lives in the domain both depend on.

No sender holds a credential. The three kinds deliver through an Upstream the api gateway materializes for the connection the channel names, so a bot token lives exactly where every other upstream credential lives.

Index

Constants

View Source
const MattermostMaxTextBytes = 16000

MattermostMaxTextBytes is the most a mattermost channel sends in one message. A Mattermost post is capped at 16,383 characters by the server; the platform cuts below that and keeps the link, so the server never refuses a post for its length.

View Source
const WebhookMaxTextBytes = 12000

WebhookMaxTextBytes is the most a webhook channel sends in one message. An incoming webhook is consumed by whichever server the URL belongs to, most often Slack or Mattermost, so the cap is the lower of the two.

Variables

View Source
var ErrTerminal = errors.New("notifychannel: upstream refused the message")

ErrTerminal marks a send failure that retrying cannot fix: the upstream refused the message itself rather than failing to receive it. A channel posting to a chat channel that was deleted, or through a bot that was uninstalled, fails this way on every attempt, so burning five of them delays nothing and fills the history with the same line five times.

The worker matches it with errors.Is and fails the row at once. Everything else -- a timeout, a refused connection, a 5xx, a rate limit -- retries on the existing backoff.

Functions

This section is empty.

Types

type MattermostSender

type MattermostSender struct {
	// contains filtered or unexported fields
}

MattermostSender posts to a Mattermost channel through the v4 REST API.

The bot token is the connection's credential, applied by the connection's authenticator as a bearer token, so this sender never sees it.

func NewMattermostSender

func NewMattermostSender(upstream UpstreamFunc) *MattermostSender

NewMattermostSender builds the mattermost transport over upstream.

func (*MattermostSender) Send

Send posts the document to the channel's target.

Mattermost answers an application-level refusal with the matching HTTP status rather than with a 200 and a flag, so the shared status classification is the whole verdict and there is no envelope to read.

type Sender

type Sender interface {
	// Send posts doc to ch, returning ErrTerminal for a refusal that
	// retrying cannot fix.
	Send(ctx context.Context, ch notification.Channel, doc notification.Document) error
}

Sender delivers one document to one channel of its kind.

type Senders

type Senders struct {
	// contains filtered or unexported fields
}

Senders dispatches a document to the sender for its channel's kind.

The email kind is absent: an email channel fans out at enqueue to one ordinary queue row per recipient, which the existing renderer and SMTP sender deliver. There is nothing for a channel transport to do with it, and a second mail path would be a second place for the deployment's mail settings to be read.

func NewSenders

func NewSenders(upstream UpstreamFunc) *Senders

NewSenders builds the dispatcher for the HTTP kinds over upstream.

func (*Senders) For

func (s *Senders) For(kind string) (Sender, bool)

For returns the sender for a kind, and whether this dispatcher delivers it.

func (*Senders) Send

Send delivers doc through the sender for ch's kind.

type Upstream

type Upstream interface {
	// BaseURL is the connection's upstream root.
	BaseURL() string
	// Do applies the connection's authentication and static headers and
	// sends the request.
	Do(req *http.Request) (*http.Response, error)
}

Upstream is the authorized transport a channel delivers through: the connection's base URL and its ability to make an authorized call.

It is an interface here, satisfied by *apigateway.Upstream, so this package depends on the idea of an authorized upstream rather than on the api gateway. That keeps the senders testable against an httptest server and keeps the credential on the gateway's side of the seam.

type UpstreamFunc

type UpstreamFunc func(connection string) (Upstream, error)

UpstreamFunc resolves a connection name to its authorized transport. The platform wires it to the api gateway; a test wires it to an httptest server.

type WebhookSender

type WebhookSender struct {
	// contains filtered or unexported fields
}

WebhookSender posts one {"text": ...} body to an incoming-webhook URL, the shape Slack and Mattermost both accept and the shape most other receivers of a "post this line somewhere" webhook understand.

The whole address is the connection's base_url, including the secret path segment an incoming webhook URL carries, so the kind sends to the base itself and names no path. That secret is the connection's to hold: a webhook URL is a bearer credential written as a URL, which is why the kind names a connection like the two token kinds rather than storing a URL of its own.

func NewWebhookSender

func NewWebhookSender(upstream UpstreamFunc) *WebhookSender

NewWebhookSender builds the webhook transport over upstream.

func (*WebhookSender) Send

Send posts the document to the webhook.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL