AIPromptTheory Suite · Free & Educational
Engine.
The content engine under your site's hood. AI-powered article campaigns that research, write, illustrate and publish on schedule — using your prompts and your choice of five AI providers. Plus the complete guide to how we built it.
The pitch
Everything Engine does
Autoblogging done responsibly: your prompts, your editorial gates, your provider keys — with the machinery to run it hands-free once you trust it.
🗂️ Campaigns
- Keyword lists, custom prompts & writing personality per campaign
- Article format & length controls, content variations
- Daily or custom schedules; pause/resume per campaign
- Category rules for automatic placement
- Duplicate-title detection — no accidental reruns
🤖 AI providers
- OpenAI, Claude, Gemini, Grok & DeepSeek
- Per-campaign provider and model selection
- One abstract provider class — add new APIs in ~50 lines
- API keys encrypted at rest (AES-256-CBC)
- Key test button so you know it works before a campaign runs
⏱️ Pipeline
- Content queue with pending → approved → published flow
- Draft-first mode for human review, or full auto-publish
- Three WP-Cron workers: campaign checks, queue processing, log cleanup
- Generate-now button when you can't wait for cron
- Failed items logged with the exact error, retryable
🚀 Publishing extras
- DALL·E featured images with Pexels fallback
- SEO schema JSON attached to every generated post
- Social-media snippets generated alongside the article
- Editorial calendar view + full activity log
- Dashboard with campaign health at a glance
Chapter 1
The campaign model: recipes, not buttons
The core abstraction is the campaign — a stored recipe that says what to write about (keywords), how to write it (prompt, personality, format, length, variations), who writes it (provider + model), where it lands (category rules, post status) and when (schedule). Once saved, the campaign runs itself; you manage recipes, not posts.
That one design decision shapes everything else in the plugin: campaigns are rows, runs are queue items, and every action is logged against its campaign — so "why did this post happen?" always has an answer.
draft status — full-auto is a choice you make deliberately, per campaign, after
you've seen what it produces.Chapter 2
Four tables: campaigns, queue, logs, keys
Engine's state lives in four custom tables: awp_campaigns (the recipes, with status
and next-run time), awp_content_queue (every generated piece and its lifecycle),
awp_activity_logs (who did what, when, with what result) and awp_api_keys
(encrypted provider credentials).
CREATE TABLE wp_awp_campaigns (
id bigint(20) UNSIGNED NOT NULL AUTO_INCREMENT,
name varchar(255) NOT NULL,
type varchar(50) NOT NULL,
status varchar(20) NOT NULL DEFAULT 'active',
settings longtext, -- the whole recipe, JSON
next_run datetime DEFAULT NULL, -- the clock
PRIMARY KEY (id),
KEY status (status),
KEY next_run (next_run)
);The next_run index is the heartbeat: the cron worker asks one cheap question —
"which active campaigns are due?" — and the database answers from the index. Settings are a
JSON blob on purpose: campaign options evolve fast, and schema migrations for every new
toggle would be madness.
Chapter 3
The provider factory: five AIs, one interface
OpenAI, Claude, Gemini, Grok and DeepSeek all speak different dialects of "give me an
article". Engine hides that behind one abstract class — each provider implements
generate_content(), and shared logic (prompt building, JSON parsing, error
normalisation) lives in the parent.
abstract class AIPT_Engine_AI_Provider {
abstract public function generate_content( $prompt, $args );
// shared: build_prompt(), parse_json_response(), error handling
}
class AIPT_Engine_AI_Factory {
public static function create( $provider = 'google_gemini', $model = null ) {
switch ( $provider ) {
case 'openai': return new AIPT_Engine_OpenAI( $model );
case 'claude': return new AIPT_Engine_Claude( $model );
case 'grok': return new AIPT_Engine_Grok( $model );
case 'deepseek': return new AIPT_Engine_DeepSeek( $model );
default: return new AIPT_Engine_Gemini( $model );
}
}
}Adding a sixth provider is a ~50-line subclass and one case. The campaign UI reads the
provider list dynamically, so new engines appear in the dropdown automatically. This is the
open/closed principle earning its keep in WordPress.
Chapter 4
API keys: encrypted at rest, tested before use
API keys are credentials with a credit card attached — storing them as plain options is negligence. Engine generates a per-site 256-bit key on activation and encrypts every provider key with AES-256-CBC and a random IV before it touches the database.
$iv = openssl_random_pseudo_bytes( 16 );
$encrypted = openssl_encrypt( $key, 'aes-256-cbc',
AIPT_ENGINE_ENCRYPTION_KEY, 0, $iv );
// store iv + ciphertext; decrypt only in memory, only when calling the APIChapter 5
The queue & three cron workers
Generation is slow (an AI round-trip can take 30+ seconds) so nothing generates inside a page request. Three WP-Cron workers split the labour:
awp_check_campaigns(hourly) — finds campaigns whosenext_runhas passed, asks the provider for content, and files the result in the queue aspending. Duplicate titles are detected and skipped with a logged warning.awp_process_queue(hourly, offset) — takes approved items, creates the WordPress post (draft or publish per campaign), attaches images, schema and snippets, and marks the itemcompleted— orfailedwith the exact error message for retry.awp_cleanup_logs(daily) — prunes old activity logs so the table never becomes the biggest thing in your database.
The status flow — pending → approved → completed / failed — is the editorial gate:
in review mode a human clicks approve; in full-auto the processor approves its own work.
Either way the audit log records it.
Chapter 6
Publishing extras: images, schema, snippets
A wall of AI text isn't a post. When a queue item publishes, Engine also:
- Generates a featured image via DALL·E — with an automatic Pexels stock-photo fallback when image generation fails or is disabled, so posts never ship naked.
- Attaches SEO schema — a JSON-LD block stored in post meta and injected on render, so generated articles arrive structured-data-ready.
- Writes social snippets — short share-ready blurbs stored alongside the post, one less thing to write when you promote it.
- Tags its work — every generated post carries a meta flag, so you can query, audit or bulk-manage AI content separately from human writing. Transparency is a feature.
Chapter 7
Mission control: dashboard, calendar, logs
Six admin screens in the suite's shared dark/light theme: a dashboard with campaign health and recent activity; campaigns for creating and managing recipes; the queue with inline approve/edit/reject; an editorial calendar showing what's scheduled to land when; logs for the full audit trail; and settings for provider keys (with a test button that verifies a key against the live API before you bet a campaign on it).
The calendar is the sleeper feature: autoblogging goes wrong when you lose track of volume. Seeing next week as a grid — three posts Tuesday, nothing Thursday — turns a firehose into an editorial plan.
Chapter 8
Shipping it — including the scars
require_once strings but not the files on disk — instant fatal. We renamed the files and
the references in one pass and verified every require resolves before zipping. If you rebrand
this plugin (please do), follow the map below and check requires last.extension_loaded( 'openssl' ) and shows a polite admin notice instead. Fail loudly,
fail early, fail politely.Plus the standing checklist: prepared statements, nonce + capability checks on every AJAX action, escaped output, sanitised campaign settings, translation-ready strings, and cron events cleared on deactivation.
Make it yours
Rebrand it. Seriously, we encourage it.
The rename map for Engine — change these consistently (and read Scar #1 and #2 first):
| What | Ours | Yours |
|---|---|---|
| Plugin folder & main file | aipt-engine/ | your-brand-engine/ |
| Plugin Name header | AIPromptTheory Engine | YourBrand Engine |
| Class prefix & file names | AIPT_Engine_* / class-aipt-engine-*.php | rename files and requires together |
| Admin page slugs | aipt-engine-dashboard … | your-brand-engine-dashboard … |
| Encryption key option | aipt_engine_encryption_key | rename with a copy-migration — or lose every stored API key |
| DB tables & cron hooks | wp_awp_*, awp_* | keep them — neutral names, zero migration risk |
Free, as in education
Get Engine + request the add-on pack
Engine is free. The add-ons are free too — we build them in the order people ask. Tell us which one you want next and we'll email you when it ships.
Part of the AIPromptTheory suite: