AI Post Generator for WordPress: Automatically Draft Blog Posts Using OpenAI

In previous article we discussed how AI is changing how we design, develop, and even think about WordPress
In this article we will try to dig deeper and create some AI post generator to show how you can use AI to generate some post content!

Keeping up with consistent blog content creation can be a challenge. If you’re a WordPress user looking to streamline your content production, this custom solution might just be what you need.

This plugin connects your WordPress site to the OpenAI API and lets you generate blog post drafts by simply entering a topic. Let’s explore what this plugin does, how it works, and how to use it.

The AI Post Generator adds a custom admin settings page where you can input your OpenAI API key and a topic. When you click the “Generate Post Draft” button, it sends the topic to OpenAI’s API (using GPT-4o-mini, gpt-4.1, gpt-03, or some other model version), receives a full blog post in response, and inserts it as a draft in your WordPress site — all through a secure REST API endpoint.


Let’s walk you through creating a WordPress plugin that uses the OpenAI API to auto-generate blog post drafts via a REST API endpoint.
This plugin features:

  1. REST API endpoint (/wp-json/ai/v1/generate-post) for post generation.
  2. Secure access limited to logged-in users who can edit posts.
  3. Admin settings page for entering the OpenAI API key and generating content.
  4. Outputs Gutenberg-ready content with paragraph blocks.

For the beginning create a plugin folder:

/wp-content/plugins/ai-post-generator/
  └── ai-post-generator.php

Now we will populate that ai-post-generator.php with some code:

First we need to Register a custom REST API endpoint :

<?php
/**
 * Plugin Name: AI Post Generator
 * Description: Generates blog post drafts using OpenAI and REST API.
 * Version: 1.0
 * Author: WeBite
 */

// Register REST API endpoint
add_action('rest_api_init', function () {
    register_rest_route('ai/v1', '/generate-post', [
        'methods' => 'POST',
        'callback' => 'ai_generate_post', //main function
        'permission_callback' => function () {
            return current_user_can('edit_posts');
        }
    ]);
});

Handling the Request:

When the endpoint is called with a POST request containing a topic, the following steps happen:

  • The topic is sanitized.
  • The API key is retrieved from WordPress settings.
  • A request is sent to OpenAI’s chat/completions endpoint using gpt-4o-mini.
function ai_generate_post($request) {

    $params = $request->get_json_params();
    $topic = sanitize_text_field($params['topic'] ?? '');

    if (!$topic || strlen($topic) < 5) {
        return new WP_Error('no_topic', 'Please provide a longer topic.', ['status' => 400]);
    }

    $api_key = get_option('ai_post_generator_api_key');
    if (!$api_key) {
        return new WP_Error('no_api_key', 'API key not set. Please configure it in the settings.', ['status' => 500]);
    }


    $response = wp_remote_post('https://api.openai.com/v1/chat/completions', [
        'headers' => [
            'Authorization' => 'Bearer ' . $api_key,
            'Content-Type'  => 'application/json',
        ],
        'body' => json_encode([
            'model' => 'gpt-4o-mini',
            'store' => true,
            'messages' => [
                ['role' => 'system', 'content' => 'You are a helpful blog post writer.'],
                ['role' => 'user', 'content' => "Write a detailed blog post about: $topic"],
            ],
            'temperature' => 0.7,
            'max_tokens' => 700,
        ], JSON_UNESCAPED_UNICODE),
        'timeout' => 20, 
    ]);

    if (is_wp_error($response)) {
        error_log("OpenAI HTTP request failed: " . $response->get_error_message());
        return new WP_Error('openai_error', 'Failed to contact OpenAI: ' . $response->get_error_message(), ['status' => 500]);
    }

    $body_raw = wp_remote_retrieve_body($response);
    $body = json_decode($body_raw, true);

    $raw = trim($body['choices'][0]['message']['content'] ?? '');

    // Split into paragraphs
    $paragraphs = preg_split('/\n\s*\n/', $raw);

    // The response from OpenAI is split into paragraphs and wrapped with Gutenberg block comments so that the draft is compatible with the block editor:
    $blocks = array_map(function($p) {
        $p = trim($p);
        return "<!-- wp:paragraph --><p>" . esc_html($p) . "</p><!-- /wp:paragraph -->";
    }, $paragraphs);

    $content = implode("\n\n", $blocks);

// The content is saved as a draft using wp_insert_post() with the topic as the title:
    $post_id = wp_insert_post([
        'post_title'   => wp_strip_all_tags($topic),
        'post_content' => $content,
        'post_status'  => 'draft',
        'post_author'  => get_current_user_id(),
    ]);

    return [
        'success' => true,
        'post_id' => $post_id,
        'message' => 'Draft created successfully.',
    ];
}

