Greater Atlanta's IT partner since 1989

Microsoft 365

AJC Graph Mailer

Microsoft 365 mail for WordPress

Version 1.2.2 · WordPress 5.8+ · PHP 7.4+ · Licensed GPL-2.0-or-later

AJC Graph Mailer 1.2.2

WordPress 5.8+ · PHP 7.4+

Download the plugin (.zip)

SHA-2560d32555d901360ac130d43686977077d42ca2c836865909d3a6843176e754fcd

  • Install it once from Plugins → Add New → Upload Plugin.
  • After that, updates arrive through WordPress's normal update screen.
  • Every update is checked against a signed release manifest before it installs.

Routes all WordPress mail through the Microsoft Graph API using app-only (client credentials) authentication.

Unlike Gravity SMTP, WP Mail SMTP, FluentSMTP and Post SMTP — which all use delegated OAuth and therefore need a licensed user mailbox to sign in as — this plugin authenticates as the application itself. That means it can send from an unlicensed shared mailbox, which is the whole reason it exists.

What it does

  • Sends through a shared or user mailbox in Microsoft 365, with no licence required on the sending mailbox.
  • Optionally shows an alias or a former distribution list address in the From header while sending through a real mailbox behind it.
  • Handles attachments of any size: inline under 2.5 MB, chunked upload sessions above that.
  • Preserves a plugin-supplied From address as Reply-To, so Gravity Forms notifications come from forms@ and replies reach whoever submitted the form.
  • Honours Retry-After when Exchange Online throttles a mailbox.
  • Works against Commercial, GCC High and DoD clouds.

How it handles failure

It fails closed. Once a client secret has been saved, a broken configuration stops mail and says so — with an error, a log entry and an admin notice — instead of quietly falling back to unauthenticated PHP mail(). Mail passes through to WordPress only while the plugin has never been configured, so a half-finished install cannot lock an administrator out of password resets.

That matters more than it sounds. A mail plugin that silently degrades is a mail plugin that loses messages nobody notices until a customer complains.

How credentials are stored

The Entra client secret is encrypted at rest with AES-256-GCM, using a key derived from wp-config.php rather than the database. A stolen database dump alone does not expose it.

The key is unique to each site. It comes from one of three sources, and the settings screen tells you which is in force:

Source Survives salt rotation Stored in the database
AJC_GRAPH_MAILER_KEY constant Yes No
WordPress salts (default) No No
Generated fallback Yes Yes

Defining AJC_GRAPH_MAILER_KEY in wp-config.php is recommended. Without it the key derives from AUTH_KEY and SECURE_AUTH_KEY, and anything that rotates those — a migration plugin, a host-side staging clone, a security plugin's hardening button — makes the stored secret unreadable and stops mail until it is re-entered. The settings screen offers a generated line to paste.

Setting it up

Tenant-side setup happens once per Microsoft 365 tenant, before the plugin is configured in WordPress. Budget about thirty minutes, plus up to two hours of waiting for permission caches to settle before the first send succeeds.

→ Tenant setup instructions

The short version:

  1. Create a shared mailbox for the site to send through.
  2. Register a single-tenant Entra app; copy the client and tenant IDs; create a client secret and copy the Value — Entra never shows it again.
  3. Scope the app to that one mailbox with RBAC for Applications. Do not also grant Mail.Send in Entra: Entra consent and Exchange RBAC are additive, and an unscoped Entra grant silently defeats the scope.
  4. In WordPress, go to Settings → Graph Mailer and enter the IDs, the secret, its expiry date and the mailbox's primary SMTP address.
  5. Test connection, then Send test.

Day-two operations — rotating the secret, adding a second sending mailbox, what each failure mode means and how to recover — are in the operations guide.

Updates

The plugin updates itself through WordPress's normal update screen, from this host rather than wordpress.org.

Every release is signed. A package installs only if it came from this host and its checksum matches a release manifest signed with a key held offline. A site that cannot verify a release refuses it and says so, rather than installing it.

Requirements

  • WordPress 5.8 or later
  • PHP 7.4 or later, with the openssl and sodium extensions
  • A Microsoft 365 tenant, and permission to register an application in it

Support

A&J Computers — joe@ajcomputers.com

Licensed GPL-2.0-or-later.

Questions about AJC Graph Mailer?

Talk to the people who build and support it.