PluginProbe
WPBot – AI ChatBot for Live Support, Lead Generation, WordPress Automation, AI Services / 8.7.4
WPBot – AI ChatBot for Live Support, Lead Generation, WordPress Automation, AI Services v8.7.4
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 8.5.5 8.5.4 8.5.3 All 534 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.7.4, at includes/integration/gemini/qcld-bot-gemini.php

585 lines 25.0 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, respond with 'Invalid answer found' and ask the exact same question again.";
267 }
268 }
269
270 if ( !$is_playground && get_option('gemeni_context_awareness_enabled') == '1' ) {
271 $site_name = get_bloginfo('name');
272 $site_desc = get_bloginfo('description');
273
274 // Get current page URL and title more reliably
275 $current_url = '';
276 $page_title = '';
277 $page_summary = '';
278
279 // Try to get from referrer first
280 $ref = wp_get_referer();
281 if ( ! $ref && isset($_SERVER['HTTP_REFERER']) ) {
282 $ref = esc_url_raw( $_SERVER['HTTP_REFERER'] );
283 }
284
285 if ( $ref ) {
286 $current_url = $ref;
287
288 // Try to get post/page by URL, fallback to query param if needed.
289 $post_id = url_to_postid( $ref );
290 if ( ! $post_id && isset( $_GET['p'] ) ) {
291 $post_id = intval( wp_unslash($_GET['p']) );
292 }
293 if ( $post_id ) {
294 $page_title = get_the_title( $post_id );
295 $raw_content = get_post_field( 'post_content', $post_id );
296 $text_content = wp_strip_all_tags( $raw_content );
297 $page_summary = wp_trim_words( $text_content, 120, '' );
298 } else {
299 // If not a post/page, try to extract title from URL or use current page
300 $parsed_url = wp_parse_url( $ref );
301 if ( isset($parsed_url['path']) ) {
302 $path = trim($parsed_url['path'], '/');
303 if ( ! empty($path) ) {
304 // Try to get title from current page if we're on it
305 if ( is_singular() ) {
306 $page_title = get_the_title();
307 $raw_content = get_the_content();
308 $text_content = wp_strip_all_tags( $raw_content );
309 $page_summary = wp_trim_words( $text_content, 120, '' );
310 } elseif ( is_archive() ) {
311 $page_title = get_the_archive_title();
312 } elseif ( is_search() ) {
313 $page_title = 'Search Results';
314 } elseif ( is_404() ) {
315 $page_title = 'Page Not Found';
316 }
317 }
318 }
319 }
320 } else {
321 // Fallback to current page info.
322 $scheme = (isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] === 'on' ? "https" : "http");
323
324 // Sanitize HTTP_HOST and REQUEST_URI from $_SERVER.
325 $sanitized_host = isset($_SERVER['HTTP_HOST']) ? sanitize_text_field($_SERVER['HTTP_HOST']) : '';
326 $sanitized_request_uri = isset($_SERVER['REQUEST_URI']) ? esc_url_raw($_SERVER['REQUEST_URI']) : '';
327
328 // Construct the URL with sanitized components.
329 $current_url_temp = $scheme . '://' . $sanitized_host . $sanitized_request_uri;
330
331 // Final sanitization of the entire URL string.
332 $current_url = esc_url_raw($current_url_temp);
333
334 if ( is_singular() ) {
335 $page_title = get_the_title();
336 $raw_content = get_the_content();
337 $text_content = wp_strip_all_tags( $raw_content );
338 $page_summary = wp_trim_words( $text_content, 120, '' );
339 } elseif ( is_archive() ) {
340 $page_title = get_the_archive_title();
341 } elseif ( is_search() ) {
342 $page_title = 'Search Results';
343 } elseif ( is_404() ) {
344 $page_title = 'Page Not Found';
345 }
346 }
347
348 $context_bits = array();
349 if ( $site_name ) { $context_bits[] = 'Site: ' . $site_name; }
350 if ( $site_desc ) { $context_bits[] = 'Tagline: ' . $site_desc; }
351 if ( $page_title ) { $context_bits[] = 'Page title: ' . $page_title; }
352 if ( $current_url ) { $context_bits[] = 'URL: ' . $current_url; }
353 if ( $page_summary ) { $context_bits[] = 'Page summary: ' . $page_summary; }
354
355 if ( ! empty( $context_bits ) ) {
356 if (!empty($system_instructions)) {
357 $system_instructions .= "\n\nContext Information: " . implode( '. ', $context_bits ) . '. Please use this context to provide more relevant and accurate responses.';
358 } else {
359 $system_instructions = 'Context Information: ' . implode( '. ', $context_bits ) . '. Please use this context to provide more relevant and accurate responses.';
360 }
361 }
362 }
363
364 $action_prompt = !empty($_POST['action_prompt']) ? wp_unslash($_POST['action_prompt']) : '';
365 if (!empty($action_prompt)) {
366 $system_instructions .= "\n\nCRITICAL ACTIVE ACTION INSTRUCTION:\n" . $action_prompt;
367 }
368
369 // RAG Integration
370 if (get_option('is_page_rag_enabled') == '1') {
371 $rag_context_text = Qcld_Bot_Rag::instance()->run_rag_search($keyword);
372 if (!empty($rag_context_text) && $rag_context_text != "No knowledge base found.") {
373 $rag_context = "Relevant Knowledge Base Information:\n";
374 $rag_context .= $rag_context_text;
375 $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.";
376
377 if (!empty($system_instructions)) {
378 $system_instructions .= "\n\n" . $rag_context;
379 } else {
380 $system_instructions = $rag_context;
381 }
382 }
383 }
384
385 if ( ( get_option( 'page_suggestion_enabled' ) == '1' ) && count( $relevant_pagelink ) > 0 ) {
386 $relevant_post_link = maybe_unserialize( get_option( 'qlcd_wp_chatbot_relevant_post_link_openai' ) );
387 $locale = get_locale();
388 if ( !$is_playground && is_array( $relevant_post_link ) && isset( $relevant_post_link[ $locale ] ) && is_array( $relevant_post_link[ $locale ] ) ) {
389 $relevant_pagelinks = '<br><br><p><em>' . implode( '', $relevant_post_link[ $locale ] ) . '</em><p>' . implode( '</br>', $relevant_pagelink );
390 } else {
391 $em_text = '';
392 if ( !$is_playground && is_array( $relevant_post_link ) && isset( $relevant_post_link[ $locale ] ) ) {
393 $em_text = is_array( $relevant_post_link[ $locale ] ) ? implode( '', $relevant_post_link[ $locale ] ) : $relevant_post_link[ $locale ];
394 }
395 $relevant_pagelinks = '<br><br><p><em>' . $em_text . '</em><p>' . implode( '</br>', $relevant_pagelink );
396 }
397 } else {
398 $relevant_pagelinks = '';
399 }
400
401 $selected_model = get_option('qcld_gemini_model') ? get_option('qcld_gemini_model') : 'gemini-2.5-flash';
402 $api_url = 'https://generativelanguage.googleapis.com/v1/models/' . $selected_model . ':generateContent';
403
404 $formatted_messages = [];
405
406 if ( ! empty( $system_instructions ) ) {
407 $formatted_messages[] = [
408 'role' => 'user',
409 'parts' => [
410 ['text' => "[System Instructions] " . $system_instructions]
411 ]
412 ];
413
414 $formatted_messages[] = [
415 'role' => 'model',
416 'parts' => [
417 ['text' => "I understand and will follow these instructions."]
418 ]
419 ];
420 }
421
422 if (!empty($_POST['ai_history'])) {
423 $parsed_history = json_decode(wp_unslash($_POST['ai_history']), true);
424 if (is_array($parsed_history)) {
425 foreach ($parsed_history as $h) {
426 if (isset($h['role']) && isset($h['content'])) {
427 $role = ($h['role'] === 'assistant') ? 'model' : 'user';
428 $formatted_messages[] = [
429 'role' => $role,
430 'parts' => [
431 ['text' => sanitize_text_field($h['content'])]
432 ]
433 ];
434 }
435 }
436 }
437 }
438
439 $last_msg = end($formatted_messages);
440 if (!$last_msg || $last_msg['role'] !== 'user' || empty($last_msg['parts'][0]['text']) || $last_msg['parts'][0]['text'] !== $keyword) {
441 $formatted_messages[] = [
442 'role' => 'user',
443 'parts' => [
444 ['text' => $keyword]
445 ]
446 ];
447 }
448
449 $data = array(
450 'contents' => $formatted_messages,
451 );
452
453 $args = array(
454 'body' => json_encode($data),
455 'headers' => array(
456 'Content-Type' => 'application/json',
457 'X-goog-api-key' => $gemini_api_key,
458 ),
459 'timeout' => 60,
460 'redirection' => 5,
461 'blocking' => true,
462 'httpversion' => '1.0',
463 'sslverify' => true,
464 );
465
466 $result = wp_remote_post($api_url, $args);
467
468 if (is_wp_error($result)) {
469 $response['status'] = 'error';
470 $response['message'] = 'API request failed: ' . $result->get_error_message();
471 } else {
472 $http_code = wp_remote_retrieve_response_code($result);
473 $response_body = wp_remote_retrieve_body($result);
474
475 if ($http_code === 200) {
476 $msg = json_decode($response_body);
477 if (
478 isset($msg->candidates[0]->content->parts[0]->text)
479 && !empty($msg->candidates[0]->content->parts[0]->text)
480 ) {
481 $response['status'] = 'success';
482 $reply_text = $Qcld_Parsedown->text( $msg->candidates[0]->content->parts[0]->text );
483 if (strpos($reply_text, 'AI_FORM_DATA') !== false) {
484 $reply_text = Qcld_WPBot_Common_Functions::format_and_save_ai_form_response($reply_text);
485 $response['message'] = $reply_text;
486 } else {
487 $response['message'] = $reply_text . $relevant_pagelinks;
488 }
489 } else {
490 $response['status'] = 'error';
491 $response['message'] = 'Invalid response format from Gemini API';
492 }
493 } else {
494 $response['status'] = 'error';
495 $response['message'] = 'API request failed with HTTP code: ' . $http_code;
496 }
497 }
498 do_action('qcld_openai_user_rate_cal', 1);
499 //echo wp_send_json( $response );
500 wp_send_json( $response );
501 }
502
503 public function qcld_gemini_get_model_list_callback() {
504 $nonce = sanitize_text_field(wp_unslash($_POST['nonce']));
505 if ( ! wp_verify_nonce( $nonce, 'wp_chatbot' ) ) {
506 wp_send_json_error( array( 'msg' => esc_html__( 'Failed in Security check', 'chatbot') ) );
507 }
508
509 $api_key = sanitize_text_field(wp_unslash($_POST['api_key']));
510 if ( empty( $api_key ) ) {
511 wp_send_json_error( array( 'msg' => esc_html__( 'API Key is required', 'chatbot') ) );
512 }
513
514 $url = "https://generativelanguage.googleapis.com/v1beta/models?key=" . $api_key;
515 $response_raw = wp_remote_get( $url, array( 'timeout' => 30 ) );
516 if ( is_wp_error( $response_raw ) ) {
517 $http_code = 500;
518 $response = wp_json_encode( array( 'error' => array( 'message' => $response_raw->get_error_message() ) ) );
519 } else {
520 $http_code = wp_remote_retrieve_response_code( $response_raw );
521 $response = wp_remote_retrieve_body( $response_raw );
522 }
523
524 if ( $http_code !== 200 ) {
525 $error_data = json_decode( $response, true );
526 $error_msg = isset( $error_data['error']['message'] ) ? $error_data['error']['message'] : 'Failed to fetch models';
527 wp_send_json_error( array( 'msg' => $error_msg ) );
528 }
529
530 $data = json_decode( $response, true );
531 $models = array();
532 if ( isset( $data['models'] ) ) {
533 foreach ( $data['models'] as $model ) {
534 if ( in_array( 'generateContent', $model['supportedGenerationMethods'] ) ) {
535 // Clean model name (models/gemini-pro -> gemini-pro)
536 $name = str_replace( 'models/', '', $model['name'] );
537 $models[] = array(
538 'id' => $name,
539 'name' => $model['displayName']
540 );
541 }
542 }
543 }
544
545 wp_send_json_success( array( 'models' => $models ) );
546 }
547 public function qcld_update_settings_option_callback(){
548 // Verify nonce for CSRF protection
549 $nonce = isset($_POST['nonce']) ? sanitize_text_field(wp_unslash($_POST['nonce'])) : '';
550 if (!wp_verify_nonce($nonce, 'wp_chatbot')) {
551 wp_send_json_error(array('message' => esc_html__('Security check failed', 'chatbot')));
552 wp_die();
553 }
554
555 // Check user capability - only administrators can modify settings
556 if (!current_user_can('manage_options')) {
557 wp_send_json_error(array('message' => esc_html__('Unauthorized access', 'chatbot')));
558 wp_die();
559 }
560
561 // Proceed with option updates
562 update_option('disable_wp_chatbot_site_search', 1);
563 update_option('enable_wp_chatbot_post_content', '');
564
565 // Send success response
566 wp_send_json_success(array('message' => esc_html__('Settings updated successfully', 'chatbot')));
567 wp_die();
568 }
569 }
570
571 /**
572 * @return qcld_wpopenai_addon
573 */
574 if(!function_exists('qcld_wpgemini_addons')){
575 function qcld_wpgemini_addons() {
576 $qcld_wpgemini_addon = new qcld_wpgemini_addons();
577 return $qcld_wpgemini_addon->instance();
578
579 }
580 }
581
582 //fire off the plugin
583 qcld_wpgemini_addons();
584
585 }