Pro Facebook posting (One Two Three Post Pro)

← All docs

Facebook posting plugin

General

Looking for the newsletter plugin? See its docs →

One Two Three Post Pro — automated Facebook posts, quality-gated

One Two Three Post Pro is a companion plugin to the free One Two Three Post. The free plugin gives you a composer + scheduler — you type in posts, it sends them to Facebook. Pro turns that into a self-running posting machine: it auto-generates the posts for you, runs them through a quality gate before they fire, and surfaces anything that went wrong. The free plugin must be installed and active first — Pro extends it, it does not replace it.

What Pro adds, end-to-end:

  • Content auto-fill — an hourly cron tops your queue up to a target depth (default 12 posts in the next 24 hours) by auto-generating posts of three types in configurable ratios: photo posts (a recent WordPress post + its featured image, with a short caption), text questions (engagement prompts from an editable pool, with Claude as a fallback), and newsletter teasers (curiosity-gap hooks as native coloured-background text posts with the signup link in the first comment). You can disable any type by setting its weight to zero; the others fill the slot. A separate Hours between posts setting controls the spacing between consecutive auto-fill posts (default 1, max 24 — set to 2 to post every 2 hours, 3 for every 3 hours, etc.).
  • Pre-publish validator chain — every queued post runs through seven configurable checks 10 minutes before it fires: AI-generated image filenames, perceptual-hash image duplicates, duplicate captions, seasonal mismatches, banned-word matches, same-type-back-to-back (type rotation), and minimum spacing between sends. Strictness toggles per check. Anything that fails is held with the reason logged on the post.
  • Image pipeline — auto-resize on publish so an oversized featured image doesn’t bloat the Facebook upload, perceptual-hash deduplication so the same picture doesn’t cycle through the queue, and an auto-prune cron to keep the hash table from growing forever.
  • Editor loop — every six hours Pro re-runs the validator chain in pre-check mode against everything firing in the next 24 hours. If a validator would block at publish time, the post is flipped to pending right now with the error visible in the queue, so you see problems hours before they’d have fired silently.
  • First-comment auto-detection — if a queued post mentions a recent WordPress post’s title, matches a configured category keyword, or contains a teaser phrase like “have you heard…”, Pro automatically fills in the corresponding WordPress permalink as the first comment. Operator-set first-comment values are never overwritten.
  • Queue dashboard — a single Settings page shows every scheduled post, recent validator activity, and any first-comment failures from the last 7 days with one-click Dismiss / Reconnect Facebook actions.

The net effect: enable auto-fill once, set the queue target, and Pro keeps Facebook running 24/7 with posts generated from your own content, in the format that performs best on Facebook (native coloured-background text posts get reach a plain link post never will), with bad posts caught before they ship.

Distribution and pricing

Free to verified subscribers of the One Two Three Send daily newsletter — exactly the same model as One Two Three Send Pro. Distributed as a standalone zip via a custom manifest, not through wp.org. After installing, open One Two Three Post → Pro Settings and verify your subscriber email; auto-updates flow from then on.

Pro features keep working forever regardless of verification status. Only the auto-update channel is gated — if you let your subscription lapse, the plugin continues to validate posts on the version you have installed, you just stop receiving new releases until you re-verify.

What it adds

  • Pre-publish validator chain — runs against every queued post immediately before the free plugin’s WP-Cron worker pushes it to Facebook. A WP_Error from any validator blocks the publish and records the reason against the post.
  • Configurable strictness — toggle each validator on/off independently from Pro Settings. Defaults are conservative; turn on the ones that match how strict you want the gate to be.
  • Validation log — every pass/fail decision is recorded with the post ID, validator name, and human-readable message. View the last 50 in the admin widget on the Pro Settings page.
  • Subscriber-verified auto-updates — the standard yellow “Update available” badge appears in WP Admin → Plugins; the download is gated on your verified subscriber email.

First-run walkthrough

Top three operator questions on day one — answered here so you can configure with confidence:

How long after I enable auto-fill will posts appear?

  • First post in the queue: within ~60 minutes. The cron fires hourly and the first tick is scheduled 5 minutes after activation.
  • Queue fills to target depth: one post per cron fire (hourly), capped at your Target queue depth setting.
  • First Facebook publish: controlled by the Hours between posts setting (default 1). The slot picker schedules each new auto-fill post for latest queued time + spacing hours, so setting spacing to 2 publishes every 2 hours, 3 every 3 hours, etc. With spacing 1 and an empty queue, the first publish happens ~1 hour after the post lands in the queue.

