Liking cljdoc? Tell your friends :D

dev.arkaitz.sendmail-base

Email for an application: build a mailer from configuration once, then send! a message with it.

(def mailer (mail/mailer {:transport :console :from "noreply@example.com"}))
(mail/send! mailer {:to "ada@example.com" :subject "Hello" :text "…"})

Two transports, chosen by :transport:

  • :console prints the whole message — headers and body — to *out* and sends nothing. It is for development, where a sign-in link should be readable in the terminal: in production it would put credentials in the logs, which the host refuses (this library cannot know what production is).
  • :smtp delivers through a submission server with this library's own client (dev.arkaitz.sendmail-base.smtp, SPEC §5): TLS always, a required wall-clock deadline on every send, and refusals that never echo a recipient, a server's text or a password.

A mailer is a value. It holds no connection and no thread: every send! connects, delivers one message and closes, inside its deadline.

Email for an application: build a mailer from configuration once, then `send!` a
message with it.

    (def mailer (mail/mailer {:transport :console :from "noreply@example.com"}))
    (mail/send! mailer {:to "ada@example.com" :subject "Hello" :text "…"})

Two transports, chosen by `:transport`:
- `:console` prints the whole message — headers and body — to `*out*` and sends
  nothing. It is for development, where a sign-in link should be readable in the
  terminal: in production it would put credentials in the logs, which the host
  refuses (this library cannot know what production is).
- `:smtp` delivers through a submission server with this library's own client
  (`dev.arkaitz.sendmail-base.smtp`, SPEC §5): TLS always, a required wall-clock
  deadline on every send, and refusals that never echo a recipient, a server's text
  or a password.

A mailer is a value. It holds no connection and no thread: every `send!` connects,
delivers one message and closes, inside its deadline.
raw docstring

dev.arkaitz.sendmail-base.integrant

Optional: requiring this namespace installs one Integrant key, :dev.arkaitz.sendmail-base/mailer, whose value is (mailer config). There is no halt-key!: a mailer holds no connection and no thread, so there is nothing to close.

{:dev.arkaitz.sendmail-base/mailer {:transport :smtp :host "smtp.example.com"
                                    :port 587 :tls :starttls
                                    :user "app" :password #wb/env "SMTP_PASSWORD"
                                    :from "noreply@example.com" :deadline-ms 10000}}

A refusal names its key and never the value; but Integrant's own failure carries the whole resolved configuration of the key that threw, password included, so a host logs the cause and never the exception Integrant threw.

Optional: requiring this namespace installs one Integrant key,
`:dev.arkaitz.sendmail-base/mailer`, whose value is `(mailer config)`. There is no
`halt-key!`: a mailer holds no connection and no thread, so there is nothing to
close.

    {:dev.arkaitz.sendmail-base/mailer {:transport :smtp :host "smtp.example.com"
                                        :port 587 :tls :starttls
                                        :user "app" :password #wb/env "SMTP_PASSWORD"
                                        :from "noreply@example.com" :deadline-ms 10000}}

A refusal names its key and never the value; but Integrant's own failure carries the
whole resolved configuration of the key that threw, password included, so a host
logs the cause and never the exception Integrant threw.
raw docstring

No vars found in this namespace.

dev.arkaitz.sendmail-base.smtp

The SMTP submission client: one message per connection, over TLS, inside one wall-clock deadline (SPEC §5).

The deadline is a watchdog, not a timeout per call. A virtual thread closes the socket when the deadline passes, which makes whatever is blocked — the connect, the TLS handshake, a read, a write — throw at once. A timeout per read would let a server that drips one byte at a time hold a send for ever; a socket write has no timeout at all. Name resolution, which no socket bounds, runs on a thread of its own and is waited for only until the deadline.

What a failure says. The stage it happened at and the server's reply code — refused at RCPT with 550 — and never the recipient, the server's own text, the message or a password: the caller logs what it is given (auth-base logs a delivery failure whole), and a reply such as 550 <ada@…> unknown carries the address.

The SMTP submission client: one message per connection, over TLS, inside one
wall-clock deadline (SPEC §5).

**The deadline is a watchdog, not a timeout per call.** A virtual thread closes the
socket when the deadline passes, which makes whatever is blocked — the connect, the
TLS handshake, a read, a write — throw at once. A timeout per read would let a
server that drips one byte at a time hold a send for ever; a socket write has no
timeout at all. Name resolution, which no socket bounds, runs on a thread of its own
and is waited for only until the deadline.

**What a failure says.** The stage it happened at and the server's reply code —
`refused at RCPT with 550` — and never the recipient, the server's own text, the
message or a password: the caller logs what it is given (auth-base logs a delivery
failure whole), and a reply such as `550 <ada@…> unknown` carries the address.
raw docstring

dev.arkaitz.sendmail-base.testing

For a host's tests, never its configuration: a mailer that keeps what it was handed. send! checks a message before any transport sees it, so what the recorder keeps is exactly what SMTP would have been given, and what it refuses SMTP would have refused. Built in code only — EDN cannot make one — so no configuration can turn a production mailer into one that delivers nothing.

For a host's tests, never its configuration: a mailer that keeps what it was handed.
`send!` checks a message before any transport sees it, so what the recorder keeps is
exactly what SMTP would have been given, and what it refuses SMTP would have refused.
Built in code only — EDN cannot make one — so no configuration can turn a production
mailer into one that delivers nothing.
raw docstring

cljdoc builds & hosts documentation for Clojure/Script libraries

Keyboard shortcuts
Ctrl+kJump to recent docs
←Move to previous article
→Move to next article
Ctrl+/Jump to the search field
× close