PluginProbe
WPBot – AI ChatBot for Live Support, Lead Generation, WordPress Automation, AI Services / 7.5.6
WPBot – AI ChatBot for Live Support, Lead Generation, WordPress Automation, AI Services v7.5.6
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 7.5.6, at includes/integration/gemini/qcld-bot-gemini.php

396 lines 15.8 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_qcld_gemini_settings_option',[$this,'qcld_gemini_settings_option_callback']);
65
66 add_action('wp_ajax_update_settings_option', [$this, 'qcld_update_settings_option_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($_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 } else {
118 $gemini_api_key = sanitize_text_field($_POST['gemini_api_key']);
119 $gemini_enabled = sanitize_text_field($_POST['gemini_enabled']);
120 $qcld_gemini_page_suggestion_enabled = sanitize_text_field($_POST['qcld_gemini_page_suggestion_enabled']);
121 $gemini_is_context_awareness_enabled = sanitize_text_field($_POST['gemini_is_context_awareness_enabled']);
122 $qcld_gemini_append_content = sanitize_text_field($_POST['qcld_gemini_append_content']) ?? '';
123 $qcld_gemini_prepend_content = sanitize_text_field($_POST['qcld_gemini_prepend_content']) ?? '';
124 if($gemini_api_key != '') {
125 update_option('qcld_gemini_api_key', $gemini_api_key);
126 }
127 if($gemini_enabled != '') {
128 update_option('qcld_gemini_enabled', $gemini_enabled);
129 }
130 if($gemini_enabled == '1') {
131 update_option('ai_enabled', 0);
132 update_option('qcld_openrouter_enabled', 0);
133
134 } else {
135 update_option('ai_enabled', 1);
136 }
137 update_option('qcld_gemini_page_suggestion_enabled', $qcld_gemini_page_suggestion_enabled);
138 update_option('gemeni_context_awareness_enabled', $gemini_is_context_awareness_enabled);
139 $openai_post_types = array();
140 if (isset($_POST['openai_post_type'])) {
141 $raw_post_types = wp_unslash($_POST['openai_post_type']);
142 if (is_array($raw_post_types)) {
143 $openai_post_types = array_map('sanitize_text_field', $raw_post_types);
144 } else {
145 $openai_post_types = sanitize_text_field($raw_post_types);
146 }
147 }
148 update_option('qcld_openai_relevant_post', $openai_post_types);
149
150 update_option('qcld_gemini_append_content', $qcld_gemini_append_content);
151 update_option('qcld_gemini_prepend_content', $qcld_gemini_prepend_content);
152
153 }
154 echo wp_json_encode($gemini_enabled);
155 wp_die();
156 }
157 public function qcld_gemini_response_callback() {
158
159 $gemini_api_key = get_option( 'qcld_gemini_api_key' );
160 $keyword = isset($_POST['keyword']) ? $_POST['keyword'] : ''; // phpcs:ignore WordPress.Security.NonceVerification.Missing
161
162 $relevant_pagelink = Qcld_WPBot_Common_Functions::qcpd_relevant_pagelink( $keyword );
163 $relevant_pagelink = array_slice( $relevant_pagelink, 0, 5, true );
164
165 if ( ( get_option( 'page_suggestion_enabled' ) == '1' ) && count( $relevant_pagelink ) > 0 ) {
166 $relevant_post_link = maybe_unserialize( get_option( 'qlcd_wp_chatbot_relevant_post_link_openai' ) );
167 // Always use get_locale() to avoid undefined function error
168 $locale = get_locale();
169 if ( is_array( $relevant_post_link ) && isset( $relevant_post_link[ $locale ] ) && is_array( $relevant_post_link[ $locale ] ) ) {
170 $relevant_pagelinks = '<br><br><p><em>' . implode( '', $relevant_post_link[ $locale ] ) . '</em><p>' . implode( '</br>', $relevant_pagelink );
171 } else {
172 // Fallback: try to use $locale, but check if key exists
173 $em_text = '';
174 if ( is_array( $relevant_post_link ) && isset( $relevant_post_link[ $locale ] ) ) {
175 $em_text = is_array( $relevant_post_link[ $locale ] ) ? implode( '', $relevant_post_link[ $locale ] ) : $relevant_post_link[ $locale ];
176 }
177 $relevant_pagelinks = '<br><br><p><em>' . $em_text . '</em><p>' . implode( '</br>', $relevant_pagelink );
178 }
179 } else {
180 $relevant_pagelinks = '';
181 }
182
183 $Qcld_Parsedown = new Qcld_Parsedown();
184
185 // Build context-aware content with system instructions
186 $system_instructions = '';
187 if ( get_option('gemeni_context_awareness_enabled') == '1' ) {
188 $site_name = get_bloginfo('name');
189 $site_desc = get_bloginfo('description');
190
191 // Get current page URL and title more reliably
192 $current_url = '';
193 $page_title = '';
194 $page_summary = '';
195
196 // Try to get from referrer first
197 $ref = wp_get_referer();
198 if ( ! $ref && isset($_SERVER['HTTP_REFERER']) ) {
199 $ref = esc_url_raw( $_SERVER['HTTP_REFERER'] );
200 }
201
202 if ( $ref ) {
203 $current_url = $ref;
204
205 // Try to get post/page by URL, fallback to query param if needed.
206 $post_id = url_to_postid( $ref );
207 if ( ! $post_id && isset( $_GET['p'] ) ) {
208 $post_id = intval( $_GET['p'] );
209 }
210 if ( $post_id ) {
211 $page_title = get_the_title( $post_id );
212 $raw_content = get_post_field( 'post_content', $post_id );
213 $text_content = wp_strip_all_tags( $raw_content );
214 $page_summary = wp_trim_words( $text_content, 120, '' );
215 } else {
216 // If not a post/page, try to extract title from URL or use current page
217 $parsed_url = parse_url( $ref );
218 if ( isset($parsed_url['path']) ) {
219 $path = trim($parsed_url['path'], '/');
220 if ( ! empty($path) ) {
221 // Try to get title from current page if we're on it
222 if ( is_singular() ) {
223 $page_title = get_the_title();
224 $raw_content = get_the_content();
225 $text_content = wp_strip_all_tags( $raw_content );
226 $page_summary = wp_trim_words( $text_content, 120, '' );
227 } elseif ( is_archive() ) {
228 $page_title = get_the_archive_title();
229 } elseif ( is_search() ) {
230 $page_title = 'Search Results';
231 } elseif ( is_404() ) {
232 $page_title = 'Page Not Found';
233 }
234 }
235 }
236 }
237 } else {
238 // Fallback to current page info.
239 $scheme = (isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] === 'on' ? "https" : "http");
240
241 // Sanitize HTTP_HOST and REQUEST_URI from $_SERVER.
242 $sanitized_host = isset($_SERVER['HTTP_HOST']) ? sanitize_text_field($_SERVER['HTTP_HOST']) : '';
243 $sanitized_request_uri = isset($_SERVER['REQUEST_URI']) ? esc_url_raw($_SERVER['REQUEST_URI']) : '';
244
245 // Construct the URL with sanitized components.
246 $current_url_temp = $scheme . '://' . $sanitized_host . $sanitized_request_uri;
247
248 // Final sanitization of the entire URL string.
249 $current_url = esc_url_raw($current_url_temp);
250
251 if ( is_singular() ) {
252 $page_title = get_the_title();
253 $raw_content = get_the_content();
254 $text_content = wp_strip_all_tags( $raw_content );
255 $page_summary = wp_trim_words( $text_content, 120, '' );
256 } elseif ( is_archive() ) {
257 $page_title = get_the_archive_title();
258 } elseif ( is_search() ) {
259 $page_title = 'Search Results';
260 } elseif ( is_404() ) {
261 $page_title = 'Page Not Found';
262 }
263 }
264
265 $context_bits = array();
266 if ( $site_name ) { $context_bits[] = 'Site: ' . $site_name; }
267 if ( $site_desc ) { $context_bits[] = 'Tagline: ' . $site_desc; }
268 if ( $page_title ) { $context_bits[] = 'Page title: ' . $page_title; }
269 if ( $current_url ) { $context_bits[] = 'URL: ' . $current_url; }
270 if ( $page_summary ) { $context_bits[] = 'Page summary: ' . $page_summary; }
271
272 if ( ! empty( $context_bits ) ) {
273 $system_instructions = 'Context Information: ' . implode( '. ', $context_bits ) . '. Please use this context to provide more relevant and accurate responses.';
274 }
275 }
276
277 if ( ( get_option( 'page_suggestion_enabled' ) == '1' ) && count( $relevant_pagelink ) > 0 ) {
278 $relevant_post_link = maybe_unserialize( get_option( 'qlcd_wp_chatbot_relevant_post_link_openai' ) );
279 // Always use get_locale() to avoid undefined function error
280 $locale = get_locale();
281 if ( is_array( $relevant_post_link ) && isset( $relevant_post_link[ $locale ] ) && is_array( $relevant_post_link[ $locale ] ) ) {
282 $relevant_pagelinks = '<br><br><p><em>' . implode( '', $relevant_post_link[ $locale ] ) . '</em><p>' . implode( '</br>', $relevant_pagelink );
283 } else {
284 // Fallback: try to use $locale, but check if key exists
285 $em_text = '';
286 if ( is_array( $relevant_post_link ) && isset( $relevant_post_link[ $locale ] ) ) {
287 $em_text = is_array( $relevant_post_link[ $locale ] ) ? implode( '', $relevant_post_link[ $locale ] ) : $relevant_post_link[ $locale ];
288 }
289 $relevant_pagelinks = '<br><br><p><em>' . $em_text . '</em><p>' . implode( '</br>', $relevant_pagelink );
290 }
291 } else {
292 $relevant_pagelinks = '';
293 }
294
295 // Gemini API expects a different payload and endpoint
296 $api_url = 'https://generativelanguage.googleapis.com/v1beta/models/gemini-2.0-flash' . ':generateContent';
297
298 // Build formatted messages with system instructions
299 $formatted_messages = [];
300
301 // Add system instructions as first user message if context is enabled
302 if ( ! empty( $system_instructions ) ) {
303 $formatted_messages[] = [
304 'role' => 'user',
305 'parts' => [
306 ['text' => "[System Instructions] " . $system_instructions]
307 ]
308 ];
309
310 // Add model response to acknowledge system instructions
311 $formatted_messages[] = [
312 'role' => 'model',
313 'parts' => [
314 ['text' => "I understand and will follow these instructions."]
315 ]
316 ];
317 }
318
319 // Add the actual user query
320 $formatted_messages[] = [
321 'role' => 'user',
322 'parts' => [
323 ['text' => $keyword]
324 ]
325 ];
326
327 $data = array(
328 'contents' => $formatted_messages,
329 );
330
331 // Use WordPress wp_remote_post for better error handling and consistency
332 $args = array(
333 'body' => json_encode($data),
334 'headers' => array(
335 'Content-Type' => 'application/json',
336 'X-goog-api-key' => $gemini_api_key,
337 ),
338 'timeout' => 60,
339 'redirection' => 5,
340 'blocking' => true,
341 'httpversion' => '1.0',
342 'sslverify' => true,
343 );
344
345 $result = wp_remote_post($api_url, $args);
346
347 // Check for WordPress errors
348 if (is_wp_error($result)) {
349 $response['status'] = 'error';
350 $response['message'] = 'API request failed: ' . $result->get_error_message();
351 } else {
352 $http_code = wp_remote_retrieve_response_code($result);
353 $response_body = wp_remote_retrieve_body($result);
354
355 if ($http_code === 200) {
356 $msg = json_decode($response_body);
357 // Gemini API returns candidates[0]->content->parts[0]->text
358 if (
359 isset($msg->candidates[0]->content->parts[0]->text)
360 && !empty($msg->candidates[0]->content->parts[0]->text)
361 ) {
362 $response['status'] = 'success';
363 $response['message'] = $Qcld_Parsedown->text( $msg->candidates[0]->content->parts[0]->text ) . $relevant_pagelinks;
364 } else {
365 $response['status'] = 'error';
366 $response['message'] = 'Invalid response format from Gemini API';
367 }
368 } else {
369 $response['status'] = 'error';
370 $response['message'] = 'API request failed with HTTP code: ' . $http_code;
371 }
372 }
373 wp_send_json( $response );
374 wp_die();
375 }
376 public function qcld_update_settings_option_callback(){
377 update_option('disable_wp_chatbot_site_search',1);
378 update_option('enable_wp_chatbot_post_content', '');
379 }
380 }
381
382 /**
383 * @return qcld_wpopenai_addon
384 */
385 if(!function_exists('qcld_wpgemini_addons')){
386 function qcld_wpgemini_addons() {
387 $qcld_wpgemini_addon = new qcld_wpgemini_addons();
388 return $qcld_wpgemini_addon->instance();
389
390 }
391 }
392
393 //fire off the plugin
394 qcld_wpgemini_addons();
395
396 }