Watch Pro Settings → Queue overview — new rows tagged with the auto badge confirm the cron is working. If nothing appears after an hour, the usual suspects are: target queue depth already met by manual posts; no Facebook page selected in the dropdown; WP-Cron not firing on a low-traffic site (hit /wp-cron.php?doing_wp_cron=1 once manually to force a tick).

Do I need a Claude API key?

No — Claude is optional. Auto-fill has three generator types:

  • Photo (recent WP post + headline as caption) — no Claude needed.
  • Newsletter promo (templated + signup URL in first comment) — no Claude needed.
  • Text question (open-ended question for engagement) — Claude needed. Silently dropped without a key; remaining ratios redistribute.

If you want Text question posts, paste a Claude API key into the field in Pro Settings → Content auto-fill. Post Pro is self-sufficient — you do not need One Two Three Send installed alongside. If you do have both plugins installed and OTTS already has a Claude key configured, Post Pro inherits it automatically.

My Facebook account has dozens of Pages — how do I pick one?

The free plugin’s OAuth flow connects to every Facebook Page your account manages. Auto-fill needs to know which single Page to target. In Pro Settings → Content auto-fill, the topmost field is a Facebook page dropdown listing every connected Page. Pick the one Post Pro should auto-post to and save. Manual composer posts (via New / Compose) keep their own per-post picker, so you can still send hand-written posts to any of your other connected Pages.

Installing

  1. Install the free plugin from wordpress.org/plugins/one-two-three-post, activate it, and connect a Facebook Page in Settings. Pro requires the free plugin to be active — it will show a notice and stay dormant otherwise.
  2. Subscribe to the One Two Three Send daily newsletter if you haven’t already (free). The Pro zip is included in the welcome email.
  3. Upload the Pro zip via Plugins → Add New → Upload Plugin and activate it.
  4. Open One Two Three Post → Pro Settings, paste your subscriber email, click Verify. The validator chain starts running on the next scheduled post.

Validators and what they check

Every validator can be turned on or off independently. The list below covers what ships in Phase 1 + Phase 4 of the Pro plugin. Later phases (queue management, image pipeline, content mix) are on the roadmap and will reuse the same toggle pattern.

Block AI-generated image filenames

Rejects any post whose attached image filename matches a configurable regex pattern. Defaults catch the common AI-generator prefixes (discover_featured, ai_, dalle_, sdxl_, mj_). If you’re posting genuine AI artwork on purpose, leave this off — it’s intended to catch leakage from automated image pipelines that shouldn’t be facing Facebook.

Block duplicate images

Refuses to publish an image the plugin has already sent within the last N days (configurable, default 90). Match is by MD5 hash plus a perceptual hash, so trivially-resized variants still count as duplicates. Useful if you have a growing media library and want to avoid the same hero photo cycling out twice in a quarter.

Block duplicate captions

Same idea as the image check, but against the post body / caption text. Default lookback is 90 days. Catches the case where two scheduled posts ended up with near-identical wording — a common failure mode when captions are templated from a small pool of phrasings.

Block seasonally-mismatched content

Refuses to publish a post whose text references a season or holiday that’s outside the current window — e.g. “Christmas markets” scheduled for July, or “summer rooftop bars” scheduled for January. Uses a built-in month-keyword map; matches are case-insensitive. Off by default since the rules are conservative and may catch deliberately off-season content.

Block banned-word matches

One word/phrase per line in the textarea. Any post whose caption contains a case-insensitive match is blocked. Useful for trade-marked terms, competitor names, or topical content you’ve decided shouldn’t go out on this Page without manual review.

Block same-type-back-to-back (type rotation)

Rejects a queued post whose type matches the last N published posts in a row. Default N = 2, meaning a third same-type post in a row blocks. Catches the failure mode where a content generator runs out of variety and starts churning out the same format. Off by default; turn on once you’ve established a rhythm you don’t want to drift from.

Block too-close publishes (spacing)

Rejects a publish that fires within N minutes of another. Default 60 minutes. Stops the page from going quiet for hours then dumping three posts at once because a backlog cleared at the same moment. Earlier post wins; the later one moves to Pending with the reason logged.

When a post is blocked

Blocked posts move to Pending status with the validator’s reason stored as the last error — exactly the same lifecycle the free plugin uses for Facebook API failures. The post appears in the standard All Posts list with the error message visible; you can fix the underlying issue (swap the image, edit the caption) and re-queue manually, or delete the post entirely. The free plugin’s normal 3-attempt retry behaviour is short-circuited by validator blocks — there’s no point retrying a deterministic rule failure.

