admin_url('admin-ajax.php', is_ssl() ? 'https' : 'relative'), 'nonce' => wp_create_nonce( 'rapidtextai_nonce' ), 'api_key' => get_option('rapidtextai_api_key', ''), 'rest_url' => esc_url_raw( rest_url( 'rapidtextai/v1' ) ), 'rest_nonce' => wp_create_nonce( 'wp_rest' ), 'post_id' => (int) get_the_ID(), 'default_engine' => function_exists( 'rapidtextai_default_engine' ) ? rapidtextai_default_engine() : 'v2', ) ); // Enqueue the modal trigger button script (follows same pattern as featured.js) wp_enqueue_script( 'rapidtextai_generate_modal', plugin_dir_url( __FILE__ ) . 'assets/js/generate-modal.js', array( 'jquery' ), filemtime( plugin_dir_path( __FILE__ ) . 'assets/js/generate-modal.js' ), true ); wp_localize_script( 'rapidtextai_generate_modal', 'rapidtextai_modal', array( 'icon_url' => 'https://app.rapidtextai.com/assets/images/fav.png?v=1.1', ) ); // Render the Generate Article modal HTML + CSS in the footer add_action( 'admin_footer', 'rapidtextai_render_generate_modal' ); } add_action( 'admin_enqueue_scripts', 'rapidtextai_metabox_enqueue_scripts' ); /** * Outputs the Generate Article modal overlay and injects the trigger button * next to the Featured Image meta box in the post editor. */ function rapidtextai_render_generate_modal() { // The new React build (app.js) mounts the meta box into #rapidtextai-root. $js_file = RAPIDTEXTAI_PLUGIN_DIR . 'assets/js/app.js'; $css_file = RAPIDTEXTAI_PLUGIN_DIR . 'assets/css/app.css'; $metabox_js_url = esc_url( RAPIDTEXTAI_PLUGIN_URL . 'assets/js/app.js?ver=' . ( file_exists( $js_file ) ? filemtime( $js_file ) : '1' ) ); $metabox_css_url = esc_url( RAPIDTEXTAI_PLUGIN_URL . 'assets/css/app.css?ver=' . ( file_exists( $css_file ) ? filemtime( $css_file ) : '1' ) ); $icon_url = 'https://app.rapidtextai.com/assets/images/fav.png?v=1.1'; ?> 'Invalid nonce', )); } // Get POST data $type = isset( $_POST['type'] ) ? sanitize_text_field( $_POST['type'] ) : ''; $tone_of_voice = isset( $_POST['toneOfVoice'] ) ? sanitize_text_field( $_POST['toneOfVoice'] ) : ''; $language = isset( $_POST['language'] ) ? sanitize_text_field( $_POST['language'] ) : 'en'; $text = isset( $_POST['text'] ) ? sanitize_textarea_field( $_POST['text'] ) : ''; $temperature = isset( $_POST['temperature'] ) ? sanitize_text_field( $_POST['temperature'] ) : '0.7'; $custom_prompt = isset( $_POST['custom_prompt'] ) ? sanitize_textarea_field( $_POST['custom_prompt'] ) : ''; $chatsession = isset( $_POST['chatsession'] ) ? sanitize_text_field( $_POST['chatsession'] ) : 'rapidtextai__'.sanitize_text_field( $_POST['model'] ).'_' . time() . '_' . wp_rand(); $userid = isset( $_POST['userid'] ) ? sanitize_text_field( $_POST['userid'] ) : ''; // Handle model if ( isset( $_POST['model'] ) && ! empty( $_POST['model'] ) ) { $model = sanitize_text_field( $_POST['model'] ); } else { $model = 'default_model'; // Set a default model if not provided } // Handle custom prompt // Build the API request payload in OpenAI format $api_payload = json_encode([ 'model' => $model, 'messages' => [ [ 'role' => 'user', 'content' => $custom_prompt ] ], 'chatsession' => $chatsession, ]); // Now, make the API call $current_api_key = get_option('rapidtextai_api_key', ''); // API endpoint with API key $api_url = "https://app.rapidtextai.com/openai/v1/chat/completionsarticle?gigsixkey=" . urlencode( $current_api_key ); // Set up headers for the request $args = array( 'body' => $api_payload, 'headers' => array( 'Content-Type' => 'application/json', ), 'timeout' => 60, ); // Make the API request $response = wp_remote_post($api_url, $args); // Handle the response if (is_wp_error($response)) { if ($return) { return $response->get_error_message(); } wp_send_json_error(array( 'message' => $response->get_error_message(), )); } else { $body = wp_remote_retrieve_body($response); $data = json_decode($body, true); // Check if response is valid JSON and has expected OpenAI format if (json_last_error() !== JSON_ERROR_NONE) { wp_send_json_error(array( 'message' => 'Invalid response format from API', 'raw' => $body )); } else { // Pass through the OpenAI formatted response if($return){ return $data; } else { wp_send_json_success($data); } } } } add_action( 'wp_ajax_rapidtextai_generate_article', 'rapidtextai_generate_article' ); // Add this new streaming function function rapidtextai_generate_article_stream() { // Check nonce if ( ! isset( $_POST['nonce'] ) || ! wp_verify_nonce( $_POST['nonce'], 'rapidtextai_nonce' ) ) { wp_send_json_error(array('message' => 'Invalid nonce')); return; } // Get POST data $custom_prompt = isset( $_POST['custom_prompt'] ) ? sanitize_textarea_field( $_POST['custom_prompt'] ) : ''; $model = isset( $_POST['model'] ) ? sanitize_text_field( $_POST['model'] ) : 'gemini-2.0-flash'; $chatsession = isset( $_POST['chatsession'] ) ? sanitize_text_field( $_POST['chatsession'] ) : 'rapidtextai_'.$model.'_' . time() . '_' . wp_rand(); // Build the API request payload with streaming enabled $api_payload = json_encode([ 'model' => $model, 'messages' => [ [ 'role' => 'user', 'content' => $custom_prompt ] ], 'stream' => true, // Enable streaming 'chatsession' => $chatsession, ]); $current_api_key = get_option('rapidtextai_api_key', ''); $api_url = "https://app.rapidtextai.com/openai/v1/chat/completionsarticle-stream?gigsixkey=" . urlencode( $current_api_key ); // Set SSE headers header('Content-Type: text/event-stream'); header('Cache-Control: no-cache'); header('Connection: keep-alive'); header('X-Accel-Buffering: no'); // Disable output buffering while (ob_get_level()) { ob_end_flush(); } ob_implicit_flush(true); // Initialize cURL for streaming $ch = curl_init(); curl_setopt_array($ch, [ CURLOPT_URL => $api_url, CURLOPT_POST => true, CURLOPT_SSL_VERIFYPEER => false, CURLOPT_SSL_VERIFYHOST => false, CURLOPT_POSTFIELDS => $api_payload, CURLOPT_HTTPHEADER => [ 'Content-Type: application/json', ], CURLOPT_WRITEFUNCTION => function($curl, $data) { // Forward streaming data directly to client echo $data; flush(); return strlen($data); }, CURLOPT_TIMEOUT => 300, CURLOPT_RETURNTRANSFER => false, ]); curl_exec($ch); $error = curl_error($ch); curl_close($ch); if ($error) { echo "data: " . json_encode(['error' => ['message' => $error]]) . "\n\n"; } exit(); } add_action( 'wp_ajax_rapidtextai_generate_article_stream', 'rapidtextai_generate_article_stream' );