The system prompt instructs the AI to act as a helpful blog post writer, and the user prompt asks it to write a detailed blog post on the topic.

The plugin adds a menu under Settings > AI Post Generator, where users can:

  • Enter their OpenAI API key.
  • Type a topic.
  • Click a button to generate a draft instantly via AJAX.

The interface includes a JavaScript snippet that triggers the REST API request and displays the result dynamically.

// Add settings menu
add_action('admin_menu', function () {
    add_options_page(
        'AI Post Generator Settings',
        'AI Post Generator',
        'manage_options',
        'ai-post-generator',
        'ai_post_generator_settings_page'
    );
});

// Register the setting
add_action('admin_init', function () {
    register_setting('ai_post_generator_settings', 'ai_post_generator_api_key');
});

Next, we will add function that will handle data that we will have on that page. We will need input filed for API KEY, and we will need input filed for topic that will be used by AI to create our post. Also we will add some ajax call that will help with generating our post:

function ai_post_generator_settings_page() {
    ?>
    <div class="wrap">
        <h1>AI Post Generator Settings</h1>
        <form method="post" action="options.php">
            <?php settings_fields('ai_post_generator_settings'); ?>
            <?php do_settings_sections('ai_post_generator_settings'); ?>
            <table class="form-table">
                <tr valign="top">
                    <th scope="row">OpenAI API Key</th>
                    <td>
                        <input type="text" name="ai_post_generator_api_key" value="<?php echo esc_attr(get_option('ai_post_generator_api_key')); ?>" class="regular-text" />
                    </td>
                </tr>
                <tr valign="top">
                    <th scope="row">Topic</th>
                    <td>
                        <input type="text" id="ai_post_topic" value="Your topic here" class="regular-text" />
                    </td>
                </tr>
            </table>
            <?php submit_button(); ?>
        </form>

        <!-- Button to trigger generation -->
        <button id="generate_ai_post" class="button button-primary">Generate Post Draft</button>

        <!-- Place to show result -->
        <div id="ai_post_result" style="margin-top: 20px;"></div>
    </div>

    <script>
    (function($){
        $('#generate_ai_post').on('click', function(e){
            e.preventDefault();

            var topic = $('#ai_post_topic').val();
            if(!topic) {
                alert('Please enter a topic.');
                return;
            }

            $('#ai_post_result').text('Generating post...');

            $.ajax({
                url: '<?php echo esc_url(rest_url('ai/v1/generate-post')); ?>',
                method: 'POST',
                beforeSend: function (xhr) {
                    xhr.setRequestHeader('X-WP-Nonce', '<?php echo wp_create_nonce('wp_rest'); ?>');
                },
                data: JSON.stringify({topic: topic}),
                contentType: 'application/json',
                success: function(response) {
                    if(response.success) {
                        $('#ai_post_result').html('Draft created! Post ID: ' + response.post_id);
                    } else {
                        $('#ai_post_result').text('Error: ' + (response.message || 'Unknown error'));
                    }
                },
                error: function(xhr) {
                    $('#ai_post_result').text('Request failed: ' + xhr.statusText);
                }
            });
        });
    })(jQuery);
    </script>
    <?php
}



This plugin offers a great way to bootstrap content generation in WordPress using AI. Whether you’re looking to brainstorm blog ideas or automate content pipelines, it provides a solid starting point.

You can extend it further by:

  • Adding support for categories or tags.
  • The API key is stored as a WordPress option – you might want to consider storing it securely with encryption.
  • Allowing post status selection (e.g., publish or draft).
  • Integrating with custom post types.
  • Scheduling regular content generation with cron jobs.