includes();
add_action('wp_ajax_qcld_gemini_response',[$this,'qcld_gemini_response_callback']);
add_action('wp_ajax_nopriv_qcld_gemini_response', [$this, 'qcld_gemini_response_callback']);
add_action('wp_ajax_update_settings_option', [$this, 'qcld_update_settings_option_callback']);
add_action('wp_ajax_qcld_gemini_settings_option', [$this, 'qcld_gemini_settings_option_callback']);
add_action('wp_ajax_qcld_gemini_get_model_list', [$this, 'qcld_gemini_get_model_list_callback']);
if (is_admin() && !empty($_GET["page"]) && (($_GET["page"] == "openai-panel_dashboard") || ($_GET["page"] == "openai-panel_file") || ($_GET["page"] == "openai-panel_help"))) {
add_action('admin_enqueue_scripts', array($this, 'qcld_wb_chatbot_admin_scripts'));
}
//add_action('wp_enqueue_scripts', array($this, 'qcld_wb_chatbot_gemini_scripts'));
add_action('admin_enqueue_scripts', array($this, 'qcld_wb_chatbot_gemini_admin_scripts'));
}
public function qcld_wb_chatbot_gemini_admin_scripts() {
if ( ! current_user_can( 'manage_options' ) ) {
return ;
}
wp_register_script(
'qcld-wp-chatbot-gemini-admin-js',
QCLD_wpCHATBOT_PLUGIN_URL . 'includes/integration/gemini/assets/js/qcld-wp-gemini-admin.js',
array('jquery'),
QCLD_wpCHATBOT_VERSION,
true
);
// Localize the script with necessary data
wp_localize_script('qcld-wp-chatbot-gemini-admin-js', 'qcld_gemini_admin_data', array(
'ajax_url' => admin_url('admin-ajax.php'),
'ajax_nonce' => wp_create_nonce('wp_chatbot'),
'gemini_api_key' => get_option('qcld_gemini_api_key'),
'gemini_enabled' => get_option('qcld_gemini_enabled'),
'qcld_gemini_append_content' => get_option('qcld_gemini_append_content'),
'qcld_gemini_prepend_content' => get_option('qcld_gemini_prepend_content')
));
wp_enqueue_script('qcld-wp-chatbot-gemini-admin-js');
}
/**
* Define wpbot Constants.
*
* @return void
* @since 1.0.0
*/
public function includes() {
require_once( QCLD_wpCHATBOT_PLUGIN_DIR_PATH . "includes/Parsedown.php" );
require_once( QCLD_wpCHATBOT_PLUGIN_DIR_PATH . "includes/class-common-function.php" );
}
public function qcld_gemini_settings_option_callback() {
$nonce = sanitize_text_field(wp_unslash($_POST['nonce']));
if (!wp_verify_nonce($nonce, 'wp_chatbot')) {
wp_send_json(array('success' => false, 'msg' => esc_html__('Failed in Security check', 'chatbot')));
wp_die();
} elseif ( ! current_user_can( 'manage_options' ) ) {
wp_send_json( array( 'success' => false, 'msg' => esc_html__( 'Unauthorized user', 'chatbot' ) ) );
wp_die();
} else {
$gemini_api_key = sanitize_text_field(wp_unslash($_POST['gemini_api_key']));
$gemini_enabled = sanitize_text_field(wp_unslash($_POST['gemini_enabled']));
$gemini_model = sanitize_text_field(wp_unslash($_POST['gemini_model']));
$qcld_gemini_page_suggestion_enabled = sanitize_text_field(wp_unslash($_POST['qcld_gemini_page_suggestion_enabled']));
$gemini_is_context_awareness_enabled = sanitize_text_field(wp_unslash($_POST['gemini_is_context_awareness_enabled']));
$qcld_gemini_append_content = sanitize_text_field(wp_unslash($_POST['qcld_gemini_append_content'])) ?? '';
$qcld_gemini_prepend_content = sanitize_text_field(wp_unslash($_POST['qcld_gemini_prepend_content'])) ?? '';
update_option('qcld_gemini_api_key', $gemini_api_key);
update_option('qcld_gemini_enabled', $gemini_enabled);
update_option('qcld_gemini_model', $gemini_model);
if($gemini_enabled == '1') {
update_option('ai_enabled', 0);
update_option('qcld_openrouter_enabled', 0);
update_option('qcld_grok_enabled', 0);
update_option('disable_wp_chatbot_site_search',1);
} else {
update_option('ai_enabled', 1);
}
update_option('qcld_gemini_page_suggestion_enabled', $qcld_gemini_page_suggestion_enabled);
update_option('gemeni_context_awareness_enabled', $gemini_is_context_awareness_enabled);
$openai_post_types = array();
if (isset($_POST['openai_post_type'])) {
$raw_post_types = wp_unslash($_POST['openai_post_type']);
if (is_array($raw_post_types)) {
$openai_post_types = array_map('sanitize_text_field', $raw_post_types);
} else {
$openai_post_types = sanitize_text_field($raw_post_types);
}
}
$is_page_rag_enabled = sanitize_text_field(wp_unslash($_POST['is_page_rag_enabled']));
update_option('qcld_openai_relevant_post', $openai_post_types);
update_option('is_page_rag_enabled', $is_page_rag_enabled);
update_option('qcld_gemini_append_content', $qcld_gemini_append_content);
update_option('qcld_gemini_prepend_content', $qcld_gemini_prepend_content);
// Add the check query
$gemini_api_key = get_option( 'qcld_gemini_api_key' );
$formatted_messages[] = [
'role' => 'user',
'parts' => [
['text' => 'If you get this query respond in plain text: "Congrats! You are connected to AI." Otherwise, respond with "Connection to AI failed."']
]
];
$data = array(
'contents' => $formatted_messages,
);
// Use WordPress wp_remote_post for better error handling and consistency
$args = array(
'body' => json_encode($data),
'headers' => array(
'Content-Type' => 'application/json',
'X-goog-api-key' => $gemini_api_key,
),
'timeout' => 60,
'redirection' => 5,
'blocking' => true,
'httpversion' => '1.0',
'sslverify' => true,
);
$selected_model = get_option('qcld_gemini_model') ? get_option('qcld_gemini_model') : 'gemini-2.5-flash';
$api_url = 'https://generativelanguage.googleapis.com/v1/models/' . $selected_model . ':generateContent';
$result = wp_remote_post($api_url, $args);
$result = json_decode(wp_remote_retrieve_body($result), true);
if( $result['error'] ?? false ) {
wp_send_json( array( 'status' => 'error', 'msg' => esc_html( $result['error']['message'] ) ) );
} elseif ( $result['candidates'] ?? false ) {
wp_send_json( array( 'status' => 'success', 'msg' => esc_html( $result['candidates'][0]['content']['parts'][0]['text'] ) ) );
}
wp_die();
}
// echo wp_json_encode($gemini_enabled);
wp_die();
}
public function qcld_gemini_response_callback() {
if ( ! isset( $_POST['nonce'] ) || ! wp_verify_nonce( sanitize_text_field(wp_unslash($_POST['nonce'])), 'wp_chatbot' ) ) {
wp_send_json_error([
'status' => 'error',
'message' => esc_html__( 'Security check failed. Unauthorized request.', 'chatbot' )
]);
wp_die();
}
// Temporary DB Fix for missing FULLTEXT index
global $wpdb;
$table1 = $wpdb->prefix . 'wpbot_response';
// phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching, PluginCheck.Security.DirectDB.UnescapedDBParameter
$index_exists = $wpdb->get_var("SHOW INDEX FROM `$table1` WHERE Key_name = 'query'");
if ( ! $index_exists ) {
// phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching, WordPress.DB.DirectDatabaseQuery.SchemaChange, PluginCheck.Security.DirectDB.UnescapedDBParameter
$wpdb->query("ALTER TABLE `$table1` ADD FULLTEXT(`query`, `keyword`, `response`)");
}
if (get_option('is_rate_limiting_enabled') == '1') {
do_action('rate_limit_checker');
}
$gemini_api_key = get_option( 'qcld_gemini_api_key' );
$keyword = isset($_POST['keyword']) ? sanitize_text_field( wp_unslash($_POST['keyword']) ) : '';
$relevant_pagelink = Qcld_WPBot_Common_Functions::qcpd_relevant_pagelink( $keyword );
$relevant_pagelink = array_slice( $relevant_pagelink, 0, 5, true );
if ( ( get_option( 'page_suggestion_enabled' ) == '1' ) && count( $relevant_pagelink ) > 0 ) {
$relevant_post_link = maybe_unserialize( get_option( 'qlcd_wp_chatbot_relevant_post_link_openai' ) );
// Always use get_locale() to avoid undefined function error
$locale = get_locale();
if ( is_array( $relevant_post_link ) && isset( $relevant_post_link[ $locale ] ) && is_array( $relevant_post_link[ $locale ] ) ) {
$relevant_pagelinks = '
' . implode( '', $relevant_post_link[ $locale ] ) . '
' . implode( '', $relevant_pagelink );
} else {
// Fallback: try to use $locale, but check if key exists
$em_text = '';
if ( is_array( $relevant_post_link ) && isset( $relevant_post_link[ $locale ] ) ) {
$em_text = is_array( $relevant_post_link[ $locale ] ) ? implode( '', $relevant_post_link[ $locale ] ) : $relevant_post_link[ $locale ];
}
$relevant_pagelinks = '
' . $em_text . '
' . implode( '', $relevant_pagelink ); } } else { $relevant_pagelinks = ''; } $Qcld_Parsedown = new Qcld_Parsedown(); $is_playground = isset($_POST['is_ai_actions_playground']) && intval($_POST['is_ai_actions_playground']) === 1; // Build context-aware content with system instructions $system_instructions = $is_playground ? 'You are a helpful AI assistant. You MUST strictly follow the interactive form instructions if the user asks for them.' : ''; // AI Interactive Form if (get_option('enable_ai_interactive_form') == '1') { $saved_ai_forms = get_option('wpbot_ai_forms', array()); if (!empty($saved_ai_forms) && is_array($saved_ai_forms)) { $system_instructions .= "\n\nYou must handle the following interactive forms when the user asks for them:\n"; foreach ($saved_ai_forms as $form) { $system_instructions .= "\nForm Title: " . $form['title'] . "\nInstructions: " . $form['prompt'] . "\n"; } $system_instructions .= "\n\nCRITICAL INSTRUCTIONS FOR INTERACTIVE FORMS:\n"; $system_instructions .= "When a user triggers an interactive form, you must act as a step-by-step data collection agent.\n"; $system_instructions .= "1. DO NOT ask all questions at once. Ask exactly ONE question at a time.\n"; $system_instructions .= "2. Wait for the user's response before asking the next question.\n"; $system_instructions .= "3. Once all necessary information is collected for the form, you MUST output a final JSON block summarizing the collected data. The keys inside the \"data\" object MUST be dynamically named based on the specific questions you asked during the form collection (e.g., \"Full Name\", \"Company Size\", \"Email\", etc.). The final JSON block must be wrapped EXACTLY in these delimiters:\n"; $system_instructions .= "__AI_FORM_DATA__{ \"form_title\": \"