One Two Three Send

Changelog

2.0.20

  • Subscription-bombing defences on the public /wp-json/otts/v1/subscribe endpoint. Bots use newsletter signup forms across thousands of sites to flood a victim’s inbox with confirmation emails, burying real alerts (fraud notifications, password resets) — your site is the unwitting relay, not the target. The endpoint now applies three additional layers on top of the existing honeypot: (1) per-IP rate limit, default 10 submissions per IP per hour, filterable via otts_subscribe_rate_limit_per_hour; (2) MX-record check on the email’s domain — typos and bogus domains are rejected; (3) disposable / temp-email domain blocklist (mailinator, guerrillamail, yopmail and ~25 common throwaways), filterable via otts_subscribe_disposable_domains. Each layer silently accept-and-drops (HTTP 200 OK) so bots can’t fingerprint which check rejected them.
  • Delete subscribers from the admin. Newsletter → Subscribers now has a Delete button on every row (nonce-protected, with a confirmation dialog). Two new admin-only REST endpoints for scripted cleanup: DELETE /wp-json/otts/v1/subscriber/{id} and POST /wp-json/otts/v1/subscriber/delete-by-email. Useful for clearing bot signups that slip past the new defences.

2.0.19

  • Adds publer to the affiliate-hint helper’s service map. When the new One Two Three Post 1.7.0 surfaces its Publer-transport setup field, the helper renders a contextual “Don’t have a Publer account yet? Sign up →” link pointing at /tools/#publer on onetwothreesend.com — same compliance posture as the existing Claude / MailerLite / Brevo / Postmark / BigScoots / Beehiiv hints. No external HTTP from this plugin; the affiliate redirection lives on the destination docs page.

2.0.18

  • Admin notification email on every new signup. New Newsletter → Settings → Notifications tab with two recipient lists: one for free signups, one for paid (paid signups often go to a different stakeholder). Notifications go out through the same email provider you have configured for newsletter sends — not via wp_mail() — so deliverability matches the rest of your traffic. Stripe paid signups + free→paid upgrades both notify the paid list. Includes a “Send test notification” button on the Notifications tab so you can verify wiring before a real signup happens. Subject line is [Site name] New {free|paid} signup — email@example.com, body includes source attribution from 2.0.17.

2.0.17

  • Captures signup source on every new subscriber. New signup_meta JSON column on wp_otts_subscribers records the first-touch referrer host, landing-page URL, and any utm_* query parameters set on the visitor’s first front-end pageview. The Subscribers admin table gains a Source column; both the free CSV export and the Pro export/import flow include source + signup_meta_json columns. Cookie name is otts_ft, SameSite=Lax, 1-year TTL; no PII stored, no external HTTP. Sites with a consent gate can hold the cookie until consent is granted via the otts_signup_attribution_consent filter. First-touch wins — re-subscribing an existing email doesn’t overwrite the original attribution. Stripe and Beehiiv signups are tagged with utm_source=stripe / utm_source=beehiiv so the same column reflects the channel of paid + imported subscribers, not just web signups.

2.0.16

  • Fixes the AI Settings tab showing two competing links (the legacy “Get a key at console.anthropic.com” plain link and the new 2.0.14 affiliate hint side by side). Now: when no Claude API key is configured, only the affiliate hint renders. When a key is already configured, only the operational “Manage your key at console.anthropic.com” link renders. One link at a time, depending on state.

2.0.15

  • The affiliate-hint helper from 2.0.14 now also renders per-provider sign-up hints on the Email provider config panel. When a Pro provider (MailerLite, Brevo) is selected and its API key field is empty, an inline “Don’t have a {provider} account yet? Sign up →” link appears beneath the config table. Providers without an affiliate program (Mailchimp, Kit, SES, Resend, SMTP) show nothing — the helper returns empty for unknown slugs. Same compliance posture as 2.0.14: links point to onetwothreesend.com/tools/, not raw affiliate URLs; filterable via otts_affiliate_hint_enabled to disable globally.

2.0.14

  • Adds a small OTTS_Affiliate_Hint helper that renders an inline “Don’t have a {service} account yet? Sign up →” link next to setup fields when the field is empty. First two call sites: the Claude API key field on Newsletter → Settings → AI Settings, and the Email provider selector on Newsletter → Settings → Provider. Operators who already have credentials never see the hints — the helper only renders when the relevant field is blank. Every link points to onetwothreesend.com/tools/ (a docs page on the publisher’s site, not a raw affiliate URL); affiliate redirection happens there and the FTC disclosure lives on that page. Operators can disable all hints globally via the otts_affiliate_hint_enabled filter (returns false), or replace the service map via otts_affiliate_hint_services. wp.org review note: no external HTTP, no tracking, no site-identifying data — static helper, fully filterable.

2.0.13

  • Adds three integration points so a Pro extension can replace the Settings → Schedule UI and own scheduling without modifying the free plugin: filter otts_settings_schedule_show_default hides the legacy schedule form when an extension takes over, action otts_settings_schedule_render_pre lets an extension inject a replacement notice, and filter otts_scheduler_register_default_cron suppresses the default otts_scheduled_send cron registration when an extension provides its own. Free plugin behaviour is unchanged without those hooks.

