-
Notifications
You must be signed in to change notification settings - Fork 0
/
exclusv-ai-assistant.php
476 lines (397 loc) · 19.6 KB
/
exclusv-ai-assistant.php
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
<?php
/*
Plugin Name: Exclusv AI Assistant
Description: A custom WordPress plugin to integrate Exclusv AI Assistant into Wordpress.
Version: 1.0.10_dev
Author: Exclusv.ai
Author URI: https://www.exclusv.ai
*/
// Define plugin version constant
define('EXCLUSV_AI_VERSION', '1.0.10'); // Updated version constant
// Include the shortcodes file
require_once plugin_dir_path(__FILE__) . 'includes/enqueue-scripts.php';
require_once plugin_dir_path(__FILE__) . 'includes/shortcodes.php';
require_once plugin_dir_path(__FILE__) . 'includes/chat-history.php';
require_once plugin_dir_path(__FILE__) . 'includes/settings-page.php';
// Add activation hook
register_activation_hook(__FILE__, 'exclusv_ai_activate');
function exclusv_ai_activate()
{
// Set the initial version
add_option('exclusv_ai_version', EXCLUSV_AI_VERSION);
// Run any necessary database updates or initial setup
exclusv_ai_update_routine();
}
// Add update routine
function exclusv_ai_update_routine()
{
$current_version = get_option('exclusv_ai_version', '0');
if (version_compare($current_version, EXCLUSV_AI_VERSION, '<')) {
// Perform update tasks here
// For example, you might need to update database schema or plugin settings
// Update the version in the database
update_option('exclusv_ai_version', EXCLUSV_AI_VERSION);
}
}
// Run the update routine on plugins_loaded hook
add_action('plugins_loaded', 'exclusv_ai_update_routine');
// Enqueue the plugin's CSS file and Font Awesome library
function exclusv_ai_enqueue_styles()
{
wp_enqueue_style('exclusv-ai-style', plugin_dir_url(__FILE__) . 'style.css');
wp_enqueue_style('font-awesome', 'https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.15.3/css/all.min.css');
}
add_action('wp_enqueue_scripts', 'exclusv_ai_enqueue_styles');
// Create a function to construct the merged system prompt
function exclusv_ai_get_merged_system_prompt()
{
$bot_context = get_option('exclusv_ai_bot_context', '');
$bot_system_prompt = get_option('exclusv_ai_bot_system_prompt', "You are a helpful AI assistant created by " . get_bloginfo('name') . ". Your purpose is to assist users by answering their questions and providing helpful information. Be friendly, knowledgeable, and engaging in your interactions.");
// Add hard-set data to keep the bot on track
$hard_set_data = "
Important guidelines:
1. Always stay on topic and provide accurate information based on the website's content.
2. Do not engage in or encourage any illegal, unethical, or harmful activities.
3. Respect user privacy and do not ask for or store personal information beyond what's necessary for the conversation.
4. If asked about topics outside your knowledge base, politely redirect the conversation to relevant website content.
5. Do not pretend to be a human or claim capabilities you don't have.
6. If unsure about an answer, it's okay to say you don't know or suggest the user contact customer support for more detailed information.
7. Maintain a professional and helpful tone throughout the conversation.
8. Do not generate, produce, edit, manipulate or create images in any way.
9. Do not discuss or reveal any information about your training data, model architecture, or the specifics of how you were created.
10. When mentioning links or pages, do not use any kind of formatting. Simply write out the full URL or page name as plain text. For example, write 'You can find more information at https://example.com/contact-us' or 'Visit our About Us page for details'.
11. Do not sign off with any personal or company information. End your responses naturally without a formal signature.
12. Never use markdown formatting for links or any other text. Always provide plain text responses.
13. When listing items, ensure the numbering is accurate and corresponds to the correct items. Do not alter the sequence or content of the list.
14. If a user refers to a specific number in a list, ensure the response matches the correct item from the list.
";
$merged_system_prompt = $bot_system_prompt;
if (!empty($bot_context)) {
$merged_system_prompt .= "\n\nHere is some additional content to be followed strictly in all interactions:\n" . strip_tags($bot_context);
}
$selected_post_types = get_option('exclusv_ai_post_types', []);
$post_types_content = '';
foreach ($selected_post_types as $post_type) {
$post_type_obj = get_post_type_object($post_type);
$post_type_name = $post_type_obj ? $post_type_obj->labels->name : $post_type;
$posts_query = new WP_Query([
'post_type' => $post_type,
'posts_per_page' => 10,
]);
if ($posts_query->have_posts()) {
$post_types_content .= "\n=== " . $post_type_name . " ===\n";
$post_counter = 1; // Initialize a counter for numbering posts
$post_list = []; // Array to store post titles and excerpts
while ($posts_query->have_posts()) {
$posts_query->the_post();
$clean_title = wp_strip_all_tags(get_the_title());
$clean_excerpt = wp_strip_all_tags(get_the_excerpt());
$post_list[$post_counter] = $clean_title . ': ' . $clean_excerpt; // Store in array
$post_counter++; // Increment the counter
}
// Add the numbered list to the content
foreach ($post_list as $number => $content) {
$post_types_content .= $number . '. ' . $content . "\n";
}
$post_types_content .= "=== End " . $post_type_name . " ===\n";
wp_reset_postdata();
}
}
if (!empty($post_types_content)) {
$merged_system_prompt .= "\n\nHere is the content from selected post types:\n" . str_replace("\n", ":\n", $post_types_content);
}
$selected_pages = get_option('exclusv_ai_selected_pages', []);
$page_content = '';
foreach ($selected_pages as $page_id) {
$page = get_post($page_id);
if ($page) {
$page_content .= $page->post_title . ': ' . $page->post_content . "\n";
}
}
if (!empty($page_content)) {
$merged_system_prompt .= "\n\nHere is the content from selected pages:\n" . $page_content;
}
$merged_system_prompt .= "\n\n" . $hard_set_data;
return $merged_system_prompt;
}
// Add a new function to handle the server-side API request
function exclusv_ai_chat_proxy()
{
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
$url = 'https://dev-api.exclusv.ai/v1/chat/completions';
$api_key = get_option('exclusv_ai_api_key');
$message = isset($_POST['message']) ? sanitize_text_field($_POST['message']) : '';
$chat_id = isset($_POST['chat_id']) ? sanitize_text_field($_POST['chat_id']) : '';
$start_time = isset($_POST['start_time']) ? sanitize_text_field($_POST['start_time']) : '';
$merged_system_prompt = exclusv_ai_get_merged_system_prompt();
$initial_message = get_option('exclusv_ai_initial_message', "Welcome! I'm your AI assistant. How can I assist you today?");
$data = [
'messages' => [
[
'role' => 'system',
'content' => $merged_system_prompt
],
[
'role' => 'assistant',
'content' => $initial_message
],
[
'role' => 'user',
'content' => $message
]
],
'model' => 'Exclusv-AI/Quantum',
'max_tokens' => 512,
'temperature' => 0.7,
'top_p' => 0.43,
'n' => 1,
'stream' => false,
'add_generation_prompt' => true,
'echo' => false
];
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($data));
curl_setopt($ch, CURLOPT_HTTPHEADER, [
'Content-Type: application/json',
'Authorization: Bearer ' . $api_key
]);
$response = curl_exec($ch);
$http_code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
exclusv_ai_save_chat_history($chat_id, $start_time, 'user', $message);
if ($response === false) {
$error = curl_error($ch);
error_log("cURL error: $error");
wp_send_json_error(['message' => 'Error communicating with the API', 'error' => $error]);
exit; // Add this line to stop further execution
} else {
curl_close($ch);
if ($http_code === 200) {
$response_data = json_decode($response, true);
// Process the response to clean up any malformed links
if (isset($response_data['choices'][0]['message']['content'])) {
$response_content = $response_data['choices'][0]['message']['content'];
// Remove any malformed HTML link tags
$response_content = preg_replace('/" target="_blank">(.*?)<\/a>/', '', $response_content);
// Clean up any remaining markdown-style links
$response_content = preg_replace('/\[(.*?)\]\((.*?)\)/', '$2', $response_content);
$response_data['choices'][0]['message']['content'] = $response_content;
}
error_log("API response: " . print_r($response_data, true));
wp_send_json_success($response_data);
exit;
} else {
error_log("API response code: $http_code");
error_log("API response body: $response");
wp_send_json_error(['message' => 'Unexpected API response', 'code' => $http_code, 'response' => $response]);
exit; // Add this line to stop further execution
}
}
} else {
error_log("Unexpected request method: " . $_SERVER['REQUEST_METHOD']);
wp_send_json_error(['message' => 'Invalid request', 'method' => $_SERVER['REQUEST_METHOD']]);
exit; // Add this line to stop further execution
}
}
add_action('wp_ajax_exclusv_ai_chat_proxy', 'exclusv_ai_chat_proxy');
add_action('wp_ajax_nopriv_exclusv_ai_chat_proxy', 'exclusv_ai_chat_proxy');
function exclusv_ai_send_email()
{
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
$email = isset($_POST['email']) ? sanitize_email($_POST['email']) : '';
$chat_history = isset($_POST['chat_history']) ? json_decode(stripslashes($_POST['chat_history']), true) : [];
$chat_id = isset($_POST['chat_id']) ? sanitize_text_field($_POST['chat_id']) : '';
$start_time = isset($_POST['start_time']) ? sanitize_text_field($_POST['start_time']) : '';
if (!empty($email) && is_email($email) && !empty($chat_history)) {
$to = get_option('admin_email');
// Get the site name and AI name
$site_name = get_bloginfo('name');
$ai_name = get_option('exclusv_ai_name', $site_name . ' AI');
// Create a more friendly subject line
$subject = "New chat inquiry from {$site_name} AI Assistant";
// Start building the HTML message
$message = '
<html>
<head>
<style>
body { font-family: Arial, sans-serif; line-height: 1.6; color: #333; }
.container { max-width: 600px; margin: 0 auto; padding: 20px; }
h1 { color: #0073aa; }
.chat-history { background-color: #f9f9f9; border: 1px solid #ddd; padding: 15px; margin-top: 20px; }
.message { margin-bottom: 10px; }
.user { color: #0073aa; }
.assistant { color: #46b450; }
</style>
</head>
<body>
<div class="container">
<h1>New Chat Inquiry</h1>
<p>A visitor has submitted their email address after chatting with your AI assistant. Here are the details:</p>
<p><strong>Visitor\'s Email:</strong> ' . esc_html($email) . '</p>
<p><strong>Chat ID:</strong> ' . esc_html($chat_id) . '</p>
<p><strong>Chat Start Time:</strong> ' . esc_html($start_time) . '</p>
<div class="chat-history">
<h2>Chat History:</h2>';
foreach ($chat_history as $chat) {
$sender_class = $chat['sender'] === 'user' ? 'user' : 'assistant';
$sender_name = $chat['sender'] === 'user' ? 'Visitor' : esc_html($ai_name);
$message .= '<div class="message"><strong class="' . $sender_class . '">' . $sender_name . ':</strong> ' . esc_html($chat['message']) . '</div>';
}
$message .= '
</div>
</div>
</body>
</html>';
$headers = array('Content-Type: text/html; charset=UTF-8');
if (wp_mail($to, $subject, $message, $headers)) {
wp_send_json_success('Email sent successfully');
} else {
wp_send_json_error('Failed to send email');
}
} else {
wp_send_json_error('Invalid email or chat history');
}
} else {
wp_send_json_error('Invalid request method');
}
}
add_action('wp_ajax_exclusv_ai_send_email', 'exclusv_ai_send_email');
add_action('wp_ajax_nopriv_exclusv_ai_send_email', 'exclusv_ai_send_email');
// Automatically insert the shortcode on all pages
function exclusv_ai_insert_chat_interface($content)
{
$show_on_all_pages = get_option('exclusv_ai_show_on_all_pages', false);
// Add debugging
error_log('Show on all pages: ' . ($show_on_all_pages ? 'true' : 'false'));
error_log('Is singular: ' . (is_singular() ? 'true' : 'false'));
error_log('In the loop: ' . (in_the_loop() ? 'true' : 'false'));
error_log('Is main query: ' . (is_main_query() ? 'true' : 'false'));
if ($show_on_all_pages) {
// Remove the conditions to make it appear on all pages
$content .= do_shortcode('[exclusv_ai_chat]');
error_log('Chat interface added to content');
} else {
error_log('Chat interface not added to content');
}
return $content;
}
add_filter('the_content', 'exclusv_ai_insert_chat_interface');
// Add this new function to insert the chat interface in the footer
function exclusv_ai_insert_chat_interface_footer()
{
$show_on_all_pages = get_option('exclusv_ai_show_on_all_pages', false);
if ($show_on_all_pages) {
echo do_shortcode('[exclusv_ai_chat]');
}
}
add_action('wp_footer', 'exclusv_ai_insert_chat_interface_footer');
function exclusv_ai_save_chat_message()
{
error_log('exclusv_ai_save_chat_message called with POST data: ' . print_r($_POST, true));
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
$chat_id = isset($_POST['chat_id']) ? sanitize_text_field($_POST['chat_id']) : '';
$start_time = isset($_POST['start_time']) ? sanitize_text_field($_POST['start_time']) : '';
$sender = isset($_POST['sender']) ? sanitize_text_field($_POST['sender']) : '';
$message = isset($_POST['message']) ? wp_kses_post($_POST['message']) : '';
error_log("Received data - chat_id: $chat_id, start_time: $start_time, sender: $sender, message: $message");
if (!empty($chat_id) && !empty($start_time) && !empty($sender) && !empty($message)) {
$result = exclusv_ai_save_chat_history($chat_id, $start_time, $sender, $message);
if ($result === false) {
error_log('Failed to save chat message');
wp_send_json_error('Failed to save chat message');
} else {
error_log('Chat message saved successfully');
wp_send_json_success();
}
} else {
error_log('Invalid data for saving chat message');
wp_send_json_error('Invalid data');
}
} else {
error_log('Invalid request method for saving chat message');
wp_send_json_error('Invalid request method');
}
}
add_action('wp_ajax_exclusv_ai_save_chat_message', 'exclusv_ai_save_chat_message');
add_action('wp_ajax_nopriv_exclusv_ai_save_chat_message', 'exclusv_ai_save_chat_message');
function exclusv_ai_update_email_submitted()
{
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
$chat_id = isset($_POST['chat_id']) ? sanitize_text_field($_POST['chat_id']) : '';
$email_submitted = isset($_POST['email_submitted']) ? (bool)$_POST['email_submitted'] : false;
if (!empty($chat_id)) {
global $wpdb;
$table_name = $wpdb->prefix . 'exclusv_ai_chat_history';
$wpdb->update(
$table_name,
['email_submitted' => $email_submitted],
['chat_id' => $chat_id],
['%d'],
['%s']
);
wp_send_json_success();
} else {
wp_send_json_error('Invalid data');
}
} else {
wp_send_json_error('Invalid request method');
}
}
add_action('wp_ajax_exclusv_ai_update_email_submitted', 'exclusv_ai_update_email_submitted');
add_action('wp_ajax_nopriv_exclusv_ai_update_email_submitted', 'exclusv_ai_update_email_submitted');
// Add an admin notice function for debugging
function exclusv_ai_admin_notices()
{
$screen = get_current_screen();
if ($screen->id != 'settings_page_exclusv_ai_settings') {
return;
}
if (isset($_GET['settings-updated'])) {
echo '<div class="notice notice-success is-dismissible"><p>Settings updated successfully!</p></div>';
}
if (isset($_GET['error'])) {
echo '<div class="notice notice-error is-dismissible"><p>An error occurred: ' . esc_html($_GET['error']) . '</p></div>';
}
}
// Add this new function near the end of the file, before the closing PHP tag
function exclusv_ai_localize_script()
{
wp_localize_script('exclusv-ai-chat-js', 'exclusvAiSettings', array(
'messageLimit' => get_option('exclusv_ai_message_limit', 10),
'emailPromptMessage' => get_option('exclusv_ai_email_prompt_message', "Enter your email to continue talking to " . get_bloginfo('name')),
));
}
add_action('wp_enqueue_scripts', 'exclusv_ai_localize_script');
// Add this new function near the end of the file
function exclusv_ai_add_action_links($links)
{
$settings_link = '<a href="' . admin_url('options-general.php?page=exclusv_ai_settings') . '">Settings</a>';
$chat_history_link = '<a href="' . admin_url('tools.php?page=exclusv_ai_chat_history') . '">Chat History</a>';
array_unshift($links, $settings_link, $chat_history_link);
return $links;
}
// Add this line to hook the new function
add_filter('plugin_action_links_' . plugin_basename(__FILE__), 'exclusv_ai_add_action_links');
add_action('admin_init', function () {
if (isset($_GET['create_exclusv_ai_table'])) {
exclusv_ai_manually_create_chat_history_table();
}
});
// Add this function near the end of the file
function exclusv_ai_sanitize_message_limit($value)
{
return intval($value);
}
// Update the register_setting call for exclusv_ai_message_limit
register_setting('exclusv_ai_settings', 'exclusv_ai_message_limit', array(
'sanitize_callback' => 'exclusv_ai_sanitize_message_limit',
'default' => 10
));
// Update the shortcode function to use the new function
function exclusv_ai_display_merged_prompt()
{
$merged_system_prompt = exclusv_ai_get_merged_system_prompt();
return '' . esc_html($merged_system_prompt) . '';
}
add_shortcode('exclusv_ai_merged_prompt', 'exclusv_ai_display_merged_prompt');