| 开发者 | shiponkarmakar |
|---|---|
| 更新时间 | 2026年10月28日 19:51 |
| 捐献地址: | 去捐款 |
| PHP版本: | 7.4 及以上 |
| WordPress版本: | 7.1 |
| 版权: | GPLv2 or later |
| 版权网址: | 版权信息 |
wp_mail() traffic through Amazon SES, SendGrid, Mailgun, Brevo (Sendinblue), Postmark, Zoho ZeptoMail, Gmail API, Microsoft 365, or any standard SMTP server — with full email logging, queue, retry, and failure alerts.
Try the live demo
Launch a full WordPress site with SendForce Mail Relay already set up — no install, nothing to sign up for. It runs in your browser on WordPress Playground, preloaded with two example connections, a Smart Routing rule and a week of email history. Simulation Mode is on, so no email is ever sent.
https://playground.wordpress.net/?blueprint-url=https://wordpress.org/plugins/wp-json/plugins/v1/plugin/sendforce-mail-relay/blueprint.json
Video overview
https://youtu.be/dUv4HolX5dk
Why SendForce Mail Relay
sendforce_before_send, sendforce_after_send, sendforce_log_entry, sendforce_api_request, sendforce_api_response for extending the plugin without forking.WP_DEBUG_LOG integration — optional mirroring of SMTP and API debug output to debug.log.wp_mail() function, so it works with every plugin that sends email — including WooCommerce, Easy Digital Downloads, Contact Form 7, WPForms, Gravity Forms, Ninja Forms, Fluent Forms, Forminator, MemberPress, LearnDash, BuddyPress, bbPress, MailPoet (transactional), and any custom plugin or theme that uses wp_mail().
sendforce-mail-relay folder to the /wp-content/plugins/ directory, or install directly through the WordPress plugin installer.Yes. You need access to an SMTP server or a transactional email provider account. Most providers (Gmail, Outlook, etc.) offer SMTP access. Transactional services like SendGrid, Mailgun, or Amazon SES offer both SMTP and HTTP API access.
Yes. All credentials are encrypted using AES-256-CBC encryption before being stored in the database. The encryption key is a dedicated random secret generated once for your site, so regenerating your WordPress security keys/salts (via a security plugin, host migration or site clone) no longer invalidates your saved passwords.
When enabled, emails are stored in a database queue instead of being sent immediately. A WP-Cron job processes the queue every minute, sending emails in batches; each run stops after about 20 seconds so it stays within typical host PHP time limits. You can also set a "Max emails per minute" on each connection to pace sending for providers with strict rate limits, such as the Gmail API. Failed emails are retried with exponential backoff (5 min → 15 min → 45 min). Tip: WP-Cron only runs when your site receives visits, so on low-traffic sites the queue can lag. For reliable timing, disable WP-Cron and trigger it from a real server cron job every minute.
Yes. SendForce Mail Relay hooks into WordPress's phpmailer_init action (SMTP mode) or pre_wp_mail filter (API mode). Since every plugin — including WooCommerce, contact form plugins, and membership plugins — sends email via WordPress's wp_mail() function, SendForce Mail Relay will handle all of your outgoing emails.
You should only use one SMTP plugin at a time. Please deactivate any other SMTP or email plugins (FluentSMTP, WP Mail SMTP, etc.) before activating SendForce Mail Relay.
By default, SendForce Mail Relay logs: recipient email, subject, headers, status (sent/failed), error message if any, and timestamp. Email body logging is optional and can be disabled in Settings > Queue & Logging for privacy compliance.
All plugin data (database tables, settings, and scheduled events) is completely removed when you delete the plugin through the WordPress admin. On a Multisite network, this happens on every site.
If you set a From email in Settings → Sender Identity, every email uses it, on every connection and every Smart Routing rule. If you leave it empty, each email keeps the From address the sending plugin chose (for example WooCommerce's store address); emails that don't set one use your site's admin email. Smart Routing never changes the From — it only picks which connection sends. Gmail and Microsoft 365 API connections always send as the connected account. Your email provider must accept the From you use: most only allow addresses on domains you've verified with them.
Yes. While the other plugin is still active, click Import settings — in the notice SendForce shows, or any time under SendForce → Settings → Import from another plugin (still there after you dismiss the notice). There is also a WP-CLI command, wp sendforce import run <source>, which is handy for staging sites and bulk work. On Multisite you import per site, and if WP Mail SMTP or Easy WP SMTP is set to one network-wide configuration, only a network administrator can import it. It previews exactly what will come across, then adds the connections (credentials re-encrypted with SendForce's own key), sender identity and fallback; FluentSMTP's per-sender routing becomes Smart Routing rules. Nothing already in SendForce is overwritten, and importing twice doesn't create duplicates. Gmail and Microsoft 365 API connections need one extra step: click Connect in SendForce to sign in again (Gmail or Outlook over SMTP with an app password imports as-is). If you used Easy WP SMTP's One-Click Setup, there are no app credentials saved on your site to copy, so SendForce asks you to create your own Google or Microsoft app. Credentials you keep in wp-config.php are not copied into the database — you'll be asked to enter them. Send a test email from SendForce, then deactivate the other plugin.
Yes. All commands live under wp sendforce:
wp sendforce test you@example.com — send a test email (optional --subject= and --message=)wp sendforce queue process — process the email queue nowwp sendforce queue stats — show queue counts by statuswp sendforce queue clear --status=failed — clear queued emails (asks for confirmation)wp sendforce log list --limit=50 — list recent log entrieswp sendforce log tail --status=failed — show the latest failureswp sendforce log count — count log entrieswp sendforce log delete --before=2026-01-01 — delete old log entries (asks for confirmation)wp sendforce import list — show which SMTP plugins can be imported fromwp sendforce import preview easy-wp-smtp — show what would be imported, without changing anythingwp sendforce import run fluent-smtp — import it (asks for confirmation; add --yes to skip)wp sendforce sysinfo — print system info for support tickets--url= to choose the site. Running wp sendforce queue process from a server cron job every minute is a reliable way to process the queue without depending on site visits.
Yes. Network Activate the plugin and each site sets itself up on its first visit, including sites created later. Every site is configured separately, with its own connections, sender identity, logs, queue and routing rules; there is no shared network-wide connection yet. When you delete a site, its SendForce data is removed with it. Importing from another SMTP plugin also works per site; if WP Mail SMTP is configured network-wide, only a network administrator can import those settings, since they belong to the whole network. If you use a real server cron instead of WP-Cron, make sure it runs cron for every site, not just the main site, so each site's queue and log cleanup run on time.
Yes. The live demo runs a real WordPress site in your browser through WordPress Playground, with SendForce already configured. It comes with two sample connections (Amazon SES and Mailgun), a Smart Routing rule and 38 logged emails, so you can explore the dashboard, logs and routing straight away. Simulation Mode is enabled, so nothing is actually sent. The demo runs the version currently published here, and nothing you do in it touches your own site.
No. SendForce Mail Relay does not collect any data, make any analytics calls, or communicate with any external server except when sending emails through your configured provider.
wp sendforce import list|preview|run <source> imports from the command line, with the same preview and confirmation as the admin UI.wp sendforce command.<, > or % were silently corrupted when saved, causing authentication failures that looked like a wrong password. The same corruption affected notification-channel secrets (Telegram/Slack bot token, Pushover keys) and the Amazon SES access key; all are now stored verbatim, with proper output escaping on the Alerts screen.sendforce_allow_private_webhook_hosts filter lets self-hosted setups opt back in for legitimate internal collectors.email, email log, gmail, outlook, smtp) to better match how users actually search. gmail and outlook in particular are high-intent searches that match our existing Gmail and Microsoft 365 OAuth flows but weren't previously tagged.aria-label on icon-only Log/Queue buttons), proper plural forms via _n() on the bulk-action counter, and minor i18n/SVG-whitelist fixes. See CHANGELOG.md for detail.provider column to wp_sendforce_logs (varchar(50), indexed). Populated automatically going forward from the captured debug payload (when available) or the active connection's configured provider. Existing rows are not back-filled; only new log entries get the column populated. dbDelta handles the schema migration on plugin upgrade.<code> tags but didn't escape the inner content first — so when a bullet contained literal <tag> text inside backticks (very common in technical changelogs), the browser interpreted the embedded text as a real HTML tag and produced floating empty <code> elements that rendered as gray pills against the page background. Fix: esc_html() the raw line before applying the markdown transformations. The two regex rules (**bold** → <strong> and backtick → <code>) now run on already-escaped text, guaranteeing balanced tags and no HTML injection from bullet content. Affects 1.0.28 only.cron_schedules filter. The filter fires whenever WP looks up scheduled events (which can happen before init, during plugins_loaded or even setup_theme), so calling __( …, 'sendforce-mail-relay' ) there ran the translation function before the textdomain was loaded. Both filter callbacks (in the activator and the mailer) now use a literal English string for the cron schedule's display label — that label is only shown in dev tools like WP Crontrol or wp-cli cron list, never user-facing, so leaving it untranslated is harmless. Resolves the deprecation notice on sites running WP_DEBUG with WP 6.7 or newer.http:// an inline red warning appears explaining that the alert message (site name, failed recipient, error details) would be sent unencrypted. Catches typos and homemade webhook receivers before save.sendforce_alerts_throttle_seconds to change the window length, set it to 0 to disable throttling entirely.manage_options capability in addition to the existing nonce check. The forms that issued these requests already live on admin-only pages, so a non-admin couldn't normally obtain a valid nonce — but explicit capability checks match WordPress.org Plugin Check expectations and protect against any future flow that might mint a nonce in a less-restricted context./var/www/example.com/wp-content/uploads/woocommerce_uploads/2026/invoice-12345.pdf were stored verbatim — leaking the server directory layout, shared-hosting username paths, and customer order IDs from WooCommerce invoice filenames. From 1.0.27 the same row stores only invoice-12345.pdf. Existing rows are not rewritten; only new log entries get basename-only.wp_mail() — WooCommerce invoices, form uploads, certificates — are base64-encoded into each provider's native schema.build_raw_mime() helper. Full release detail in CHANGELOG.md.AADSTS50011 redirect URI mismatch. Root cause was add_query_arg() not URL-encoding values, leaving & characters bare inside redirect_uri. Switched to http_build_query() with PHP_QUERY_RFC3986.make_request()).Bearer TOKEN / Zoho-enczapikey TOKEN prefixes — auto-stripped before constructing the auth header. All API keys are also auto-trimmed.admin_url filters (Wordfence, LiteSpeed Cache).wp_kses SVG whitelist used for channel logos on the Alerts tab.from_email / from_domain conditions, "via rule" badge in Email Log, starter presets, "What's Next" roadmap tab, styled confirm dialogs.oauth_email field on newly created connections so the schema is consistent from save time.IsContentHtml flag in both HTML and plain-text paths).next_retry_at) on the next cron run.wp_strip_all_tags on provider errors returned to the browser.wp_mail() returns true on fallback success; clearer recovery message. Suppressed spurious SMTP-warning when active path was API or PHP-Mail.<select> dropdowns with branded styled component (full keyboard support — Arrow/Enter/Escape). Default/Fallback selectors auto-refresh after connection save. Form-control polish (chevron, focus ring, hover, disabled states)..DS_Store file from assets/images/providers/. Added phpcs:ignore annotations with rationale to interpolated table-name $wpdb queries. Restructured WP-CLI log-delete query for proper phpcs handling.<style>/<script> blocks from PHP output (proper enqueue). Surface actual provider HTTP status / response body in failure messages. Added "Raw API request / response" panel to Email Log detail modal. Masked-dots placeholder for saved password/API-key fields. Hardened secret redaction (covers client_secret, response bodies, malformed-JSON fallback). Defused CSV formula injection on log export. Gated on-load DB schema upgrade to admin/WP-CLI. Added confirmation prompts to destructive WP-CLI commands.wp sendforce test, queue, log, sysinfo). Added developer hooks (sendforce_before_send, sendforce_after_send, sendforce_log_entry, sendforce_api_request, sendforce_api_response). Added Developer Debug setting to mirror SMTP/API debug to debug.log. Added raw API request/response capture in new debug_data log column (with Authorization redaction). Email Log export as CSV/JSON. "Copy Debug Info" button on Email Test screen. Replaced stale "SMTP-Manager" User-Agent on Resend with "SendForce-Mail-Relay".sendforce-mail-relay.php.