Lettermint.Emails (Lettermint v2.2.0)

Copy Markdown View Source

Sends email with the project sending token (x-lettermint-token).

Every function needs :sending_token on the client. Nothing about a message is stored on the client: every call sends exactly what it is given.

lettermint = Lettermint.new(sending_token: System.fetch_env!("LETTERMINT_PROJECT_TOKEN"))

{:ok, result} =
  Lettermint.Emails.send(lettermint, %{
    from: "Acme <hello@acme.com>",
    to: ["jane@example.com"],
    subject: "Welcome",
    html: "<p>Thanks for signing up.</p>"
  }, idempotency_key: "welcome-jane")

A message is a map in the API's field names (reply_to, scheduled_at, sandbox_result, ...) with atom or string keys, or a Lettermint.Types.SendMailRequest struct. For the pipe-friendly builder, see compose/2 and Lettermint.EmailBuilder.

Idempotency

The :idempotency_key option (the Idempotency-Key header) applies to the whole request. In send_batch/3, each email can also have its own idempotency_key field, so that a retried batch sends only the emails that were not accepted yet; see send_batch/3.

Attachments

An attachment is a map with :filename, :content, and optionally :content_type and :content_id. content is base64 text, as the API expects it, or {:bytes, binary} with the raw bytes, which the SDK base64-encodes:

attachments: [
  %{filename: "invoice.pdf", content: {:bytes, File.read!("invoice.pdf")}, content_type: "application/pdf"},
  %{filename: "logo.png", content: logo_base64, content_id: "logo"}
]

Tags

tags holds up to 20 name/value tags (19 when the legacy tag is also set). Names match ^[A-Za-z0-9_-]{1,32}$, must not start with __lettermint and must be unique (case-sensitive); values match ^[A-Za-z0-9_-]{1,64}$. The SDK checks this before the request and returns Lettermint.ClientValidationError.

Summary

Types

An email of a batch: a message/0 or a Lettermint.Types.SendBatchMailItem struct, optionally with a per-email idempotency_key field.

An email: a map in the API's field names, or a SendMailRequest struct.

:idempotency_key (sent as Idempotency-Key) and :timeout (milliseconds).

Functions

Starts an immutable email builder. Pass a message to start from it.

Checks the sending token: GET /ping returns "pong".

Sends up to 500 emails in one request. The list may mix messages and builders. Takes the options of send/3.

Types

batch_message()

@type batch_message() :: message() | Lettermint.Types.SendBatchMailItem.t()

An email of a batch: a message/0 or a Lettermint.Types.SendBatchMailItem struct, optionally with a per-email idempotency_key field.

message()

@type message() :: map() | Lettermint.Types.SendMailRequest.t()

An email: a map in the API's field names, or a SendMailRequest struct.

send_options()

@type send_options() :: [idempotency_key: String.t(), timeout: pos_integer()]

:idempotency_key (sent as Idempotency-Key) and :timeout (milliseconds).

Functions

compose(client, message \\ nil)

@spec compose(Lettermint.Client.t(), message() | nil) :: Lettermint.EmailBuilder.t()

Starts an immutable email builder. Pass a message to start from it.

Raises Lettermint.ConfigError when the client has no sending token, and Lettermint.ClientValidationError when message is invalid.

ping(client, options \\ [])

@spec ping(Lettermint.Client.t(), [{:timeout, pos_integer()}]) ::
  {:ok, String.t()} | {:error, Lettermint.Error.t()}

Checks the sending token: GET /ping returns "pong".

send(client, message, options \\ [])

Sends one email.

Options: :idempotency_key (retrying with the same key does not send the email again) and :timeout in milliseconds.

send_batch(client, messages, options \\ [])

Sends up to 500 emails in one request. The list may mix messages and builders. Takes the options of send/3.

Each email can have its own idempotency_key (1 to 255 characters, unique within the batch): set the field on a message, or use Lettermint.EmailBuilder.idempotency_key/2. A nil key counts as no key. If an email with the same key and content was accepted in the last 24 hours, the API returns its original result and does not send it again. Reusing a key with different content, or while the email with that key is still being processed, rejects the whole batch with Lettermint.ConflictError (code IDEMPOTENCY_CONFLICT) and sends nothing.

Emails are accepted in order. When one fails, the emails before it may already be accepted; the error's details["accepted"] then lists them, each with its "index" in the batch and its "message_id". Retry the batch with the same per-email keys to send only the rest.

Lettermint.Emails.send_batch(lettermint, [
  %{from: "hello@acme.com", to: ["jane@example.com"], subject: "Hi", text: "…", idempotency_key: "order-1"},
  %{from: "hello@acme.com", to: ["john@example.com"], subject: "Hi", text: "…", idempotency_key: "order-2"}
])