Validation log

Every validator decision — pass or fail — is recorded in wp_ottpost_pro_validation_log with the post ID, the validator name, the result, and a human-readable message. The Pro Settings page surfaces the last 50 rows in a widget at the bottom; older rows are kept for 30 days and then pruned by the daily cleanup cron.

What’s coming later

The current release ships Phase 1 (foundation + settings) and Phase 4 (validators). Future phases — implemented when there’s demand — will add:

  • Rolling queue — maintain a configurable depth (e.g. 12 posts across 24 hours), append one post at a time, enforce type rotation (no two photo posts back-to-back).
  • Image pipeline — Unsplash + WP media library waterfall with 512×624 crop-to-fill, perceptual-hash dedup, optional headline-on-photo overlay for article share posts.
  • Content mix engine — configurable per-Page ratios across post types (Photo / Text Question / Article Share / Newsletter Promo), with caption generation pulled from your WP posts.
  • First-comment automation — auto-add article links or recipe URLs to the first comment based on caption keywords.

If any of these would be valuable for how you run your Page, send a note via the contact form — usage signal is what moves items off the roadmap.

Content auto-fill

Picking which Facebook page

The free plugin’s OAuth flow connects to every Facebook page your account manages — that can be 50+ pages on some accounts. Auto-fill needs to know which single page to target. Open One Two Three Post → Pro Settings → Content auto-fill and pick the page from the dropdown at the top of that panel. Auto-generated posts will only go to that page from then on.

Manual composer posts (when you click New / Compose) keep their own per-post page picker — you can still send manually-written posts to any connected page. The Pro Settings selector controls auto-fill only.

If the selected page is later disconnected or its access token is revoked by Facebook, auto-fill halts silently rather than picking a different page at random. Check the page selection in Pro Settings after any Facebook reconnect.

The Pro plugin can keep your Facebook queue topped up automatically. When enabled, an hourly WP-Cron job checks how many posts you have scheduled in the next 24 hours; if you’re below your target queue depth (default 12), it appends one auto-generated post scheduled 24 hours from now. Repeats hourly until the queue is full, then idles.

Three generator types ship in 1.4.0:

  • Photo — picks a recent WordPress post that has a featured image and that you haven’t auto-shared inside the image dedup window. The post’s headline becomes the caption; the permalink lands in the first comment (which is what Facebook’s algorithm prefers for external links). Self-dedups against the existing image hash registry.
  • Text question — picks an open-ended engagement question from an operator-editable pool (Pro Settings → Text question pool; seeded with 20 generic questions). Posts as a native Facebook coloured-background text post for higher reach (post-type slug coloured_background in the post meta, in case you’re inspecting the queue). If the pool is empty, falls back to a Claude API call instead. Claude key configurable in Pro Settings — Post Pro is self-sufficient and doesn’t need One Two Three Send installed.
  • Newsletter teaser — rotates a curiosity-gap hook from an operator-editable library (Pro Settings → Newsletter teaser hooks). Posts as a native Facebook coloured-background text post — much higher visual punch than a plain post. Signup URL lands in the first comment only. Capped at 1 per 24 hours. Default hook library is generic (“The places that don’t make it into the brochures, every week”); replace with hooks specific to your topic for much better engagement.

You set relative weights for each type (default 50/25/25 — Photo / Text Question / Newsletter Promo). They don’t need to add up to 100. A type with weight 0 never appears. If a type can’t fire right now (no Claude key, no recent WP posts with featured images), the selector silently redistributes to the remaining types so the queue keeps moving.

Every auto-generated post is tagged with an auto badge in the queue overview below, so you can tell at a glance which ones were composed by you and which were filled in by the system. Edit or delete works the same way for both.

Disable the toggle any time. Already-queued auto-generated posts stay queued — turning it off just stops new ones being added.

Image pipeline

Auto-resize on publish

When the toggle is on, Pro re-crops the attached image to a configurable target aspect ratio just before pushing the post to Facebook. Defaults to 1200×630 — the Open Graph aspect ratio Facebook recommends for link previews. Auto-fix rather than a block: the operator never sees a publish fail because of an aspect mismatch.

Resized variants are stored as regular WordPress attachments with the original as their parent, so the second publish of the same image is a cache hit — no re-cropping cost. Operators who post the same hero image to multiple newsletters get a single, fast crop.

Perceptual hash deduplication

