Create your own Chat GPT Interface plugin for WordPress using OpenAI’s API

black samsung flat screen computer monitor

Creating an application that interfaces with OpenAI’s API using PHP (potentially within the WordPress ecosystem), HTML, and vanilla JavaScript involves several steps. Below is a comprehensive guide to building a clean, attractive, and performant interface that allows users to interact with various OpenAI API features, including model selection (e.g., DALL·E 3 for image generation), prompt input, file attachments, and additional context.

Table of Contents

  1. Overview
  2. Prerequisites
  3. Setting Up the Environment
  4. Designing the Front-End Interface
  5. Implementing the Back-End with PHP
  6. Integrating with OpenAI’s API
  7. Handling File Uploads
  8. Security Considerations
  9. Optimizing Performance
  10. Deployment
  11. Sample Code
  12. Conclusion

Overview

The application will provide a user-friendly interface where users can:

  • Select from various OpenAI models (including DALL·E 3).
  • Enter prompts for text or image generation.
  • Attach files if required.
  • Provide additional context or parameters.
  • View responses from OpenAI’s API.

We will build this application as a WordPress plugin to leverage WordPress’s ecosystem, security features, and ease of integration. However, the principles can be adapted for a standalone PHP application.

Prerequisites

Before you begin, ensure you have the following:

  • Web Server: Apache or Nginx.
  • PHP: Version 7.4 or higher.
  • WordPress: Latest version if opting to build within WordPress.
  • OpenAI API Key: Obtain from OpenAI.
  • Basic Knowledge: PHP, HTML, CSS, JavaScript, and WordPress plugin development.

Setting Up the Environment

WordPress Installation: If not already installed, set up WordPress on your server.

Plugin Structure: Create a new folder in wp-content/plugins/ named openai-interface.

Main Plugin File: Create openai-interface.php inside the plugin folder.phpCopy code

<?php
/*
Plugin Name: OpenAI Interface
Description: A plugin to interact with OpenAI's API through a user-friendly interface.
Version: 1.0
Author: Your Name
*/

// Exit if accessed directly
if (!defined('ABSPATH')) {
    exit;
}

// Include necessary files
include_once plugin_dir_path(__FILE__) . 'includes/openai-interface-functions.php';

Additional Files: Create an includes folder for organizing PHP functions and a assets folder for CSS and JavaScript.

Designing the Front-End Interface

Create a clean and responsive interface using HTML and CSS. Utilize modern design principles for attractiveness and usability.

Shortcode Creation: Allow users to embed the interface anywhere using a shortcode.In openai-interface-functions.php:phpCopy code

<?php
// Register shortcode
function openai_interface_shortcode() {
    ob_start();
    ?>
    <div id="openai-interface">
        <form id="openai-form">
            <div class="form-group">
                <label for="model">Select Model:</label>
                <select id="model" name="model">
                    <option value="gpt-4">GPT-4</option>
                    <option value="gpt-3.5-turbo">GPT-3.5 Turbo</option>
                    <option value="dalle-3">DALL·E 3</option>
                    <!-- Add more models as needed -->
                </select>
            </div>
            <div class="form-group">
                <label for="prompt">Prompt:</label>
                <textarea id="prompt" name="prompt" required></textarea>
            </div>
            <div class="form-group">
                <label for="file">Attach File:</label>
                <input type="file" id="file" name="file">
            </div>
            <div class="form-group">
                <label for="context">Extra Context:</label>
                <textarea id="context" name="context"></textarea>
            </div>
            <button type="submit">Submit</button>
        </form>
        <div id="response"></div>
    </div>
    <?php
    return ob_get_clean();
}
add_shortcode('openai_interface', 'openai_interface_shortcode');

Styling with CSS: Add CSS for a clean and attractive layout.In assets/css/style.css:cssCopy code

#openai-interface {
    max-width: 600px;
    margin: 0 auto;
    padding: 20px;
    background-color: #f9f9f9;
    border-radius: 8px;
    box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
}

.form-group {
    margin-bottom: 15px;
}

label {
    display: block;
    margin-bottom: 5px;
    font-weight: bold;
}

input[type="text"],
textarea,
select {
    width: 100%;
    padding: 8px;
    border: 1px solid #ccc;
    border-radius: 4px;
    box-sizing: border-box;
}

button {
    padding: 10px 20px;
    background-color: #0073aa;
    color: #fff;
    border: none;
    border-radius: 4px;
    cursor: pointer;
}

button:hover {
    background-color: #005177;
}

#response {
    margin-top: 20px;
    padding: 15px;
    background-color: #fff;
    border: 1px solid #ddd;
    border-radius: 4px;
}

Enqueueing Styles and Scripts:In openai-interface-functions.php:phpCopy code

// Enqueue CSS and JS
function openai_interface_enqueue_assets() {
    if (is_page() || is_single()) { // Adjust conditions as needed
        wp_enqueue_style('openai-interface-style', plugin_dir_url(__FILE__) . '../assets/css/style.css');
        wp_enqueue_script('openai-interface-script', plugin_dir_url(__FILE__) . '../assets/js/script.js', array('jquery'), '1.0', true);

        // Localize script to pass AJAX URL and nonce
        wp_localize_script('openai-interface-script', 'openai_ajax_obj', array(
            'ajax_url' => admin_url('admin-ajax.php'),
            'nonce'    => wp_create_nonce('openai_ajax_nonce')
        ));
    }
}
add_action('wp_enqueue_scripts', 'openai_interface_enqueue_assets');

Implementing the Back-End with PHP

Handle form submissions, process inputs, and communicate with OpenAI’s API securely.

AJAX Handler:In openai-interface-functions.php:phpCopy code

// Handle AJAX request
function openai_interface_handle_request() {
    check_ajax_referer('openai_ajax_nonce', 'nonce');

    // Sanitize inputs
    $model = sanitize_text_field($_POST['model']);
    $prompt = sanitize_textarea_field($_POST['prompt']);
    $context = sanitize_textarea_field($_POST['context']);

    // Handle file upload if exists
    $file_data = null;
    if (!empty($_FILES['file']['name'])) {
        require_once(ABSPATH . 'wp-admin/includes/file.php');
        $uploaded = wp_handle_upload($_FILES['file'], array('test_form' => false));

        if (isset($uploaded['file'])) {
            $file_path = $uploaded['file'];
            $file_type = wp_check_filetype($file_path);
            $file_data = base64_encode(file_get_contents($file_path));
            // Optionally, delete the file after reading
            unlink($file_path);
        } else {
            wp_send_json_error('File upload failed.');
        }
    }

    // Prepare data for OpenAI API
    $api_key = 'YOUR_OPENAI_API_KEY'; // Securely store and retrieve this
    $endpoint = 'https://api.openai.com/v1/';

    // Determine API endpoint based on model
    if ($model === 'dalle-3') {
        $endpoint .= 'images/generations';
        $data = array(
            'prompt' => $prompt,
            'n' => 1,
            'size' => '1024x1024'
            // Add more parameters as needed
        );
    } else {
        $endpoint .= 'chat/completions';
        $data = array(
            'model' => $model,
            'messages' => array(
                array('role' => 'user', 'content' => $prompt)
            ),
            'temperature' => 0.7
            // Add more parameters as needed
        );
    }

    // Initialize cURL
    $ch = curl_init($endpoint);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    curl_setopt($ch, CURLOPT_HTTPHEADER, array(
        'Content-Type: application/json',
        'Authorization: Bearer ' . $api_key
    ));
    curl_setopt($ch, CURLOPT_POST, true);
    curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($data));

    // Execute request
    $response = curl_exec($ch);
    $http_code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
    curl_close($ch);

    if ($http_code == 200) {
        wp_send_json_success(json_decode($response, true));
    } else {
        wp_send_json_error('API request failed with response: ' . $response);
    }
}
add_action('wp_ajax_openai_request', 'openai_interface_handle_request');
add_action('wp_ajax_nopriv_openai_request', 'openai_interface_handle_request');

Storing the API Key Securely:

Option 1: Define in wp-config.php:

Add the following line to wp-config.php

define('OPENAI_API_KEY', 'your-openai-api-key'); 

Then, in your plugin:

$api_key = OPENAI_API_KEY;

Option 2: Use WordPress Options:

Create an admin settings page where you can input the API key.

Store it using update_option and retrieve with get_option.

Integrating with OpenAI’s API

Communicate with OpenAI’s API by sending HTTP requests with the necessary parameters.

  • Text Generation: Use the /v1/chat/completions endpoint.
  • Image Generation: Use the /v1/images/generations endpoint.

Ensure that the application dynamically adjusts based on the selected model.

Handling File Uploads

If the API requires file attachments (e.g., for certain endpoints like fine-tuning), handle file uploads securely:

  1. Validate File Types and Sizes: Restrict to allowed MIME types and size limits to prevent malicious uploads.
  2. Use WordPress’s File Handling Functions: Utilize wp_handle_upload for secure processing.
  3. Temporary Storage: Process the file and remove it immediately after use to avoid storage bloat.

Security Considerations

  1. API Key Protection: Never expose the API key on the client-side. Always handle API interactions server-side.
  2. Nonce Verification: Use WordPress nonces to protect against CSRF attacks.
  3. Input Sanitization: Sanitize and validate all user inputs to prevent XSS and other injection attacks.
  4. File Upload Security: Restrict file types, sizes, and handle uploads securely.
  5. Error Handling: Avoid exposing sensitive error information to users.

Optimizing Performance

  1. Asynchronous Requests: Use AJAX to handle form submissions without reloading the page.
  2. Caching Responses: Implement caching for repeated requests to reduce API calls and improve response times.
  3. Minimize Asset Sizes: Compress CSS and JavaScript files. Use minification techniques.
  4. Lazy Loading: Load resources only when needed.
  5. Efficient Code: Write optimized PHP and JavaScript code to reduce server load and enhance speed.

Deployment

  1. Testing: Thoroughly test the application in a staging environment.
  2. Security Audit: Ensure all security measures are in place.
  3. Performance Testing: Use tools like Google Lighthouse to assess and optimize performance.
  4. Launch: Deploy the plugin to the live WordPress site.
  5. Monitoring: Continuously monitor for errors, performance issues, and security threats.

Sample Code

Below are sample implementations for the front-end and back-end components.

Front-End: HTML & JavaScript

HTML Structure (via Shortcode):

As previously defined in the shortcode function.

JavaScript for Handling Form Submission (assets/js/script.js):

javascriptCopy codedocument.addEventListener('DOMContentLoaded', function () {
    const form = document.getElementById('openai-form');
    const responseDiv = document.getElementById('response');

    form.addEventListener('submit', function (e) {
        e.preventDefault();

        const formData = new FormData(form);
        formData.append('action', 'openai_request');
        formData.append('nonce', openai_ajax_obj.nonce);

        // Show loading state
        responseDiv.innerHTML = 'Processing...';

        fetch(openai_ajax_obj.ajax_url, {
            method: 'POST',
            body: formData
        })
            .then(response => response.json())
            .then(data => {
                if (data.success) {
                    // Display the response based on the model
                    const model = form.querySelector('#model').value;
                    if (model === 'dalle-3') {
                        const imageUrl = data.data.data[0].url;
                        responseDiv.innerHTML = `<img src="${imageUrl}" alt="Generated Image" style="max-width: 100%;">`;
                    } else {
                        const message = data.data.choices[0].message.content;
                        responseDiv.innerHTML = `<pre>${message}</pre>`;
                    }
                } else {
                    responseDiv.innerHTML = `<span style="color: red;">${data.data}</span>`;
                }
            })
            .catch(error => {
                responseDiv.innerHTML = `<span style="color: red;">An error occurred: ${error.message}</span>`;
            });
    });
});

Explanation:

  • Event Listener: Waits for the DOM to load and attaches a submit event listener to the form.
  • FormData: Collects form data, including the file if attached.
  • AJAX Request: Sends the data to the server using the Fetch API.
  • Response Handling: Displays the generated text or image based on the selected model.
  • Error Handling: Shows error messages if the request fails.

Back-End: PHP

Handling AJAX Requests:

As previously defined in the openai_interface_handle_request function.

Enhancements:

  1. Dynamic Parameters: Allow users to set additional OpenAI API parameters via the interface.
  2. Support for Multiple Models: Extend model options and handle specific requirements for each model.
  3. Response Formatting: Improve how responses are displayed, supporting markdown or rich content.
  4. Logging: Optionally log requests and responses for auditing or analytics.

Complete openai-interface-functions.php Example:

phpCopy code<?php
// Exit if accessed directly
if (!defined('ABSPATH')) {
    exit;
}

