Wonderful SMTP Mailer and Log

Description

A small SMTP plugin that does three things and nothing else: it sends your mail
over SMTP, it writes down what happened, and it tells a webhook when a message
fails.

We built it because the SMTP plugin we had relied on for years kept growing.
More features, more integrations, more settings — most of which we simply
didn’t need. Eventually, that added complexity started causing problems on
production sites.

Many alternatives had gone the same way: email logs behind paid tiers, API
providers, OAuth flows, deliverability dashboards, upgrade banners, and entire
mail suites around what should be a simple job.

We wanted the opposite: connect to a mail server, send the email, log the
result, and stay out of the way.

Email is critical infrastructure. Every additional feature is another dependency
and another potential failure point — and when mail breaks, customers notice
immediately.

So we built the slim alternative we wanted ourselves, and we run it in our own
production environment and on our client sites.

What it does

  • Routes every wp_mail() call over your SMTP server — WooCommerce, contact
    forms, core password resets, all of it, without touching their code.
  • Host, port, encryption (STARTTLS, SSL/TLS or none), optional authentication.
  • Sender address and name, with an explicit switch for whether they override a
    sender another plugin already set.
  • A connection check that logs in to your mail server and hangs up without
    sending anything — the safe way to find out whether the settings are right.
  • A test message that shows you the actual SMTP conversation — when a server
    answers “535 5.7.139 Authentication unsuccessful”, you read that line instead
    of guessing.
  • A detail view for every logged message: the full server response, the headers,
    the attachments and the message body as source, so you can see exactly what a
    resend would deliver.
  • An email log: date, recipient, subject, status and the server’s response,
    with its own menu entry rather than another item buried under Settings.
  • A date range filter, so an entry from six months ago is two clicks away
    instead of forty pages down.
  • Full-text search across recipient, subject and message body, scoped to the
    period you filtered — “find the mail that mentioned invoice 0912”.
  • Attachments listed on every logged message, downloadable in one click and
    re-attached automatically when you resend.
  • Attachment storage — the part most email logs leave out. A log that records
    a filename cannot resend the file, and plenty of plugins delete theirs the
    moment the message is sent. Switch storage on and a copy is kept for as many
    days as you choose, in a directory that denies web access, so a message resent
    three weeks later still carries what it was sent with. Off by default, and
    every copy is deleted again on schedule.
  • Delivery counts for the filtered period, next to the all-time totals.
  • A resend button on every logged message, which asks before it sends and lets
    you correct the address first — the usual reason to resend is that the
    original one was mistyped.
  • A log-only mode that records every message and hands none of them to the
    mail server — the setting a staging site needs so a real customer can never
    receive anything.
  • A dashboard as the landing screen: delivery counts for the last seven days,
    the active delivery mode, and every setting with its current value and where
    it came from — the database, or a constant your docker-compose passed in.
  • An optional webhook that fires on failure, so Zapier, n8n, Make or your own
    endpoint can raise an alert.

What it deliberately does not do

No API providers, no OAuth, no fallback connections, no deliverability score, no
dashboard widget, no newsletter integration, no pro tier, no advertising for
one, and no upsell notices. If you need those, one of the big plugins will serve
you better, and that is a fine outcome.

Safety rails

  • With no SMTP host configured the plugin stays out of the way entirely and
    WordPress keeps using PHP mail() — installing it cannot take your email
    down.
  • Every setting can be defined as a constant in wp-config.php, following
    one mechanical rule: the option name in upper case. That keeps credentials out
    of the database and out of any dump copied to a staging site, and lets a Docker
    container pass them in as environment variables:

    define( ‘WONDERFUL_SMTP_MAILER_AND_LOG_HOST’, getenv( ‘SMTP_HOST’ ) );
    define( ‘WONDERFUL_SMTP_MAILER_AND_LOG_PASSWORD’, getenv( ‘SMTP_PASSWORD’ ) );

    A defined constant wins over the settings field, and the field is then shown
    read-only so the two cannot silently disagree.

  • No runtime dependencies. The plugin uses the PHPMailer that ships with
    WordPress itself — there is no vendor directory and nothing to keep patched.
  • The stored password is never written into the HTML of the settings form. A
    toggle next to the field fetches it on request, so it stays out of the page
    source, the browser cache and any screenshot until you deliberately ask.
  • Log-only mode is announced on every admin screen, not just this plugin’s own.
    It is a silent state by design — wp_mail() keeps reporting success — and the
    person who needs the warning is the one wondering why a customer never got
    their confirmation.
  • Stored attachments are deleted when the plugin is deactivated, not just when it
    is uninstalled — switching it off should not leave a folder of customer
    documents on the server.
  • “Force sender” is off by default, so plugins that set their own sender on
    purpose keep it.
  • Resending is a manual button. Nothing retries by itself, so a failing server
    can never turn into a mail loop.

How it is built

Development is test driven, and the suite covers the behaviour that decides
whether your mail actually leaves the building: that an unconfigured plugin keeps
its hands off PHPMailer entirely, that “none” really disables TLS instead of
quietly upgrading, that a sender another plugin set on purpose survives, that a
corrupt delivery-mode value falls back to sending rather than silently swallowing
your mail, that log-only mode never once reaches the mailer, that the retention
purge deletes what is past the cutoff and nothing else, and that a webhook fires
with the failure details but no credentials.

Those tests run together with the WordPress coding standards, a PHP 7.4
compatibility lint and WordPress.org’s own Plugin Check every single time, before
a release is built at all. An error in any of them stops the release — the
pipeline refuses, it is not a checklist someone waves through.