The duplicate-image validator now computes an 8×8 average-hash (aHash) on every attachment in addition to the MD5 check. This catches images that have been resized, re-encoded, or lightly cropped — variants that have a different MD5 but still look the same to a viewer. Matches against the dedup window via Hamming distance with a conservative default threshold of 8 (out of 64 bits), so genuinely distinct images aren’t false-flagged as dupes.

Auto-prune

A daily WP-Cron job deletes hash rows older than twice the dedup window. The table stays bounded over time — sites running for years don’t accumulate hash data from images outside the lookup window anyway.

Editor loop

Auto-fill generates posts and schedules them 24 hours out. The editor loop is a second WP-Cron job that runs every 6 hours, picks up every post scheduled to fire in the next 24 hours, and runs the entire validator chain against it early. If a validator would have blocked the post at publish time, it moves to pending status right now — with the failure reason on the post — so you see the problem hours or even a full day before it would have fired, with time to fix or replace.

This is the closest parallel in the plugin to the original Python automation system’s editor pass, which runs six times a day for the same reason: catching problems early instead of at the moment of publish. The plugin’s implementation is simpler — it doesn’t auto-fix anything, just promotes the failure earlier — but the operator effect is similar.

Per-post 12-hour cooldown so the same post doesn’t get re-evaluated on every 6-hour tick. Editor decisions write to the same validation log as publish-time decisions, so the Recent validations widget shows both in chronological order.

First-comment auto-detection

The first comment on a Facebook post is usually where a successful operator puts the external link — Facebook’s algorithm tends to deprioritise posts that have a link in the body, so the workaround is “intro in the post, link in the first comment”. The free plugin already supports this with a manual First comment field in the composer. The Pro plugin can fill that field automatically when the operator leaves it empty.

Three detectors run in priority order at publish time. First match wins. An operator-set value is never overwritten.

  1. Title mentions (on by default) — if the caption contains the exact title of a recent WP post (3+ word title to avoid one-word false positives), link to that post. The most specific match.
  2. Category keywords (off by default) — operator configures a keyword: category-slug map (e.g. recipe: food). When the caption contains a configured keyword, link to the latest published post in that category.
  3. Teaser phrases (off by default) — captions like “Have you heard…”, “The story behind…”, “Most people don’t know” imply there’s more to the story. The plugin appends a link to the latest WP post as a soft fallback. The default phrase list is editable.

Each detector has its own toggle in Pro Settings, so you can run with just title-mentions on and skip the more aggressive ones, or any combination. When a detector fires, the source (mention, category, teaser) is recorded in _ottpost_pro_fc_source post meta — useful for auditing which detector chose a link.

Queue overview

From 1.8.2: if any post in the last 7 days published its parent post successfully but the optional first-comment failed (most commonly with (#200) You do not have sufficient permissions when the page access token is missing the pages_manage_engagement scope), a red error banner appears at the top of the Queue overview. The banner lists the affected posts with their error messages and provides a one-click Reconnect Facebook button when the failure is a permissions error. See the troubleshooting entry for the full fix.

From 1.8.3: the banner clears automatically when you reconnect Facebook (the OAuth callback fires a hook that drops the stale permission-error markers). For any non-permission errors that linger, each row has a Dismiss link and the table has a Dismiss all button — use them once you have verified subsequent posts are commenting cleanly.

The Pro Settings page shows a Queue overview table with the next 20 scheduled (or pending-retry) posts ordered by scheduled time. Each row shows when it fires, the post type, an 80-character caption preview, current status, and quick links to edit or delete the post. A summary line at the top shows scheduled counts in the next 24 hours and 7 days so the depth of the queue is visible at a glance without paging through the free plugin’s calendar view.

Delete confirms before removing the post — the free plugin’s standard All Posts screen is still where to go for bulk operations and bin recovery. The dashboard is read-mostly, optimised for “what’s coming up next” rather than archive editing.

Troubleshooting

  • “Verify your subscriber email” notice won’t go away. The email you entered isn’t in the active subscriber list. Either subscribe at onetwothreesend.com using that email first, or use the email you originally subscribed with. Verification calls the same endpoint as One Two Three Send Pro; one subscription covers both Pro plugins.
  • Validators aren’t running. The free plugin (One Two Three Post) must be installed and active. The Pro plugin shows a dormant notice if it isn’t. Also check that at least one validator is toggled on in Pro Settings — they’re all off by default for a clean install.
  • A post was blocked I didn’t expect. Check the validation log widget on the Pro Settings page for the most recent decision — the reason field tells you which validator fired. If a default rule is too strict (banned-word match catches something legitimate, dedup window too long), tune it from the same page.