定制 mantekio/wp-ses-mail 二次开发

按需修改功能、优化性能、对接业务系统,提供一站式技术支持

邮箱:yvsm@zunyunkeji.com | QQ:316430983 | 微信:yvsm316

mantekio/wp-ses-mail

Composer 安装命令:

composer require mantekio/wp-ses-mail

包简介

WordPress must-use plugin that sends mail through Amazon SES with an IAM role, so no SMTP credentials are stored and no send failures pass silently.

README 文档

README

Packagist Version License: GPL v2

A WordPress must-use plugin that sends mail through Amazon SES, authenticated by an IAM role, so there are no credentials stored anywhere and no send failures that pass silently.

⚠️ Status: 0.9.0 (pre-1.0). Feature-complete and hardened through repeated adversarial review, with the SES signing checked against AWS's own SigV4 test vectors. It has not yet been run end-to-end against a live Amazon SES account, so treat it as pre-production until 1.0.0. It ships in the open while that verification runs; issues and field reports are welcome.

📖 Full write-up: Your WordPress mail credentials are sitting in your database

The problem

By default wp_mail() hands your message to PHP's mail() and out through sendmail: no sending reputation, no SPF alignment, no DKIM signature, so modern providers bin it as spam, often without even a bounce. And wp_mail()'s entire failure vocabulary is a single false. On the default path it does not even return that: sendmail accepts the message, wp_mail() returns true, and the mail dies downstream where WordPress never hears about it. A password reset that never arrives, with nothing in the logs.

The usual fix is an SMTP plugin. It fixes authentication, but it stores the SMTP username and password in wp_options. Every database dump, backup, and staging clone then carries a credential that can send mail as your domain, DKIM-signed, with no fingerprint that it was not you. That is a liability with a settings screen.

What it does

  • Sends via the SES API, not SMTP. A signed HTTPS request, so there is no long-lived password in the flow at all.
  • Authenticates with an IAM role. Credentials come from the AWS default chain (env vars, then the ECS task role, then the EC2 instance role), read at send time and never written to the database, wp-config.php, or disk. There is no secret at rest to leak.
  • Replaces only the transport. It hands core a subclass of PHPMailer on pre_wp_mail and overrides one method, postSend(). Core still builds the whole message and honours every wp_mail_* filter, so no core contract is reimplemented and nothing can drift.
  • Fails loudly, never falls back. An SES rejection returns false with the real SES error via wp_mail_failed. A misconfiguration refuses to send (on every admin screen and in the log) rather than falling through to sendmail and spam.
  • Remembers bounces and complaints. A signed, topic-pinned SNS endpoint records hard bounces and complaints to a suppression table that is checked before every send, so a dead or complaining address is never mailed again and your SES reputation stays intact.
  • Ships a real health check. wp ses verify signs live requests with the same code the send path uses, and exits non-zero when anything is wrong, so wp ses verify || alert works in cron.

Requirements

  • WordPress 5.7+, for the pre_wp_mail hook. On older versions there is no seam: mail falls through to sendmail and the plugin can warn but cannot stop it.
  • PHP 7.4+, with the openssl and curl extensions.
  • WordPress running on AWS compute with an IAM role allowing ses:SendEmail (plus ses:GetAccount and ses:GetEmailIdentity for verify). Off AWS, the standard AWS_* environment variables work.
  • A verified SES identity to send from (a domain, with Easy DKIM, is what makes mail align).

Installation

A must-use plugin loads before regular plugins and cannot be deactivated by accident.

Manual

mkdir -p wp-content/mu-plugins
cp wp-ses-mail.php wp-content/mu-plugins/

Composer

composer require mantekio/wp-ses-mail

Composer installs it as a wordpress-muplugin, which has two consequences worth knowing:

  • Allow the installer plugin. On a fresh project Composer blocks composer/installers until you permit it. Add this to your root composer.json (most WordPress-Composer stacks already have it):
    { "config": { "allow-plugins": { "composer/installers": true } } }
  • Make sure it actually loads. It installs into wp-content/mu-plugins/wp-ses-mail/ (a subfolder), and vanilla WordPress only auto-loads *.php placed directly in mu-plugins/. Rely on a mu-plugins autoloader (Bedrock and similar stacks ship one), or use the Manual method above to drop the single file straight in.

Configuration

Define in wp-config.php (never the database):

Constant Required Meaning
WP_SES_REGION yes* SES region, e.g. eu-west-1. *Falls back to the AWS_REGION environment variable.
WP_SES_FROM yes Default From address, a verified SES identity, e.g. noreply@example.com.
WP_SES_SNS_TOPIC_ARN for bounces The SNS topic ARN SES publishes bounce/complaint events to. The endpoint fails closed until this is set (see Bounces).
WP_SES_CONFIGURATION_SET no SES configuration set, for event tracking.
WP_SES_ALERT_EMAIL no Best-effort address to alert on a serious send failure.
WP_SES_ENDPOINT test only Override the SES endpoint at a local simulator (e.g. LocalStack). Leave unset in production.
define( 'WP_SES_REGION', 'eu-west-1' );
define( 'WP_SES_FROM',   'noreply@example.com' );
define( 'WP_SES_SNS_TOPIC_ARN', 'arn:aws:sns:eu-west-1:123456789012:ses-events' );

