gizlang:mail
the one way a program sends mail. A mailer is one URL that names the transport, its credentials and the sender, so a person sets it once (an environment variable, a settings field) and the program never branches on the provider:
smtp://USER:PASSWORD@HOST[:587]?from=SENDER SMTP, upgraded with STARTTLS (plain only to this machine) smtps://USER:PASSWORD@HOST[:465]?from=SENDER SMTP over TLS from the first byte ses://ACCESS:SECRET@REGION?from=SENDER[&configuration=SET] Amazon SES (API v2, SigV4) resend://KEY@resend?from=SENDER Resend's API
The user name, password and key are percent-encoded in the URL. A message is plain text, with an HTML part when it has one; a sign-in or share link is never rewritten for click tracking. An error says what failed, never the body, the recipient, a credential or the provider's answer.
import * as Mail from "gizlang:mail";Types
Mailer
type Mailer = { scheme: string; host: string; port: i64; user: string; secret: string; from: string; configuration: string; }A transport: its scheme ("smtp", "smtps", "ses" or "resend"), host (an SES region), port, user (an access key),
secret (a password, an SES secret key, an API key), the sender (from: an address, or "Name <address>") and the
SES configuration set ("": none).
scheme:stringhost:stringport:i64user:stringsecret:stringfrom:stringconfiguration:string
Message
type Message = { to: string; subject: string; text: string; html: string; key: string; }One message: the recipient, the subject, the text, an HTML part ("": none) and a key that makes a retry the same message where the transport supports it ("": none).
to:stringsubject:stringtext:stringhtml:stringkey:string
Transport
type Transport = (host: string, request: Request) => Result<Response, string>An HTTP exchange with host over TLS: the network, or a test's stand-in.
Functions
message
function message(to: string, subject: string, text: string): MessageA plain text message.
mailer
function mailer(url: string): Result<Mailer, string>The mailer of URL url, or why it is not one.
Effects: fail.
address
function address(to: string): boolWhether to is one email address that cannot carry another header.
Effects: fail.
send
function send(sys: System, mailer: Mailer, m: Message): Result<string, string>Sends m with mailer over the network: the provider's message id ("" when SMTP gives none), or why not.
Effects: fail, read, write, console, io.
sendWith
function sendWith(mailer: Mailer, now: i64, m: Message, transport: Transport): Result<string, string>Sends m with an HTTP mailer (ses, resend) at time now (ms) through transport.
Effects: fail, read, write, console, io.
Constants
NOT_CONFIGURED
const NOT_CONFIGURED = "Email is not configured."What a program says when no mailer is set.