The tests themselves stay in the repository and are not part of this download.
Nothing ships here that your site does not need at runtime: a small set of PHP
classes and four assets, with no vendor directory and no framework.

That discipline is also why the feature list is short. Every feature is a promise
that has to keep working.

External services

This plugin contacts two kinds of external endpoints, both of which you
configure yourself. It has no vendor backend, sends no telemetry, and phones
home nowhere.

1. Your SMTP server

The host you enter in the settings receives your outgoing messages: sender,
recipients, subject, body, attachments, and — if authentication is enabled — the
username and password you configured. This is the entire purpose of the plugin.
Which company that server belongs to, and which terms and privacy policy apply,
is determined by you when you enter the host name. No connection is made until
you configure one.

2. Your failure webhook (optional, off by default)

If, and only if, you fill in the webhook field, a JSON request of the form
{“text”: “…”} is sent to that URL whenever a message fails. It contains your
site URL, the recipient address, the subject and the error the mail server
returned. It contains no message body and no credentials. Nothing is sent while
the field is empty. The receiving service is one you choose — Zapier, n8n, Make,
Slack or your own endpoint — and its terms and privacy policy apply to what you
send it.

Message contents and log entries stay in your own database. No data is
transmitted to Wonderful Plugins.

Screenshots

Installation

  1. Install and activate the plugin.
  2. Go to SMTP Mailer Settings in the admin menu.
  3. Enter host, port and encryption for your mail server. Port 587 with STARTTLS fits most providers.
  4. If your server requires a login, leave authentication enabled and fill in username and password. To keep the password out of the database, define WONDERFUL_SMTP_MAILER_AND_LOG_PASSWORD in wp-config.php instead.
  5. Set the sender address. Most providers reject a sender that differs from the account you authenticate with.
  6. Optionally add a webhook URL for failure alerts.
  7. Go to SMTP Mailer Testing and run the connection check. If it comes back green, send a test message from the same screen.

FAQ

I installed it but configured nothing. Did my email break?

No. Without an SMTP host the plugin does not touch outgoing mail at all and
WordPress keeps using PHP mail() exactly as before.

What is the difference between the connection check and the test message?

The connection check opens a session with your mail server, negotiates
encryption, logs in and hangs up. Nothing is sent and nothing is logged, so you
can run it as often as you like while you are getting the settings right. The
test message actually delivers an email and records it in the log, which also
proves that logging works.

The test message fails. What now?

Read the SMTP conversation printed underneath the error. It is the unedited
exchange with your mail server, and the reason is almost always in the last few
lines — wrong credentials, a blocked port, or a sender your provider will not
accept.

Where are my credentials stored?

In the WordPress options table, unless you define them as constants in
wp-config.php, which is what we recommend for production. The password is
never echoed back into the settings form.

Can I get an attachment back out of the log?

Yes. Open the message and click the attachment. The download only ever serves a
file this site itself attached to that logged email — the request names a log
entry and a position in its attachment list, never a path — and a resend
re-attaches whatever is still on disk. Files deleted since are marked as gone.

Why would I turn on attachment storage?

Because the log records where an attachment was, not the file itself. Some
plugins keep what they send — the well-known WooCommerce invoice plugins file
their PDFs away and can hand them back later. Plenty of others do not: form
uploads written to a temporary directory, one-off exports, reports generated for
a single send. Those are gone within the hour, and a resend then goes out without
them.

With storage on, a copy is kept regardless of what the sending plugin does, for
as many days as you choose.

Copies are off by default because they are customer documents sitting on disk.
When you turn them on they go into a directory that denies web access and carries
an index.php, and each file is stored under a random 32-character name with a
neutral .bin extension — so nothing there is guessable, and nothing there is
something a web server would execute even if the directory protection were
bypassed. The original filename lives in the database and is restored on
download. Files over 10 MB are never copied.

A daily job deletes copies past the period you set. Setting it to 0 keeps a copy
for as long as its log entry lives — deleting the entry always takes its copies
with it, so a file is never left on disk with no record pointing at it.
Deactivating the plugin deletes them all, and uninstalling removes the
directory. Once a copy is gone the
message shows the attachment struck through as no longer available, and warns you
before you resend rather than quietly sending it short.

Does the log store the message body?

Yes — it has to, otherwise the resend button could not work. Log entries live in
your own database and are deleted after the retention period you set, 30 days by
default. Set it to 0 to keep everything.

How do I find an old log entry?

Open SMTP Mailer Email Log and set the two date fields above the table.
The counters at the top follow the filter, so you also get the delivery numbers
for exactly the period you picked. Entries older than your retention setting are
gone for good, so pick that setting with the audit trail you want in mind.

How do I stop a staging site from mailing real customers?

Set Delivery mode to “Log only”. Every message is still recorded in full —
recipient, subject, headers and body — and none of them reaches the mail server.
wp_mail() still reports success, so plugins that check its return value behave
normally. Suppressed messages show up in the log as “Not sent” and are not
counted as delivered.

Does anything retry automatically?

No. Resending is always a deliberate click. That is intentional: automatic
retries against a misconfigured server are how a mail problem becomes a mail
flood.

Will this grow into a pro version later?

No. Staying small is the point of the plugin.

Reviews

There are no reviews for this plugin.

Contributors & Developers

“Wonderful SMTP Mailer and Log” is open source software. The following people have contributed to this plugin.

Contributors

Changelog

1.0.1

  • Connection test gives up after ten seconds instead of hanging when host,
    port or encryption are wrong, and says which of them do not match.
  • The test runs without reloading the screen, so you can see it working.
  • Resending from the log reloads the table, so the new entry is in it.

1.0.0

  • Initial release.