emdash-mail

README snapshot of emdash-mail.

EmDash Mail

EmDash Mail is a small, production-minded EmDash plugin for outbound transactional email delivery. It is the general mail pipeline plugin for EmDash system mail and other plugin- or core-generated email, distinct from form-mailer.

Plugin/package ID: emdash-mail

What It Does

EmDash Mail owns outgoing delivery for EmDash-generated email such as:

  • invitations
  • magic links
  • password reset or recovery
  • other transactional mail emitted through EmDash's email pipeline

It does not:

  • collect public form submissions
  • provide form spam protection
  • implement newsletter or campaign tooling
  • replace form-mailer

form-mailer remains the narrow public-form plugin. EmDash Mail is the general outbound delivery layer.

Current v1 Provider Scope

Implemented now:

  • console
  • zeptomail

Present in settings but intentionally not implemented yet:

  • cloudflare

Cloudflare Worker binding delivery is planned as an optional companion plugin because the currently verified EmDash standard-plugin runtime does not expose a confirmed binding path for a sandboxed email:deliver transport plugin.

EmDash Integration Model

This plugin is an EmDash email provider plugin:

  • capability: email:provide
  • hook: email:deliver

EmDash core or other plugins call the email pipeline. This plugin is the transport provider selected for delivery.

Capabilities

  • email:provide Registers the exclusive email:deliver provider hook.
  • network:fetch Used for ZeptoMail's HTTP API.

Allowed hosts are intentionally narrow:

  • api.zeptomail.com

Installation

Marketplace install

  1. Install EmDash Mail from the EmDash marketplace.
  2. Enable the plugin in your EmDash site.
  3. Open the plugin settings page at EmDash Mail.
  4. Save sender and provider settings.
  5. If your site exposes EmDash's global email-provider selection, select emdash-mail as the active provider plugin.

Local/dev install

import { defineConfig } from "emdash";
import { emdashMailPlugin } from "emdash-mail";

export default defineConfig({
  plugins: [emdashMailPlugin()]
});

Then:

  1. Run npm install
  2. Run npm run build
  3. Start your EmDash site with the plugin enabled

Build artifacts are written to:

  • dist/index.mjs
  • dist/sandbox-entry.mjs

Settings

  • Enable plugin Master kill switch for delivery.
  • Provider console, zeptomail, or cloudflare placeholder.
  • Sender name Optional display name for outgoing mail.
  • Sender address Required sender address.
  • Default reply-to address Optional reply-to applied by providers that support it.
  • Test recipient address Used by the admin test-send flow.
  • Subject prefix Optional prefix prepended to subjects.
  • ZeptoMail API key One-way write secret.

Secrets are never rendered back into the UI. The admin page only shows whether a secret is stored.

Local Development

Recommended path:

  • use provider console

The console provider never sends real mail. It writes structured logs and returns a fake message ID, which makes it suitable for local development and system tests.

ZeptoMail Setup

  1. Verify your sending domain in ZeptoMail.
  2. Create an API key in ZeptoMail.
  3. Save the API key in the EmDash Mail admin settings.
  4. Set provider to zeptomail.
  5. Run the test-send flow from the admin page.

EmDash Mail only fetches https://api.zeptomail.com.

Cloudflare Status

Cloudflare Email Service itself can support both Workers bindings and a REST API. Official docs:

This standard plugin does not directly implement Cloudflare Worker binding delivery. The intended product shape is:

  • keep emdash-mail as the marketplace/catalog-safe mail plugin
  • add Cloudflare Worker binding delivery through an optional native companion plugin

Planned companion repo:

If we later decide to support Cloudflare REST API mode inside the standard plugin, that should be a separate provider mode with explicit API-token settings and documentation.

Logging and Runtime Notices

Successful sends log structured metadata with ctx.log.info().

Failed sends:

  • log structured errors with ctx.log.error()
  • persist a sanitized admin-visible runtime notice
  • expire that notice after 7 days

Troubleshooting

Plugin disabled

Enable the plugin in settings before using it as the active provider.

ZeptoMail selected but no API key stored

Store a ZeptoMail API key in the settings page.

Cloudflare selected

Cloudflare Worker binding delivery requires the optional native companion plugin.

Test send fails

Check:

  • plugin enabled
  • valid sender address
  • valid test recipient address
  • provider-specific credentials

Relationship to form-mailer

form-mailer is for public form submission handling.

EmDash Mail is for outbound mail delivery.

If EmDash core or another plugin emits email because of a form workflow, EmDash Mail can still be the transport provider. It simply does not own the form workflow itself.