2.0.12

  • Send reliability overhaul. Per-recipient failures are now classified as transient (rate limit, network blip, 5xx — retry), permanent (invalid email, 4xx — never retry, mark subscriber bounced), or system (auth failure, suspended account — halt the send and email the admin). A new wp_otts_send_retries table holds transient failures; a 5-minute cron worker re-fires them with exponential backoff (5m → 15m → 45m → 2h → 6h) up to 5 attempts. Subscribers get new bounce_state, soft_bounces, last_bounce_at, and last_delivery_at columns. The Resend provider now returns structured WP_Error values with a category so the classifier can act on them without re-parsing the response. A new “Send Health” admin page (Newsletter → Send Health) shows pending retries, bounced subscribers, recently resolved retries, and recent send results — and an admin notice fires whenever a send finishes with any non-success rows.

2.0.11

  • Resend provider now retries on HTTP 429 with backoff. Resend caps free/default accounts at 5 requests per second; sequential sends to 6+ subscribers were hitting the rate limit on later recipients, and the failure was recorded but never retried — so those recipients silently never got the email. The send loop is unchanged; the provider retries up to 3 times with Retry-After honoured (or 250ms default) before giving up.

2.0.10

  • Welcome email now ends with the standard footer + working unsubscribe link (the same one broadcast newsletters use). The default body text already promises “every email has an instant unsubscribe at the bottom” — until this release, the welcome email had no footer at all, so the link was missing. Looks up the new subscriber’s token to build the URL, falls back to no footer if for any reason the token can’t be loaded.
  • Sidebar menu label changed from “Newsletter” to “One Two Three Send”. Submenu items (Dashboard, Newsletters, Subscribers, Settings, etc.) keep their original names — those describe specific features, only the top-level brand label changes.

2.0.9

  • Welcome email body now supports rich HTML — paste headings, lists, emoji links, and CTA buttons into the body field at Newsletter → Settings → Welcome Email and they render. Bodies without any HTML tags still get the previous plain-text + wpautop treatment, so existing setups carry over unchanged.

2.0.8

  • Signup forms gained a “Redirect after signup” field (Newsletter → Signup Forms → edit form). When set, the subscriber is redirected to that URL after a successful signup instead of seeing the inline success message. The token {email} in the URL is replaced with the URL-encoded email so a follow-up page (e.g. a Stripe-checkout pricing page) can pre-fill the address. Leave blank to keep the existing inline-message behaviour.

2.0.7

  • Docs: added a “Useful links” section in the Description with pointers to the features overview, documentation, pricing, privacy policy, and contact page on onetwothreesend.com. No code changes.

2.0.6

  • Docs: clarified that the Claude API key is OPTIONAL — the plugin works fine for hand-written newsletters without it. The AI features (Generate, Rewrite, Shorten, Expand, Fix grammar, subject suggestions, tone check) only run when you click them, so a key is only needed if you want them. Updated the FAQ and install steps accordingly.

2.0.3

  • Newsletters can now be marked Free or Paid from the edit screen. Free is the default and sends the full body to every active subscriber. The companion pro plugin applies the paywall when the mode is Paid.
  • Added filter otts_send_recipients so pro-plugin Stripe paywall can segment free vs paid subscribers per newsletter.
  • Added filter otts_render_for_subscriber so pro-plugin paywall can substitute a teaser + Subscribe CTA when a free subscriber receives a paid-newsletter send.
  • Added extension points on the Settings page: otts_settings_tabs filter, otts_render_settings_tab_{tab} and otts_save_settings_{tab} actions, so companion plugins can add their own tabs without modifying free-plugin files.

2.0.2

  • Fix: differentiated Plugin URI and Author URI in the plugin header as required by the wordpress.org submission check.

2.0.1

  • wordpress.org compliance pass based on Plugin Check report.
  • Added translator comments to every translatable string with placeholders.
  • Ordered placeholders (%1$s, %2$s) in strings with multiple values.
  • Switched file operations to WP_Filesystem-aligned helpers (wp_handle_upload, wp_delete_file).
  • Tightened $_POST / $_GET sanitization pipeline (wp_unslash → sanitize_*).
  • Subscriber database queries now pass through $wpdb->prepare() end-to-end.
  • Removed legacy load_plugin_textdomain() call; WP 4.6+ auto-loads translations.

2.0.0

  • Major refactor for wordpress.org submission.
  • Removed license-gating system — all advertised features work out of the box.
  • Removed phone-home license validation.
  • Extended Phase 2 features (Stripe paywall, additional email providers, popup/slide-in forms) are now in a separate companion plugin.
  • Added filter hooks for companion plugins: otts_form_types, otts_provider_choices, otts_make_provider, otts_editor_action, otts_audit_checks.
  • Cleaner settings UI — Claude API key moved from Advanced to a dedicated AI tab.

1.0.6

  • Merged lead-magnet delivery into the welcome email (one email per signup instead of two).
  • Expired download links now auto-regenerate and email a fresh link when clicked.
  • Default download link expiry bumped to 365 days.

1.0.5

  • Improved default welcome email copy.
  • New {from_name} placeholder for email templates.

1.0.4

  • Signup form is now cache-safe — swapped the nonce for a honeypot.

1.0.3

  • Lead Magnet feature — upload a file, new subscribers receive a signed, time-limited download link.

1.0.2

  • Welcome email on signup.
  • Pre-send audit with 10 checks.
  • Reorganised settings tabs.

1.0.1

  • Hotfix for edit-newsletter page permissions.

1.0.0

  • Initial release.

Plugin Website
Visit website

Version:
2.0.20
Last Updated
May 22, 2026
Active Installs
10
Requires
WordPress 6.0
Tested Up To
WordPress 6.9.4
Requires PHP
8.1

Share Post

Join our newsletter.

Get insights into what’s happening at ChangelogWP right in your inbox. We don’t believe in spam.