PluginProbe
WPBot – AI ChatBot for Live Support, Lead Generation, WordPress Automation, AI Services / 8.8.1
WPBot – AI ChatBot for Live Support, Lead Generation, WordPress Automation, AI Services v8.8.1
8.8.1 8.8.0 8.7.9 8.7.8 8.7.7 8.7.6 8.7.5 8.7.4 8.7.3 8.7.2 8.7.1 8.7.0 8.6.9 8.6.8 8.6.7 8.6.6 8.6.5 8.6.4 8.6.2 8.6.1 8.6.0 8.5.9 8.5.8 8.5.7 8.5.6 All 537 releases
chatbot / includes / integration / gemini / qcld-bot-gemini.php

qcld-bot-gemini.php in WPBot – AI ChatBot for Live Support, Lead Generation, WordPress Automation, AI Services 8.8.1, at includes/integration/gemini/qcld-bot-gemini.php

586 lines 25.5 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 if (!defined('ABSPATH')) exit; // Exit if accessed directly
3
4 if(!class_exists('qcld_wpgemini_addons')){
5
6
7 /**
8 * Main Class.
9 */
10 final class qcld_wpgemini_addons
11 {
12 private $id = 'Open AI';
13
14 /**
15 * WPBot Pro version.
16 *
17 * @var string
18 */
19 public $version = '1.0.6';
20
21 /**
22 * WPBot Pro helper.
23 *
24 * @var object
25 */
26 public $helper;
27
28 /**
29 * The single instance of the class.
30 *
31 * @var qcld_wb_Chatbot
32 * @since 1.0.0
33 */
34 protected static $_instance = null;
35
36 /**
37 * Main wpbot Instance.
38 *
39 * Ensures only one instance of wpbot is loaded or can be loaded.
40 *
41 * @return qcld_wb_Chatbot - Main instance.
42 * @since 1.0.0
43 * @static
44 */
45 public static function instance() {
46 if ( is_null( self::$_instance ) ) {
47 self::$_instance = new self();
48 }
49
50 return self::$_instance;
51 }
52
53 public $response_list;
54
55 /**
56 * Constructor
57 */
58 public function __construct()
59 {
60
61 $this->includes();
62 add_action('wp_ajax_qcld_gemini_response',[$this,'qcld_gemini_response_callback']);
63 add_action('wp_ajax_nopriv_qcld_gemini_response', [$this, 'qcld_gemini_response_callback']);
64 add_action('wp_ajax_update_settings_option', [$this, 'qcld_update_settings_option_callback']);
65 add_action('wp_ajax_qcld_gemini_settings_option', [$this, 'qcld_gemini_settings_option_callback']);
66 add_action('wp_ajax_qcld_gemini_get_model_list', [$this, 'qcld_gemini_get_model_list_callback']);
67
68 if (is_admin() && !empty($_GET["page"]) && (($_GET["page"] == "openai-panel_dashboard") || ($_GET["page"] == "openai-panel_file") || ($_GET["page"] == "openai-panel_help"))) {
69 add_action('admin_enqueue_scripts', array($this, 'qcld_wb_chatbot_admin_scripts'));
70 }
71 //add_action('wp_enqueue_scripts', array($this, 'qcld_wb_chatbot_gemini_scripts'));
72 add_action('admin_enqueue_scripts', array($this, 'qcld_wb_chatbot_gemini_admin_scripts'));
73 }
74
75
76
77 public function qcld_wb_chatbot_gemini_admin_scripts() {
78 if ( ! current_user_can( 'manage_options' ) ) {
79 return ;
80 }
81 wp_register_script(
82 'qcld-wp-chatbot-gemini-admin-js',
83 QCLD_wpCHATBOT_PLUGIN_URL . 'includes/integration/gemini/assets/js/qcld-wp-gemini-admin.js',
84 array('jquery'),
85 QCLD_wpCHATBOT_VERSION,
86 true
87 );
88
89 // Localize the script with necessary data
90 wp_localize_script('qcld-wp-chatbot-gemini-admin-js', 'qcld_gemini_admin_data', array(
91 'ajax_url' => admin_url('admin-ajax.php'),
92 'ajax_nonce' => wp_create_nonce('wp_chatbot'),
93 'gemini_api_key' => get_option('qcld_gemini_api_key'),
94 'gemini_enabled' => get_option('qcld_gemini_enabled'),
95 'qcld_gemini_append_content' => get_option('qcld_gemini_append_content'),
96 'qcld_gemini_prepend_content' => get_option('qcld_gemini_prepend_content')
97 ));
98
99 wp_enqueue_script('qcld-wp-chatbot-gemini-admin-js');
100 }
101
102 /**
103 * Define wpbot Constants.
104 *
105 * @return void
106 * @since 1.0.0
107 */
108 public function includes() {
109 require_once( QCLD_wpCHATBOT_PLUGIN_DIR_PATH . "includes/Parsedown.php" );
110 require_once( QCLD_wpCHATBOT_PLUGIN_DIR_PATH . "includes/class-common-function.php" );
111 }
112 public function qcld_gemini_settings_option_callback() {
113 $nonce = sanitize_text_field(wp_unslash($_POST['nonce']));
114 if (!wp_verify_nonce($nonce, 'wp_chatbot')) {
115 wp_send_json(array('success' => false, 'msg' => esc_html__('Failed in Security check', 'chatbot')));
116 wp_die();
117 } elseif ( ! current_user_can( 'manage_options' ) ) {
118 wp_send_json( array( 'success' => false, 'msg' => esc_html__( 'Unauthorized user', 'chatbot' ) ) );
119 wp_die();
120 } else {
121 $gemini_api_key = sanitize_text_field(wp_unslash($_POST['gemini_api_key']));
122 $gemini_enabled = sanitize_text_field(wp_unslash($_POST['gemini_enabled']));
123 $gemini_model = sanitize_text_field(wp_unslash($_POST['gemini_model']));
124 $qcld_gemini_page_suggestion_enabled = sanitize_text_field(wp_unslash($_POST['qcld_gemini_page_suggestion_enabled']));
125 $gemini_is_context_awareness_enabled = sanitize_text_field(wp_unslash($_POST['gemini_is_context_awareness_enabled']));
126 $qcld_gemini_append_content = sanitize_text_field(wp_unslash($_POST['qcld_gemini_append_content'])) ?? '';
127 $qcld_gemini_prepend_content = sanitize_text_field(wp_unslash($_POST['qcld_gemini_prepend_content'])) ?? '';
128 update_option('qcld_gemini_api_key', $gemini_api_key);
129 update_option('qcld_gemini_enabled', $gemini_enabled);
130 update_option('qcld_gemini_model', $gemini_model);
131 if($gemini_enabled == '1') {
132 update_option('ai_enabled', 0);
133 update_option('qcld_openrouter_enabled', 0);
134 update_option('qcld_grok_enabled', 0);
135 update_option('disable_wp_chatbot_site_search',1);
136
137 } else {
138 update_option('ai_enabled', 1);
139 }
140 update_option('qcld_gemini_page_suggestion_enabled', $qcld_gemini_page_suggestion_enabled);
141 update_option('gemeni_context_awareness_enabled', $gemini_is_context_awareness_enabled);
142 $openai_post_types = array();
143 if (isset($_POST['openai_post_type'])) {
144 $raw_post_types = wp_unslash($_POST['openai_post_type']);
145 if (is_array($raw_post_types)) {
146 $openai_post_types = array_map('sanitize_text_field', $raw_post_types);
147 } else {
148 $openai_post_types = sanitize_text_field($raw_post_types);
149 }
150 }
151 $is_page_rag_enabled = sanitize_text_field(wp_unslash($_POST['is_page_rag_enabled']));
152 update_option('qcld_openai_relevant_post', $openai_post_types);
153 update_option('is_page_rag_enabled', $is_page_rag_enabled);
154 update_option('qcld_gemini_append_content', $qcld_gemini_append_content);
155 update_option('qcld_gemini_prepend_content', $qcld_gemini_prepend_content);
156
157 // Add the check query
158 $gemini_api_key = get_option( 'qcld_gemini_api_key' );
159 $formatted_messages[] = [
160 'role' => 'user',
161 'parts' => [
162 ['text' => 'If you get this query respond in plain text: "Congrats! You are connected to AI." Otherwise, respond with "Connection to AI failed."']
163 ]
164 ];
165 $data = array(
166 'contents' => $formatted_messages,
167 );
168
169 // Use WordPress wp_remote_post for better error handling and consistency
170 $args = array(
171 'body' => json_encode($data),
172 'headers' => array(
173 'Content-Type' => 'application/json',
174 'X-goog-api-key' => $gemini_api_key,
175 ),
176 'timeout' => 60,
177 'redirection' => 5,
178 'blocking' => true,
179 'httpversion' => '1.0',
180 'sslverify' => true,
181 );
182 $selected_model = get_option('qcld_gemini_model') ? get_option('qcld_gemini_model') : 'gemini-2.5-flash';
183 $api_url = 'https://generativelanguage.googleapis.com/v1/models/' . $selected_model . ':generateContent';
184 $result = wp_remote_post($api_url, $args);
185 $result = json_decode(wp_remote_retrieve_body($result), true);
186 if( $result['error'] ?? false ) {
187 wp_send_json( array( 'status' => 'error', 'msg' => esc_html( $result['error']['message'] ) ) );
188 } elseif ( $result['candidates'] ?? false ) {
189 wp_send_json( array( 'status' => 'success', 'msg' => esc_html( $result['candidates'][0]['content']['parts'][0]['text'] ) ) );
190 }
191
192 wp_die();
193
194 }
195 // echo wp_json_encode($gemini_enabled);
196 wp_die();
197 }
198 public function qcld_gemini_response_callback() {
199 if ( ! isset( $_POST['nonce'] ) || ! wp_verify_nonce( sanitize_text_field(wp_unslash($_POST['nonce'])), 'wp_chatbot' ) ) {
200 wp_send_json_error([
201 'status' => 'error',
202 'message' => esc_html__( 'Security check failed. Unauthorized request.', 'chatbot' )
203 ]);
204 wp_die();
205 }
206
207 // Temporary DB Fix for missing FULLTEXT index
208 global $wpdb;
209 $table1 = $wpdb->prefix . 'wpbot_response';
210 // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching, PluginCheck.Security.DirectDB.UnescapedDBParameter
211 $index_exists = $wpdb->get_var("SHOW INDEX FROM `$table1` WHERE Key_name = 'query'");
212 if ( ! $index_exists ) {
213 // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching, WordPress.DB.DirectDatabaseQuery.SchemaChange, PluginCheck.Security.DirectDB.UnescapedDBParameter
214 $wpdb->query("ALTER TABLE `$table1` ADD FULLTEXT(`query`, `keyword`, `response`)");
215 }
216
217 if (get_option('is_rate_limiting_enabled') == '1') {
218 do_action('rate_limit_checker');
219 }
220 $gemini_api_key = get_option( 'qcld_gemini_api_key' );
221 $keyword = isset($_POST['keyword']) ? sanitize_text_field( wp_unslash($_POST['keyword']) ) : '';
222
223 $relevant_pagelink = Qcld_WPBot_Common_Functions::qcpd_relevant_pagelink( $keyword );
224 $relevant_pagelink = array_slice( $relevant_pagelink, 0, 5, true );
225
226 if ( ( get_option( 'page_suggestion_enabled' ) == '1' ) && count( $relevant_pagelink ) > 0 ) {
227 $relevant_post_link = maybe_unserialize( get_option( 'qlcd_wp_chatbot_relevant_post_link_openai' ) );
228 // Always use get_locale() to avoid undefined function error
229 $locale = get_locale();
230 if ( is_array( $relevant_post_link ) && isset( $relevant_post_link[ $locale ] ) && is_array( $relevant_post_link[ $locale ] ) ) {
231 $relevant_pagelinks = '<br><br><p><em>' . implode( '', $relevant_post_link[ $locale ] ) . '</em><p>' . implode( '</br>', $relevant_pagelink );
232 } else {
233 // Fallback: try to use $locale, but check if key exists
234 $em_text = '';
235 if ( is_array( $relevant_post_link ) && isset( $relevant_post_link[ $locale ] ) ) {
236 $em_text = is_array( $relevant_post_link[ $locale ] ) ? implode( '', $relevant_post_link[ $locale ] ) : $relevant_post_link[ $locale ];
237 }
238 $relevant_pagelinks = '<br><br><p><em>' . $em_text . '</em><p>' . implode( '</br>', $relevant_pagelink );
239 }
240 } else {
241 $relevant_pagelinks = '';
242 }
243
244 $Qcld_Parsedown = new Qcld_Parsedown();
245
246 $is_playground = isset($_POST['is_ai_actions_playground']) && intval($_POST['is_ai_actions_playground']) === 1;
247
248 // Build context-aware content with system instructions
249 $system_instructions = $is_playground ? 'You are a helpful AI assistant. You MUST strictly follow the interactive form instructions if the user asks for them.' : '';
250
251 // AI Interactive Form
252 if (get_option('enable_ai_interactive_form') == '1') {
253 $saved_ai_forms = get_option('wpbot_ai_forms', array());
254 if (!empty($saved_ai_forms) && is_array($saved_ai_forms)) {
255 $system_instructions .= "\n\nYou must handle the following interactive forms when the user asks for them:\n";
256 foreach ($saved_ai_forms as $form) {
257 $system_instructions .= "\nForm Title: " . $form['title'] . "\nInstructions: " . $form['prompt'] . "\n";
258 }
259 $system_instructions .= "\n\nCRITICAL INSTRUCTIONS FOR INTERACTIVE FORMS:\n";
260 $system_instructions .= "When a user triggers an interactive form, you must act as a step-by-step data collection agent.\n";
261 $system_instructions .= "1. DO NOT ask all questions at once. Ask exactly ONE question at a time.\n";
262 $system_instructions .= "2. Wait for the user's response before asking the next question.\n";
263 $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";
264 $system_instructions .= "__AI_FORM_DATA__{ \"form_title\": \"<Form Title>\", \"data\": { \"Question 1\": \"Answer 1\", \"Question 2\": \"Answer 2\" } }__AI_FORM_DATA_END__\n";
265 $system_instructions .= "Do not include any other text after this JSON block once the form is complete.\n";
266 $system_instructions .= "4. If the user provides an invalid, irrelevant, or nonsensical answer to your question, DO NOT apologize or state that you lack information. Instead, politely inform the user in the language of the conversation (the language the user is speaking in, e.g. German if communicating in German) that their answer is invalid or cannot be assigned, and ask the exact same question again in the user's language. NEVER output the English phrase 'Invalid answer found' unless the user is communicating in English.\n";
267 $system_instructions .= "5. MULTI-LANGUAGE SUPPORT: Always communicate, ask questions, validate answers, and reply strictly in the user's language (matching the language used by the user, e.g. German, French, Spanish, etc.). Understand and accept valid answers in the user's language.";
268 }
269 }
270
271 if ( !$is_playground && get_option('gemeni_context_awareness_enabled') == '1' ) {
272 $site_name = get_bloginfo('name');
273 $site_desc = get_bloginfo('description');
274
275 // Get current page URL and title more reliably
276 $current_url = '';
277 $page_title = '';
278 $page_summary = '';
279
280 // Try to get from referrer first
281 $ref = wp_get_referer();
282 if ( ! $ref && isset($_SERVER['HTTP_REFERER']) ) {
283 $ref = esc_url_raw( $_SERVER['HTTP_REFERER'] );
284 }
285
286 if ( $ref ) {
287 $current_url = $ref;
288
289 // Try to get post/page by URL, fallback to query param if needed.
290 $post_id = url_to_postid( $ref );
291 if ( ! $post_id && isset( $_GET['p'] ) ) {
292 $post_id = intval( wp_unslash($_GET['p']) );
293 }
294 if ( $post_id ) {
295 $page_title = get_the_title( $post_id );
296 $raw_content = get_post_field( 'post_content', $post_id );
297 $text_content = wp_strip_all_tags( $raw_content );
298 $page_summary = wp_trim_words( $text_content, 120, '…' );
299 } else {
300 // If not a post/page, try to extract title from URL or use current page
301 $parsed_url = wp_parse_url( $ref );
302 if ( isset($parsed_url['path']) ) {
303 $path = trim($parsed_url['path'], '/');
304 if ( ! empty($path) ) {
305 // Try to get title from current page if we're on it
306 if ( is_singular() ) {
307 $page_title = get_the_title();
308 $raw_content = get_the_content();
309 $text_content = wp_strip_all_tags( $raw_content );
310 $page_summary = wp_trim_words( $text_content, 120, '…' );
311 } elseif ( is_archive() ) {
312 $page_title = get_the_archive_title();
313 } elseif ( is_search() ) {
314 $page_title = 'Search Results';
315 } elseif ( is_404() ) {
316 $page_title = 'Page Not Found';
317 }
318 }
319 }
320 }
321 } else {
322 // Fallback to current page info.
323 $scheme = (isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] === 'on' ? "https" : "http");
324
325 // Sanitize HTTP_HOST and REQUEST_URI from $_SERVER.
326 $sanitized_host = isset($_SERVER['HTTP_HOST']) ? sanitize_text_field($_SERVER['HTTP_HOST']) : '';
327 $sanitized_request_uri = isset($_SERVER['REQUEST_URI']) ? esc_url_raw($_SERVER['REQUEST_URI']) : '';
328
329 // Construct the URL with sanitized components.
330 $current_url_temp = $scheme . '://' . $sanitized_host . $sanitized_request_uri;
331
332 // Final sanitization of the entire URL string.
333 $current_url = esc_url_raw($current_url_temp);
334
335 if ( is_singular() ) {
336 $page_title = get_the_title();
337 $raw_content = get_the_content();
338 $text_content = wp_strip_all_tags( $raw_content );
339 $page_summary = wp_trim_words( $text_content, 120, '…' );
340 } elseif ( is_archive() ) {
341 $page_title = get_the_archive_title();
342 } elseif ( is_search() ) {
343 $page_title = 'Search Results';
344 } elseif ( is_404() ) {
345 $page_title = 'Page Not Found';
346 }
347 }
348
349 $context_bits = array();
350 if ( $site_name ) { $context_bits[] = 'Site: ' . $site_name; }
351 if ( $site_desc ) { $context_bits[] = 'Tagline: ' . $site_desc; }
352 if ( $page_title ) { $context_bits[] = 'Page title: ' . $page_title; }
353 if ( $current_url ) { $context_bits[] = 'URL: ' . $current_url; }
354 if ( $page_summary ) { $context_bits[] = 'Page summary: ' . $page_summary; }
355
356 if ( ! empty( $context_bits ) ) {
357 if (!empty($system_instructions)) {
358 $system_instructions .= "\n\nContext Information: " . implode( '. ', $context_bits ) . '. Please use this context to provide more relevant and accurate responses.';
359 } else {
360 $system_instructions = 'Context Information: ' . implode( '. ', $context_bits ) . '. Please use this context to provide more relevant and accurate responses.';
361 }
362 }
363 }
364
365 $action_prompt = !empty($_POST['action_prompt']) ? wp_unslash($_POST['action_prompt']) : '';
366 if (!empty($action_prompt)) {
367 $system_instructions .= "\n\nCRITICAL ACTIVE ACTION INSTRUCTION:\n" . $action_prompt;
368 }
369
370 // RAG Integration
371 if (get_option('is_page_rag_enabled') == '1') {
372 $rag_context_text = Qcld_Bot_Rag::instance()->run_rag_search($keyword);
373 if (!empty($rag_context_text) && $rag_context_text != "No knowledge base found.") {
374 $rag_context = "Relevant Knowledge Base Information:\n";
375 $rag_context .= $rag_context_text;
376 $rag_context .= "\n\nUse the above information to answer the user's question. If the answer is not in the Knowledge Base, rely on your general knowledge but mention that this information is not in the local knowledge base.";
377
378 if (!empty($system_instructions)) {
379 $system_instructions .= "\n\n" . $rag_context;
380 } else {
381 $system_instructions = $rag_context;
382 }
383 }
384 }
385
386 if ( ( get_option( 'page_suggestion_enabled' ) == '1' ) && count( $relevant_pagelink ) > 0 ) {
387 $relevant_post_link = maybe_unserialize( get_option( 'qlcd_wp_chatbot_relevant_post_link_openai' ) );
388 $locale = get_locale();
389 if ( !$is_playground && is_array( $relevant_post_link ) && isset( $relevant_post_link[ $locale ] ) && is_array( $relevant_post_link[ $locale ] ) ) {
390 $relevant_pagelinks = '<br><br><p><em>' . implode( '', $relevant_post_link[ $locale ] ) . '</em><p>' . implode( '</br>', $relevant_pagelink );
391 } else {
392 $em_text = '';
393 if ( !$is_playground && is_array( $relevant_post_link ) && isset( $relevant_post_link[ $locale ] ) ) {
394 $em_text = is_array( $relevant_post_link[ $locale ] ) ? implode( '', $relevant_post_link[ $locale ] ) : $relevant_post_link[ $locale ];
395 }
396 $relevant_pagelinks = '<br><br><p><em>' . $em_text . '</em><p>' . implode( '</br>', $relevant_pagelink );
397 }
398 } else {
399 $relevant_pagelinks = '';
400 }
401
402 $selected_model = get_option('qcld_gemini_model') ? get_option('qcld_gemini_model') : 'gemini-2.5-flash';
403 $api_url = 'https://generativelanguage.googleapis.com/v1/models/' . $selected_model . ':generateContent';
404
405 $formatted_messages = [];
406
407 if ( ! empty( $system_instructions ) ) {
408 $formatted_messages[] = [
409 'role' => 'user',
410 'parts' => [
411 ['text' => "[System Instructions] " . $system_instructions]
412 ]
413 ];
414
415 $formatted_messages[] = [
416 'role' => 'model',
417 'parts' => [
418 ['text' => "I understand and will follow these instructions."]
419 ]
420 ];
421 }
422
423 if (!empty($_POST['ai_history'])) {
424 $parsed_history = json_decode(wp_unslash($_POST['ai_history']), true);
425 if (is_array($parsed_history)) {
426 foreach ($parsed_history as $h) {
427 if (isset($h['role']) && isset($h['content'])) {
428 $role = ($h['role'] === 'assistant') ? 'model' : 'user';
429 $formatted_messages[] = [
430 'role' => $role,
431 'parts' => [
432 ['text' => sanitize_text_field($h['content'])]
433 ]
434 ];
435 }
436 }
437 }
438 }
439
440 $last_msg = end($formatted_messages);
441 if (!$last_msg || $last_msg['role'] !== 'user' || empty($last_msg['parts'][0]['text']) || $last_msg['parts'][0]['text'] !== $keyword) {
442 $formatted_messages[] = [
443 'role' => 'user',
444 'parts' => [
445 ['text' => $keyword]
446 ]
447 ];
448 }
449
450 $data = array(
451 'contents' => $formatted_messages,
452 );
453
454 $args = array(
455 'body' => json_encode($data),
456 'headers' => array(
457 'Content-Type' => 'application/json',
458 'X-goog-api-key' => $gemini_api_key,
459 ),
460 'timeout' => 60,
461 'redirection' => 5,
462 'blocking' => true,
463 'httpversion' => '1.0',
464 'sslverify' => true,
465 );
466
467 $result = wp_remote_post($api_url, $args);
468
469 if (is_wp_error($result)) {
470 $response['status'] = 'error';
471 $response['message'] = 'API request failed: ' . $result->get_error_message();
472 } else {
473 $http_code = wp_remote_retrieve_response_code($result);
474 $response_body = wp_remote_retrieve_body($result);
475
476 if ($http_code === 200) {
477 $msg = json_decode($response_body);
478 if (
479 isset($msg->candidates[0]->content->parts[0]->text)
480 && !empty($msg->candidates[0]->content->parts[0]->text)
481 ) {
482 $response['status'] = 'success';
483 $reply_text = $Qcld_Parsedown->text( $msg->candidates[0]->content->parts[0]->text );
484 if (strpos($reply_text, 'AI_FORM_DATA') !== false) {
485 $reply_text = Qcld_WPBot_Common_Functions::format_and_save_ai_form_response($reply_text);
486 $response['message'] = $reply_text;
487 } else {
488 $response['message'] = $reply_text . $relevant_pagelinks;
489 }
490 } else {
491 $response['status'] = 'error';
492 $response['message'] = 'Invalid response format from Gemini API';
493 }
494 } else {
495 $response['status'] = 'error';
496 $response['message'] = 'API request failed with HTTP code: ' . $http_code;
497 }
498 }
499 do_action('qcld_openai_user_rate_cal', 1);
500 //echo wp_send_json( $response );
501 wp_send_json( $response );
502 }
503
504 public function qcld_gemini_get_model_list_callback() {
505 $nonce = sanitize_text_field(wp_unslash($_POST['nonce']));
506 if ( ! wp_verify_nonce( $nonce, 'wp_chatbot' ) ) {
507 wp_send_json_error( array( 'msg' => esc_html__( 'Failed in Security check', 'chatbot') ) );
508 }
509
510 $api_key = sanitize_text_field(wp_unslash($_POST['api_key']));
511 if ( empty( $api_key ) ) {
512 wp_send_json_error( array( 'msg' => esc_html__( 'API Key is required', 'chatbot') ) );
513 }
514
515 $url = "https://generativelanguage.googleapis.com/v1beta/models?key=" . $api_key;
516 $response_raw = wp_remote_get( $url, array( 'timeout' => 30 ) );
517 if ( is_wp_error( $response_raw ) ) {
518 $http_code = 500;
519 $response = wp_json_encode( array( 'error' => array( 'message' => $response_raw->get_error_message() ) ) );
520 } else {
521 $http_code = wp_remote_retrieve_response_code( $response_raw );
522 $response = wp_remote_retrieve_body( $response_raw );
523 }
524
525 if ( $http_code !== 200 ) {
526 $error_data = json_decode( $response, true );
527 $error_msg = isset( $error_data['error']['message'] ) ? $error_data['error']['message'] : 'Failed to fetch models';
528 wp_send_json_error( array( 'msg' => $error_msg ) );
529 }
530
531 $data = json_decode( $response, true );
532 $models = array();
533 if ( isset( $data['models'] ) ) {
534 foreach ( $data['models'] as $model ) {
535 if ( in_array( 'generateContent', $model['supportedGenerationMethods'] ) ) {
536 // Clean model name (models/gemini-pro -> gemini-pro)
537 $name = str_replace( 'models/', '', $model['name'] );
538 $models[] = array(
539 'id' => $name,
540 'name' => $model['displayName']
541 );
542 }
543 }
544 }
545
546 wp_send_json_success( array( 'models' => $models ) );
547 }
548 public function qcld_update_settings_option_callback(){
549 // Verify nonce for CSRF protection
550 $nonce = isset($_POST['nonce']) ? sanitize_text_field(wp_unslash($_POST['nonce'])) : '';
551 if (!wp_verify_nonce($nonce, 'wp_chatbot')) {
552 wp_send_json_error(array('message' => esc_html__('Security check failed', 'chatbot')));
553 wp_die();
554 }
555
556 // Check user capability - only administrators can modify settings
557 if (!current_user_can('manage_options')) {
558 wp_send_json_error(array('message' => esc_html__('Unauthorized access', 'chatbot')));
559 wp_die();
560 }
561
562 // Proceed with option updates
563 update_option('disable_wp_chatbot_site_search', 1);
564 update_option('enable_wp_chatbot_post_content', '');
565
566 // Send success response
567 wp_send_json_success(array('message' => esc_html__('Settings updated successfully', 'chatbot')));
568 wp_die();
569 }
570 }
571
572 /**
573 * @return qcld_wpopenai_addon
574 */
575 if(!function_exists('qcld_wpgemini_addons')){
576 function qcld_wpgemini_addons() {
577 $qcld_wpgemini_addon = new qcld_wpgemini_addons();
578 return $qcld_wpgemini_addon->instance();
579
580 }
581 }
582
583 //fire off the plugin
584 qcld_wpgemini_addons();
585
586 }