Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
858868f338 |
@@ -1,5 +1,39 @@
|
|||||||
# Nolimit Send: releases
|
# Nolimit Send
|
||||||
|
|
||||||
This repository holds the release zips for the Nolimit Send WordPress plugin, and nothing else. WordPress reads it to offer updates.
|

|
||||||
|
|
||||||
Download the latest zip from Releases.
|
Chooses how WordPress and WooCommerce send email. Pick SMTP2GO, Brevo, Mailgun,
|
||||||
|
SendGrid, Postmark, Amazon SES, Google or Microsoft — or type in any SMTP
|
||||||
|
server — and every message the site sends goes through it. One screen, no
|
||||||
|
account, no telemetry, no paid tier.
|
||||||
|
|
||||||
|
## Install
|
||||||
|
|
||||||
|
1. Download `nolimit-send.zip` from the [latest release](https://gitea.nolimit.dk/kw/nolimit-send-dist/releases/latest).
|
||||||
|
2. **Plugins → Add New → Upload Plugin**, then activate.
|
||||||
|
3. Open **Send** in the Nolimit menu, pick a provider, and press
|
||||||
|
*Send a test message* — [the setup guide](docs/SETUP.md) says what each
|
||||||
|
provider wants in the password field.
|
||||||
|
|
||||||
|
Nothing is sent through it until you switch it on. Later versions arrive in
|
||||||
|
**Dashboard → Updates** like any other plugin.
|
||||||
|
|
||||||
|
## Documentation
|
||||||
|
|
||||||
|
- [Overview](docs/README.md) — what it does, and what it deliberately does not
|
||||||
|
- [Setting it up, and knowing it works](docs/SETUP.md) — provider by provider,
|
||||||
|
how to check a message really went through your provider, and what to do
|
||||||
|
when mail stops
|
||||||
|
- [Hooks and integration](docs/CONTRACT.md) — for developers: what the plugin
|
||||||
|
hooks into, what it stores, and what it leaves alone
|
||||||
|
|
||||||
|
## More of it
|
||||||
|
|
||||||
|
| | |
|
||||||
|
|---|---|
|
||||||
|
|  | **Honest about Microsoft 365.** Password sign-in for SMTP is being retired and this plugin does not do OAuth, so the Microsoft preset says so on the screen instead of working until it quietly stops. |
|
||||||
|
|  | **The server's own answer.** A failed test shows what the mail server said, and the last real failure is kept with its time, so "why did that email not arrive" has an answer. |
|
||||||
|
|  | **No pretending.** SMTP hands a message over; it cannot report bounces or spam complaints. The screen says what a test proves and what only your provider's dashboard can tell you. |
|
||||||
|
|
||||||
|
Requires WordPress 5.9+ and PHP 7.4+. WooCommerce is not required, but it is
|
||||||
|
what the plugin is tested against.
|
||||||
|
|||||||
Binary file not shown.
|
After Width: | Height: | Size: 101 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 96 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 118 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 89 KiB |
@@ -0,0 +1,198 @@
|
|||||||
|
# The surface Nolimit Send exposes
|
||||||
|
|
||||||
|
<!-- nlsnd:version 0.1.0 -->
|
||||||
|
|
||||||
|
Everything another plugin, a theme or a site owner can bind to, store against,
|
||||||
|
or break by changing. It describes what the installed plugin actually does, not
|
||||||
|
what it might one day do: a table written from intent lists what a plugin means
|
||||||
|
to provide rather than what it provides.
|
||||||
|
|
||||||
|
The contract covers the files inside the installed plugin. Nothing else is part
|
||||||
|
of it.
|
||||||
|
|
||||||
|
## Hooks this plugin provides
|
||||||
|
|
||||||
|
**None.** This plugin fires no `do_action()` and applies no `apply_filters()`
|
||||||
|
of its own, so there is nothing here for anyone to hook.
|
||||||
|
|
||||||
|
That is a deliberate state rather than an oversight, and it is worth one line
|
||||||
|
so nobody adds one casually: every extension point is a promise that outlives
|
||||||
|
the reason it was added, and nothing has yet asked to extend this. In
|
||||||
|
particular there is no filter that lets another plugin change the SMTP
|
||||||
|
settings — that is exactly the door a credential leaks through. The moment
|
||||||
|
something does ask, the filter goes in this table in the same commit.
|
||||||
|
|
||||||
|
<!-- nlsnd:hooks:start -->
|
||||||
|
|
||||||
|
## Hooks this plugin registers on
|
||||||
|
|
||||||
|
🔴 Deliberately not headed "consumes". `add_filter()` is how you **answer** a
|
||||||
|
filter — you supply the value somebody else asked for — and reading it as
|
||||||
|
consumption gets the direction of the promise backwards. For an action the
|
||||||
|
word is *listens*; for a filter it is *answers*. The Kind column below says
|
||||||
|
which.
|
||||||
|
|
||||||
|
Priority and accepted-argument count are given where they are not WordPress'
|
||||||
|
defaults of `10` and `1`, because those two are what break silently — see the
|
||||||
|
`update_plugins_` row.
|
||||||
|
|
||||||
|
| Hook | Kind | Registered in | Why |
|
||||||
|
| --- | --- | --- | --- |
|
||||||
|
| `phpmailer_init` | action | `includes/class-mailer.php` | The whole job: points PHPMailer at the chosen server. Does nothing unless enabled, with a host, and no other mail plugin present. |
|
||||||
|
| `wp_mail_failed` | action | `includes/class-mailer.php` | Keeps the reason a message failed — time and message only — when this plugin was the one sending. |
|
||||||
|
| `wp_mail_from` | filter, priority 99 | `includes/class-mailer.php` | The sender address. 99 so WooCommerce's own callback at 10 has already had its say. |
|
||||||
|
| `wp_mail_from_name` | filter, priority 99 | `includes/class-mailer.php` | The sender name, on the same rule. |
|
||||||
|
| `plugins_loaded` | action | `includes/class-plugin.php` | Everything else is registered from here. |
|
||||||
|
| `admin_menu` | action | `includes/class-admin.php` | Registers the screen under the shared Nolimit menu. |
|
||||||
|
| `admin_init` | action | `includes/class-admin.php` | Handles the save, test and clear form posts, after the nonce and capability checks. |
|
||||||
|
| `admin_init` | action | `includes/class-updater.php` | Drops the cached feed when the user presses "Check again". |
|
||||||
|
| `admin_enqueue_scripts` | action | `includes/class-admin.php` | The one stylesheet, on this plugin's screen only. |
|
||||||
|
| `admin_post_nlsnd_auto_update` | action | `includes/class-auto-update.php` | The auto-update toggle's form target. Name is this plugin's; the hook is WordPress'. |
|
||||||
|
| `plugin_action_links_<basename>` | filter | `includes/class-admin.php` | The "Settings" link on the Plugins screen. Hook name is built from `NLSND_PLUGIN_BASENAME`. |
|
||||||
|
| `plugins_api` | filter, 3 args | `includes/class-updater.php` | The "View details" panel. Guarded on `$args->slug`. |
|
||||||
|
| `update_plugins_<hostname>` | filter, 3 args | `includes/class-updater.php` | Offers this plugin's own updates. |
|
||||||
|
| `upgrader_process_complete` | action, 0 args | `includes/class-updater.php` | Forgets the cached feed after any update runs. |
|
||||||
|
|
||||||
|
`send_test()` also adds and removes a `wp_mail_failed` listener around one
|
||||||
|
`wp_mail()` call, so the test button can say why a message did not go out. It
|
||||||
|
is removed again on the way out.
|
||||||
|
|
||||||
|
**Nothing hooks `wp_mail` itself.** No filter here can alter a message's
|
||||||
|
recipient, subject, body, headers or attachments, and the plugin's own checks
|
||||||
|
assert that `wp_mail` has no callback from it. That is the property that lets
|
||||||
|
the plugin be site-wide: it configures the transport and leaves the message
|
||||||
|
alone.
|
||||||
|
|
||||||
|
### 🔴 `update_plugins_<hostname>` is shared, and the argument count is load-bearing
|
||||||
|
|
||||||
|
The hook name is built from the **host**, not the repository, so every plugin
|
||||||
|
updating from `gitea.nolimit.dk` lands on the same filter and WordPress runs
|
||||||
|
every callback on it for every one of them. Answering unconditionally offers
|
||||||
|
this plugin's release to a sibling — which has happened on a live shop, and
|
||||||
|
installs a stranger's zip over a plugin with auto-updates on.
|
||||||
|
|
||||||
|
The defence is two halves and neither works alone: `add_filter( …, 10, 3 )`
|
||||||
|
**and** a guard returning `$update` untouched when `$plugin_file` is not this
|
||||||
|
plugin's basename. Leave the count at `2` and the third argument never
|
||||||
|
arrives, so the guard compares against an empty string and silently does
|
||||||
|
nothing — the same bug it was written to prevent, wearing a fix's clothes.
|
||||||
|
|
||||||
|
A test on a site with one plugin from that host cannot see this, because the
|
||||||
|
collision cannot arise there. The way to check it is to fire the real filter in
|
||||||
|
both directions: the neighbour is left alone, **and** this plugin still answers
|
||||||
|
for itself. The second half is not redundant. A guard that bails on everything
|
||||||
|
also leaves the neighbour alone.
|
||||||
|
|
||||||
|
## The family's shared hooks
|
||||||
|
|
||||||
|
These are the Nolimit-family surface, not this plugin's.
|
||||||
|
|
||||||
|
| Hook | This plugin's relationship | Where |
|
||||||
|
| --- | --- | --- |
|
||||||
|
| `wpmgr_dashboard_cards` | **answers** — supplies this plugin's card | `includes/class-admin.php` |
|
||||||
|
| `wpmgr_dashboard_cards` | applied by the shared file this plugin ships | `includes/shared-menu.php` |
|
||||||
|
| `wpmgr_menu_title` | applied by the shared file this plugin ships | `includes/shared-menu.php` |
|
||||||
|
| `wpmgr_menu_glyph` | applied by the shared file this plugin ships | `includes/shared-menu.php` |
|
||||||
|
| `admin_head` | listened to by the shared file this plugin ships | `includes/shared-menu.php` |
|
||||||
|
|
||||||
|
<!-- nlsnd:hooks:end -->
|
||||||
|
|
||||||
|
### 🔴 Shipping a file is not owning its hooks
|
||||||
|
|
||||||
|
`includes/shared-menu.php` is byte-identical across the Nolimit plugins.
|
||||||
|
Whichever copy loads **first** declares the functions; every later copy sees
|
||||||
|
them already defined and does nothing. So the three `wpmgr_*`
|
||||||
|
filters above are applied by *a* copy of that file, which on any real site is
|
||||||
|
probably another plugin's. Anyone depending on those filters should depend on
|
||||||
|
the family, not on this plugin being installed.
|
||||||
|
|
||||||
|
The card this plugin answers with carries `title`, `status`, `headline`,
|
||||||
|
`lines`, `url`, `action` and `colour`. `colour` is `NLSND_COLOUR`, which the
|
||||||
|
shared file paints as a card header with white text.
|
||||||
|
|
||||||
|
## The provider table — shared with Nolimit Forms
|
||||||
|
|
||||||
|
`NLSND_Mailer::providers()` is **hand-copied** from `NLFRM_Mailer::providers()`
|
||||||
|
in Nolimit Forms, which has an SMTP mailer of its own. Nothing shares the code
|
||||||
|
across the two plugins, so a difference between the copies is a defect that
|
||||||
|
neither plugin can see. The values that must agree, by id:
|
||||||
|
|
||||||
|
| Id | Host | Port | Encryption |
|
||||||
|
| --- | --- | --- | --- |
|
||||||
|
| `brevo` | `smtp-relay.brevo.com` | 587 | tls |
|
||||||
|
| `smtp2go` | `mail.smtp2go.com` | **2525** | tls |
|
||||||
|
| `mailgun` | `smtp.mailgun.org` | 587 | tls |
|
||||||
|
| `sendgrid` | `smtp.sendgrid.net` | 587 | tls |
|
||||||
|
| `postmark` | `smtp.postmarkapp.com` | 587 | tls |
|
||||||
|
| `ses` | *(none — region-specific, typed in)* | 587 | tls |
|
||||||
|
| `google` | `smtp.gmail.com` | 587 | tls |
|
||||||
|
| `microsoft` | `smtp.office365.com` | 587 | tls |
|
||||||
|
| `custom` | *(none — typed in)* | 587 | tls |
|
||||||
|
|
||||||
|
Cautions such as the Microsoft one are kept out of the table on purpose
|
||||||
|
(`NLSND_Mailer::warning()`), so one can change without touching the contract.
|
||||||
|
|
||||||
|
**Both plugins hook `phpmailer_init`.** With both switched on, the later
|
||||||
|
callback wins. Nolimit Forms is told this plugin is present by the constant
|
||||||
|
`NLSND_VERSION`, which is defined at include time for exactly that reason.
|
||||||
|
Nolimit Send reports Forms' SMTP on its own screen as a notice rather than
|
||||||
|
standing down for it.
|
||||||
|
|
||||||
|
## Stored data
|
||||||
|
|
||||||
|
Every row here is removed by `uninstall.php` on delete — not on deactivate,
|
||||||
|
because switching a plugin off for ten seconds to test something must not
|
||||||
|
destroy the shop's mail settings.
|
||||||
|
|
||||||
|
| Key | Kind | Holds |
|
||||||
|
| --- | --- | --- |
|
||||||
|
| `nlsnd_settings` | option, not autoloaded | Every setting, including the SMTP password as typed. |
|
||||||
|
| `nlsnd_last_failure` | option | The last delivery failure: a time and a message capped at 400 characters. |
|
||||||
|
| `nlsnd_release_feed` | transient, 15 min | The cached update feed. |
|
||||||
|
| `nlsnd_auto_update_seeded` | option | A marker, so the auto-update default is offered once and never re-applied. |
|
||||||
|
|
||||||
|
The password is stored in clear because WordPress has nowhere to keep a secret;
|
||||||
|
anyone who can read the options table can read it. It is never rendered back
|
||||||
|
into a form. Mail content — recipient, subject, body — is **never** stored, and
|
||||||
|
there is no send log.
|
||||||
|
|
||||||
|
## Capabilities
|
||||||
|
|
||||||
|
| Capability | Gates |
|
||||||
|
| --- | --- |
|
||||||
|
| `manage_options` | Seeing the screen, saving settings, sending a test, clearing the last failure. |
|
||||||
|
| `update_plugins` | The auto-update toggle only. WordPress' own capability for the same decision. |
|
||||||
|
|
||||||
|
## Constants
|
||||||
|
|
||||||
|
`NLSND_VERSION`, `NLSND_PLUGIN_FILE`, `NLSND_PLUGIN_DIR`, `NLSND_PLUGIN_URL`,
|
||||||
|
`NLSND_PLUGIN_BASENAME`, `NLSND_COLOUR`.
|
||||||
|
|
||||||
|
`NLSND_VERSION` has a reader outside this repository: Nolimit Forms asks whether
|
||||||
|
it is defined. It must stay defined at include time, not from a hook.
|
||||||
|
|
||||||
|
`NLSND_COLOUR` (`#556b0f`) is the other one with a reader outside this
|
||||||
|
plugin: the shared menu paints it as a dashboard card background with
|
||||||
|
hardcoded white text, which it measures at 6.01:1 against white, over the 4.5:1
|
||||||
|
the 14px label needs. It exists in three places that must stay the same string —
|
||||||
|
the `define()`, the stylesheet's `--nlsnd-accent`, and `assets/icon.svg`.
|
||||||
|
|
||||||
|
## What is deliberately not here
|
||||||
|
|
||||||
|
Stated because an absent surface is invisible, and the next person to want one
|
||||||
|
should find the reason rather than the silence.
|
||||||
|
|
||||||
|
* **No WP-CLI commands, no REST routes, no AJAX endpoints.** The screen is a
|
||||||
|
form post handled on `admin_init`.
|
||||||
|
* **No JavaScript.** One stylesheet, no script is enqueued.
|
||||||
|
* **No cron, no scheduled events.** Nothing runs on a timer; the update feed is
|
||||||
|
fetched lazily behind a transient.
|
||||||
|
* **No queue, throttle or retry.** A failed message is recorded and not re-sent.
|
||||||
|
* **No send log, and no bounce or complaint handling.** SMTP cannot report them.
|
||||||
|
* **No OAuth.** Google needs an App Password; Microsoft's password sign-in is
|
||||||
|
being retired and the screen says so.
|
||||||
|
* **No hook on `wp_mail`, and no filter over the SMTP credentials.**
|
||||||
|
* **No user meta, post meta or term meta.**
|
||||||
|
* **No telemetry of any kind.** The only network traffic is the mail itself, to
|
||||||
|
the server the owner named, and the update check against the public release
|
||||||
|
repository, which sends no credential.
|
||||||
@@ -0,0 +1,68 @@
|
|||||||
|
# Nolimit Send
|
||||||
|
|
||||||
|
<!-- nlsnd:version 0.1.0 -->
|
||||||
|
|
||||||
|
Chooses how WordPress and WooCommerce send email. Pick a provider — SMTP2GO,
|
||||||
|
Brevo, Mailgun, SendGrid, Postmark, Amazon SES, Google, Microsoft — or type in
|
||||||
|
any SMTP server, and every message the site sends goes through it.
|
||||||
|
|
||||||
|
## The problem it was written for
|
||||||
|
|
||||||
|
By default WordPress hands mail to the web host's own `mail()`. That is the
|
||||||
|
mail that lands in spam, arrives from `wordpress@` a domain that has no SPF
|
||||||
|
record for the host, or is silently dropped — and a shop only finds out when a
|
||||||
|
customer writes to say the order confirmation never came.
|
||||||
|
|
||||||
|
The fix is to send through a real mail service over SMTP. The plugins that do
|
||||||
|
it are usually large, and several of them phone home or sell the upgrade on
|
||||||
|
the same screen where the password goes. This one is a single screen.
|
||||||
|
|
||||||
|
## What it does, and what it refuses to do
|
||||||
|
|
||||||
|
* **Routes everything.** It configures PHPMailer, the library behind
|
||||||
|
`wp_mail()`, so WordPress itself, WooCommerce orders and receipts, password
|
||||||
|
resets and every other plugin's mail go through the chosen server. It is
|
||||||
|
site-wide, not WooCommerce-only.
|
||||||
|
* **Presets** that fill in the host, port and encryption, with a note per
|
||||||
|
provider on what the password field really wants (Brevo wants an SMTP key,
|
||||||
|
Google an App Password).
|
||||||
|
* **A test message**, sent from the screen, that shows the server's own
|
||||||
|
answer when it fails.
|
||||||
|
* **The last failure**, kept and shown with a time, so "why did that email not
|
||||||
|
arrive" has an answer on the screen rather than in a log nobody opens.
|
||||||
|
* **A sender address and name**, replacing WordPress' default `wordpress@…` —
|
||||||
|
or, if forced, every sender.
|
||||||
|
|
||||||
|
What it refuses to do:
|
||||||
|
|
||||||
|
* **It never touches a message's own headers.** Reply-To, Cc, List-Unsubscribe
|
||||||
|
and anything a caller set are passed through exactly as they came.
|
||||||
|
* **It does not queue, throttle or retry.** A failed message is recorded, not
|
||||||
|
re-sent.
|
||||||
|
* **It cannot report bounces or complaints.** SMTP hands a message over; whether
|
||||||
|
it was delivered comes back, if at all, to the provider's dashboard. The
|
||||||
|
screen says so rather than implying a delivery report.
|
||||||
|
* **It does not do OAuth.** Google works with an App Password. Microsoft 365 is
|
||||||
|
retiring username-and-password SMTP, and the screen says that plainly on the
|
||||||
|
Microsoft preset — [the setup guide](SETUP.md#microsoft-365) has the dates.
|
||||||
|
* **It stands down** when another SMTP plugin (WP Mail SMTP, FluentSMTP, Post
|
||||||
|
SMTP, Easy WP SMTP, Brevo for WordPress) is active, and names it on the screen.
|
||||||
|
|
||||||
|
## Documentation
|
||||||
|
|
||||||
|
| File | For |
|
||||||
|
| --- | --- |
|
||||||
|
| [SETUP.md](SETUP.md) | Installing it, choosing a provider, checking it works, and what to do when mail stops. |
|
||||||
|
| [CONTRACT.md](CONTRACT.md) | For developers: every hook, option, capability and constant — and what is deliberately absent. |
|
||||||
|
|
||||||
|
## Good to know
|
||||||
|
|
||||||
|
* **No telemetry**, no account, no upsell. Nothing is sent anywhere except the
|
||||||
|
mail itself, to the server you named, and the update check against the
|
||||||
|
public release page, which carries no credential.
|
||||||
|
* **Updates** come from that release page rather than wordpress.org, and appear
|
||||||
|
in **Dashboard → Updates** like any other plugin's.
|
||||||
|
* The SMTP password is stored as typed in one option row, because WordPress has
|
||||||
|
nowhere better to keep it. It is never printed back into the form, and it is
|
||||||
|
removed when the plugin is deleted.
|
||||||
|
* The strings are English only.
|
||||||
+109
@@ -0,0 +1,109 @@
|
|||||||
|
# Setting up Nolimit Send
|
||||||
|
|
||||||
|
<!-- nlsnd:version 0.1.0 -->
|
||||||
|
|
||||||
|
## Installing it on a shop
|
||||||
|
|
||||||
|
| Needs | Version |
|
||||||
|
| --- | --- |
|
||||||
|
| WordPress | 5.9 or newer |
|
||||||
|
| PHP | 7.4 or newer |
|
||||||
|
| WooCommerce | Not required. It is tested with WooCommerce (6.0 or newer) because that is the mail most shops care about |
|
||||||
|
|
||||||
|
Download `nolimit-send.zip` from the
|
||||||
|
[latest release](https://gitea.nolimit.dk/kw/nolimit-send-dist/releases/latest),
|
||||||
|
install it through **Plugins → Add New → Upload Plugin**, and activate.
|
||||||
|
After the first install, updates arrive through the normal WordPress updates
|
||||||
|
screen — the plugin carries an `Update URI`, so it checks its own release feed
|
||||||
|
and is never asked about on wordpress.org.
|
||||||
|
|
||||||
|
**Nothing is sent through it until it is configured.** After activation the
|
||||||
|
plugin is off: WordPress keeps sending the way it did. That is deliberate — a
|
||||||
|
mailer that switched itself on with no server behind it would take every email
|
||||||
|
the shop sends down with it.
|
||||||
|
|
||||||
|
## Choosing how the site sends
|
||||||
|
|
||||||
|
The screen is **Send**, under the shared Nolimit menu in the admin sidebar,
|
||||||
|
and needs the `manage_options` capability.
|
||||||
|
|
||||||
|
1. Tick **Send through this server** and pick a provider. The host, port and
|
||||||
|
encryption are filled in from the preset; choosing a different provider
|
||||||
|
replaces all three, so there is never a mixed pair such as one provider's
|
||||||
|
name over another's host.
|
||||||
|
2. Enter the username and password the way the note under the field says. What
|
||||||
|
the field wants differs, and is the usual cause of a rejected login:
|
||||||
|
|
||||||
|
| Provider | What goes in the password field |
|
||||||
|
| --- | --- |
|
||||||
|
| Brevo | An **SMTP key** from SMTP & API, not the account password and not an API key |
|
||||||
|
| SMTP2GO | That SMTP user's password. Port 2525 is the default: it is open from more networks than 587 |
|
||||||
|
| Mailgun | That SMTP user's password from the Mailgun dashboard |
|
||||||
|
| SendGrid | An API key with Mail Send permission; the username is the literal word `apikey` |
|
||||||
|
| Postmark | The server API token, in **both** the username and the password field |
|
||||||
|
| Amazon SES | The SES **SMTP** password, and the region's host typed in |
|
||||||
|
| Google | An **App Password**, which needs two-step verification on that account |
|
||||||
|
| Microsoft | The mailbox password, with SMTP AUTH enabled for that mailbox — see below |
|
||||||
|
| Other | Whatever your server expects |
|
||||||
|
|
||||||
|
3. Optionally set a sender address and name. Unless **Always use this sender**
|
||||||
|
is ticked, they replace only WordPress' own default `wordpress@…` /
|
||||||
|
`WordPress` and leave any sender a plugin chose alone.
|
||||||
|
4. **Save**, then **Send a test message**. A failure shows the server's own
|
||||||
|
answer. A real failure is kept with its time; the status reads "a message
|
||||||
|
failed recently" for 24 hours, and a button clears it sooner. A later success
|
||||||
|
does not clear it early.
|
||||||
|
|
||||||
|
### Microsoft 365
|
||||||
|
|
||||||
|
Username-and-password SMTP is being retired: switched off by default for
|
||||||
|
existing organisations from the end of December 2026, unavailable to new ones,
|
||||||
|
with a final date not yet announced. **This plugin does not do OAuth**, which is
|
||||||
|
what replaces it, so the Microsoft preset works until an administrator loses the
|
||||||
|
ability to enable it. For anything that has to keep working, use a sending
|
||||||
|
provider. The screen says the same thing on the preset itself.
|
||||||
|
|
||||||
|
### Other mail plugins
|
||||||
|
|
||||||
|
If WP Mail SMTP, FluentSMTP, Post SMTP, Easy WP SMTP or Brevo for WordPress is
|
||||||
|
active, this plugin does **not** send: two plugins that both configure PHPMailer
|
||||||
|
produce whatever the later one says. The screen names the plugin. Nolimit Forms
|
||||||
|
has an SMTP mailer of its own; that is only a notice, and the owner decides
|
||||||
|
which to switch off.
|
||||||
|
|
||||||
|
### Auto-updates
|
||||||
|
|
||||||
|
The plugin offers to switch its own auto-updates on, once, through a notice on
|
||||||
|
its screen. Taking or dismissing the offer writes a marker
|
||||||
|
(`nlsnd_auto_update_seeded`) so it is never asked again — the setting is
|
||||||
|
WordPress' own, in WordPress' own place, and the toggle is gated on
|
||||||
|
`update_plugins`.
|
||||||
|
|
||||||
|
## Knowing it works
|
||||||
|
|
||||||
|
* **Send a test message** from the screen. It goes through the server you chose
|
||||||
|
and, when it fails, shows that server's own answer — a refused login, a host
|
||||||
|
that cannot be reached, a sender the provider has not verified.
|
||||||
|
* **Read the status line** at the top of the screen. It reads *Sending through
|
||||||
|
<provider>* when everything is in place, *Not sending yet* when it is switched
|
||||||
|
off or has no host, *Mail is handled by <plugin>* when another mail plugin is
|
||||||
|
in the way, and *A message failed recently* after a real failure.
|
||||||
|
* **Look at one real email.** Place a test order or use the password-reset
|
||||||
|
form, and open the message's full headers in the receiving mailbox. The
|
||||||
|
`Received:` lines should name your provider, not your web host.
|
||||||
|
|
||||||
|
A test message reaching the provider proves the login and the route. It does not
|
||||||
|
prove the message reached an inbox: that answer lives in the provider's own
|
||||||
|
dashboard, and so do bounces and spam complaints.
|
||||||
|
|
||||||
|
## If mail stops
|
||||||
|
|
||||||
|
1. The screen's **last failure** card shows the most recent error with its time.
|
||||||
|
It is only recorded when this plugin was the one sending.
|
||||||
|
2. A password or key that was rotated at the provider is the commonest cause.
|
||||||
|
Enter the new one and save; the field is never filled in for you, and
|
||||||
|
leaving it empty keeps the stored one.
|
||||||
|
3. Untick **Send through this server** to hand sending straight back to
|
||||||
|
WordPress while you sort it out. Nothing else is changed.
|
||||||
|
4. Deleting the plugin from the Plugins screen removes every setting it stored,
|
||||||
|
including the password.
|
||||||
Reference in New Issue
Block a user