// Register shortcode
function openai_interface_shortcode() {
    ob_start();
    ?>
    <div id="openai-interface">
        <form id="openai-form" enctype="multipart/form-data">
            <div class="form-group">
                <label for="model">Select Model:</label>
                <select id="model" name="model" required>
                    <option value="gpt-4">GPT-4</option>
                    <option value="gpt-3.5-turbo">GPT-3.5 Turbo</option>
                    <option value="dalle-3">DALL·E 3</option>
                    <!-- Add more models as needed -->
                </select>
            </div>
            <div class="form-group">
                <label for="prompt">Prompt:</label>
                <textarea id="prompt" name="prompt" required></textarea>
            </div>
            <div class="form-group">
                <label for="file">Attach File:</label>
                <input type="file" id="file" name="file" accept=".txt,.jpg,.png,.pdf">
            </div>
            <div class="form-group">
                <label for="context">Extra Context:</label>
                <textarea id="context" name="context"></textarea>
            </div>
            <button type="submit">Submit</button>
        </form>
        <div id="response"></div>
    </div>
    <?php
    return ob_get_clean();
}
add_shortcode('openai_interface', 'openai_interface_shortcode');

// Enqueue CSS and JS
function openai_interface_enqueue_assets() {
    if (is_page() || is_single()) { // Adjust conditions as needed
        wp_enqueue_style('openai-interface-style', plugin_dir_url(__FILE__) . '../assets/css/style.css');
        wp_enqueue_script('openai-interface-script', plugin_dir_url(__FILE__) . '../assets/js/script.js', array('jquery'), '1.0', true);

        // Localize script to pass AJAX URL and nonce
        wp_localize_script('openai-interface-script', 'openai_ajax_obj', array(
            'ajax_url' => admin_url('admin-ajax.php'),
            'nonce'    => wp_create_nonce('openai_ajax_nonce')
        ));
    }
}
add_action('wp_enqueue_scripts', 'openai_interface_enqueue_assets');

// Handle AJAX request
function openai_interface_handle_request() {
    check_ajax_referer('openai_ajax_nonce', 'nonce');

    // Sanitize inputs
    $model = sanitize_text_field($_POST['model']);
    $prompt = sanitize_textarea_field($_POST['prompt']);
    $context = sanitize_textarea_field($_POST['context']);

    // Handle file upload if exists
    $file_data = null;
    if (!empty($_FILES['file']['name'])) {
        require_once(ABSPATH . 'wp-admin/includes/file.php');
        $uploaded = wp_handle_upload($_FILES['file'], array('test_form' => false));

        if (isset($uploaded['file'])) {
            $file_path = $uploaded['file'];
            $file_type = wp_check_filetype($file_path);
            $file_data = base64_encode(file_get_contents($file_path));
            // Optionally, delete the file after reading
            unlink($file_path);
        } else {
            wp_send_json_error('File upload failed.');
        }
    }

    // Prepare data for OpenAI API
    $api_key = OPENAI_API_KEY; // Ensure this is defined securely
    $endpoint = 'https://api.openai.com/v1/';

    // Determine API endpoint based on model
    if ($model === 'dalle-3') {
        $endpoint .= 'images/generations';
        $data = array(
            'prompt' => $prompt,
            'n' => 1,
            'size' => '1024x1024'
            // Add more parameters as needed
        );
    } else {
        $endpoint .= 'chat/completions';
        $data = array(
            'model' => $model,
            'messages' => array(
                array('role' => 'user', 'content' => $prompt)
            ),
            'temperature' => 0.7
            // Add more parameters as needed
        );

        // Include context if provided
        if (!empty($context)) {
            $data['messages'][] = array('role' => 'system', 'content' => $context);
        }
    }

    // Initialize cURL
    $ch = curl_init($endpoint);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    curl_setopt($ch, CURLOPT_HTTPHEADER, array(
        'Content-Type: application/json',
        'Authorization: Bearer ' . $api_key
    ));
    curl_setopt($ch, CURLOPT_POST, true);
    curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($data));

    // Execute request
    $response = curl_exec($ch);
    $http_code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
    curl_close($ch);

    if ($http_code == 200) {
        wp_send_json_success(json_decode($response, true));
    } else {
        wp_send_json_error('API request failed with response: ' . $response);
    }
}
add_action('wp_ajax_openai_request', 'openai_interface_handle_request');
add_action('wp_ajax_nopriv_openai_request', 'openai_interface_handle_request');

Conclusion

Building an interface to interact with OpenAI’s API within the WordPress ecosystem involves careful planning of both front-end and back-end components. By leveraging WordPress’s plugin architecture, you can create a secure, maintainable, and user-friendly application. Ensure that you adhere to best practices in security, performance optimization, and user experience design to deliver a robust solution.

Feel free to expand upon this foundation by adding features such as user authentication, usage tracking, support for more OpenAI API endpoints, and enhanced UI/UX elements to cater to specific user needs.

Leave a Comment

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.