email

package
v0.5.0 Latest Latest
Warning

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

Go to latest
Published: Oct 27, 2026 License: Apache-2.0 Imports: 10 Imported by: 0

Documentation

Overview

Package email provides SendGrid transactional email integration for workflows. It lets workflows send transactional emails via SendGrid, and exposes HostCall functions callable from WASM workflow code.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func New

func New() plugin.Plugin

New creates a new Plugin instance.

Types

type CheckStatusInput added in v0.4.0

type CheckStatusInput struct {
	MessageID string `json:"message_id"`
}

type CheckStatusOutput added in v0.4.0

type CheckStatusOutput struct {
	Status string        `json:"status"`
	Events []StatusEvent `json:"events"`
}

type Config

type Config struct {
	Enabled     bool   `json:"email_enabled"`
	DefaultFrom string `json:"default_from,omitempty"`
}

Config holds optional configuration for the email plugin.

SendGridAPIKey lived here until cleat#1992 part 1 moved it to a deployment secret ("email.sendgrid_api_key") so it can be rotated with `cleatctl set-deployment-secret` and take effect without a worker restart. See sendGridAPIKey (host_functions.go) for the per-call lookup that replaced the cached apiKey field this struct used to carry.

Enabled is new, and load-bearing for enablement now in a way DefaultFrom never was. env.Config is the SAME raw --plugin-config bytes every plugin's Init receives (cmd/cleat-worker/main.go builds one Environment and copies it per plugin, Config included) -- there is no per-plugin section, only a flat object every plugin's own Config struct picks its own field names out of. Before cleat#1992, "config non-empty" WAS an email-specific signal, because a non-empty config with no sendgrid_api_key was a hard error ("sendgrid_api_key is required"), so an llm-only deployment simply never set one. Once the key moved out of Config entirely, that fell away: any worker with ANY --plugin-config -- for llm, for any other plugin, for nothing email cares about -- made len(env.Config) == 0 false, so email read itself as configured and checkRequiredDeploymentSecrets then refused to start the whole worker over a missing email.sendgrid_api_key nobody asked for. Found in cleat-review's #2202 pass. A prefixed name, not a bare "enabled": this struct is unmarshaled from the SAME shared blob every other plugin's Config is, so a bare field name is one any other plugin could also define and collide with by accident.

type Plugin

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

Plugin implements SendGrid email sending for workflows.

func (*Plugin) DeploymentSecretPrefix added in v0.3.0

func (p *Plugin) DeploymentSecretPrefix() string

DeploymentSecretPrefix implements plugin.HasDeploymentSecretPrefix: email only ever reads "email.sendgrid_api_key".

func (*Plugin) Info

func (p *Plugin) Info() plugin.PluginInfo

Info returns plugin metadata for discovery and documentation.

func (*Plugin) Init

func (p *Plugin) Init(ctx context.Context, env *plugin.Environment) error

Init initializes the plugin with the given environment.

It no longer reads a SendGrid API key: that moved to a deployment secret (cleat#1992 part 1), fetched fresh on every call by sendGridAPIKey in host_functions.go rather than cached here. Enablement is decided by Config.Enabled ("email_enabled" in --plugin-config), not by config-section presence -- see Config's doc comment for why len(env.Config) == 0 alone stopped being a safe signal once sendgrid_api_key left this struct. plugin.ErrNotConfigured is how a disabled email says so quietly rather than logging ERROR on every stock start. Whether the deployment secret itself is set is checked separately, at worker boot, by the fail-closed check setup.go runs over every enabled plugin's RequiredDeploymentSecrets.

func (*Plugin) RegisterHostFunctions

func (p *Plugin) RegisterHostFunctions(scope plugin.FuncRegistry) error

RegisterHostFunctions registers workflow-callable functions on the scoped function registry. The plugin name is implicit -- each plugin gets its own scope, so function names need not be globally unique.

func (*Plugin) RequiredDeploymentSecrets added in v0.3.0

func (p *Plugin) RequiredDeploymentSecrets(config []byte) ([]string, error)

RequiredDeploymentSecrets implements plugin.HasRequiredDeploymentSecrets. Unconditional: this is only consulted for a plugin Init already accepted (a config section is present), and every call this plugin serves needs the SendGrid key, so there is no enabled-but-key-optional case to encode here.

type SendInput added in v0.4.0

type SendInput struct {
	To       string   `json:"to"`
	Subject  string   `json:"subject"`
	BodyHTML string   `json:"body_html"`
	BodyText string   `json:"body_text,omitempty"`
	From     string   `json:"from,omitempty"`
	ReplyTo  string   `json:"reply_to,omitempty"`
	CC       []string `json:"cc,omitempty"`
	BCC      []string `json:"bcc,omitempty"`
}

type SendOutput added in v0.4.0

type SendOutput struct {
	MessageID string `json:"message_id"`
	Status    string `json:"status"`
}

type SendTemplateInput added in v0.4.0

type SendTemplateInput struct {
	To           string         `json:"to"`
	TemplateID   string         `json:"template_id"`
	TemplateData map[string]any `json:"template_data"`
	From         string         `json:"from,omitempty"`
	ReplyTo      string         `json:"reply_to,omitempty"`
}

type SendTemplateOutput added in v0.4.0

type SendTemplateOutput struct {
	MessageID string `json:"message_id"`
	Status    string `json:"status"`
}

type StatusEvent added in v0.4.0

type StatusEvent struct {
	Timestamp string `json:"timestamp"`
	Event     string `json:"event"`
}

Jump to

Keyboard shortcuts

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