No credentials go here. The IAM role provides them.

Bounces and complaints

SES holds you to bounce and complaint thresholds; cross them and it throttles your sending, then suspends the account. WordPress has no memory of a bounce and will email a dead address forever, so the plugin keeps that memory for it.

  1. In SES, set the identity's bounce and complaint notifications to publish to an SNS topic, and set WP_SES_SNS_TOPIC_ARN to its ARN.
  2. Subscribe the topic to the endpoint https://your-site/wp-json/wpses/v1/sns. The plugin auto-confirms the subscription.
  3. From then on, hard bounces and complaints are written to the suppression table and blocked before the next send.

Security. That endpoint is a public URL. AWS shares one regional signing certificate across all customers, so a valid signature alone only proves a message came from some topic. The endpoint therefore pins your topic ARN and verifies the SNS signature on every message, and fails closed until the ARN is set, so no one can forge a notification to suppress your users' mail.

Lift a wrongly-suppressed address:

wp ses unsuppress --email=someone@example.com

Verifying

wp ses verify

It reports region, credential source, identity verification, DKIM, sandbox state, quota, and whether the bounce topic is wired up, and it exits non-zero on any problem, so it composes into cron:

# nightly: page if the SES config ever drifts
0 3 * * *  cd /var/www/site && wp ses verify || wp ses verify | mail -s "SES broken on $(hostname)" ops@example.com

Hooks

Actions you can hook for logging, metrics, or alerting:

Action Fires when
wpses_sent A send succeeded. Passes the SES MessageId and the Destination.
wpses_send_failed A send failed. Passes a WP_Error.
wpses_suppression_unreadable The suppression table could not be read, so the plugin failed open loudly (sent anyway) rather than block mail on a database blip.

Known limits

  • It is a transactional transport, not a bulk queue. A newsletter blast to tens of thousands of subscribers wants a queue and probably a dedicated bulk sender; leaning on this for that just meets SES throttling as a failed send.
  • No retry or backoff yet. A refused send fails loudly and stops; durable retries belong in a queue in front of the plugin.
  • Message-size ceiling. SES caps the size of a single message; a mail with very large inline attachments will fail rather than be silently truncated.
  • Alignment is DNS, not the plugin. DKIM, SPF, and DMARC alignment are records you add. The plugin signs the request and can tell you they are missing, but cannot add them for you.
  • WordPress 5.7+ only (see Requirements).

How it works

The full reasoning (why a subclass and not the pre_wp_mail fork, why loud failure and no fallback, the SNS signature trap, and the newsroom bounce loop) is in the write-up:

Your WordPress mail credentials are sitting in your database

License

GPL-2.0-or-later: same as WordPress.

Built and maintained by ManTek Technologies: WordPress + AWS at scale, for newsrooms and beyond.

mantekio/wp-ses-mail 适用场景与选型建议

mantekio/wp-ses-mail 是一款 基于 PHP 开发的 Composer 扩展包,目前已累计 0 次下载、GitHub Stars 达 0, 最近一次更新时间为 2026 年 07 月 15 日, 在 PHP 生态内属于活跃度较高的组件。

它主要适用于以下技术方向: 「email」 「wordpress」 「smtp」 「aws」 「ses」 「phpmailer」 等业务场景。在实际项目中,围绕这些方向常见需要落地的问题包括:接口对接、性能调优、并发安全、与既有框架(Laravel / ThinkPHP / Yii / Webman 等)的兼容适配,以及生产环境的日志埋点与稳定性保障。

我们在过去多个企业项目中使用过 mantekio/wp-ses-mail 或与其功能相近的方案,如果你在选型或落地过程中遇到问题,例如 版本兼容、二次改造、私有化封装、与内部系统对接、生产 BUG 排查,欢迎联系我们协助评估。

围绕 mantekio/wp-ses-mail 我们能提供哪些服务?
定制开发 / 二次开发

基于 mantekio/wp-ses-mail 在你已有业务上做功能扩展、字段裁剪、UI 适配、与内部账号 / 权限 / 日志系统的深度对接。

BUG 修复 & 性能优化

线上偶发问题、内存泄漏、慢查询、并发异常等排查修复;针对高流量场景做缓存、队列、索引层面的调优。

项目外包 & 长期维护

承接完整的项目从需求 → 设计 → 开发 → 上线 → 长期运维;也可按月提供技术保姆服务。

yvsm@zunyunkeji.com QQ:316430983 微信:yvsm316 西安尊云信息科技 · 专注 PHP / Go / 分布式系统研发

统计信息

  • 总下载量: 0
  • 月度下载量: 0
  • 日度下载量: 0
  • 收藏数: 0
  • 点击次数: 0
  • 依赖项目数: 0
  • 推荐数: 0

GitHub 信息

  • Stars: 0
  • Watchers: 0
  • Forks: 0
  • 开发语言: PHP

其他信息

  • 授权协议: GPL-2.0-or-later
  • 更新时间: 2026-07-15