options = get_option('mxchat_options'); $this->chat_count = get_option('mxchat_chat_count', 0); $this->is_activated = $this->is_license_active(); // Initialize default options if they are not set if (!$this->options) { $this->initialize_default_options(); } // Add admin menu and initialize settings add_action('admin_menu', array($this, 'mxchat_add_plugin_page')); add_action('admin_init', array($this, 'mxchat_page_init')); add_action('admin_enqueue_scripts', array($this, 'mxchat_enqueue_admin_assets')); add_action('wp_ajax_mxchat_delete_chat_history', array($this, 'mxchat_delete_chat_history')); add_action('admin_post_mxchat_submit_content', array($this, 'mxchat_handle_content_submission')); add_action('admin_post_mxchat_delete_prompt', array($this, 'mxchat_handle_delete_prompt')); add_action('wp_ajax_mxchat_fetch_chat_history', array($this, 'mxchat_fetch_chat_history')); add_action('wp_ajax_nopriv_mxchat_fetch_chat_history', array($this, 'mxchat_fetch_chat_history')); add_action('admin_post_mxchat_submit_sitemap', array($this, 'mxchat_handle_sitemap_submission')); add_action('wp_footer', array($this, 'mxchat_append_chatbot_to_body')); add_action('admin_head-mxchat-prompts', array($this, 'mxchat_enqueue_admin_assets')); add_action('admin_head-toplevel_page_mxchat-max', array($this, 'mxchat_enqueue_admin_assets')); add_action('wp_ajax_mxchat_activate_license', array($this, 'mxchat_handle_activate_license')); add_action('admin_notices', array($this, 'mxchat_display_admin_notice')); // Add the AJAX handler for logged-in users add_action('wp_ajax_mxchat_save_inline_prompt', array($this, 'mxchat_save_inline_prompt')); add_action('admin_post_mxchat_delete_all_prompts', array($this, 'mxchat_handle_delete_all_prompts')); // Define admin_post actions for form submission handling add_action('admin_post_mxchat_add_intent', array($this, 'mxchat_handle_add_intent')); add_action('admin_post_mxchat_delete_intent', array($this, 'mxchat_handle_delete_intent')); add_action('admin_post_mxchat_update_intent_threshold', array($this, 'mxchat_handle_update_intent_threshold')); add_action('admin_post_mxchat_stop_processing', array($this, 'mxchat_stop_processing')); add_action('admin_post_mxchat_edit_intent', array($this, 'handle_edit_intent')); } // Method to check if the license is active private function is_license_active() { $license_status = get_option('mxchat_license_status', 'inactive'); return $license_status === 'active'; } // Initialize default options private function initialize_default_options() { $default_options = array( 'api_key' => '', 'xai_api_key' => '', 'claude_api_key' => '', 'system_prompt_instructions' => '[EXAMPLE INSTRUCTIONS] You are an AI Chatbot assistant for this website. The primary subject you should focus on is [insert proper subject here]. Your main goal is to assist visitors with questions related to this specific topic. Here are some key things to keep in mind: - Your name is [Chatbot Name]. - Stay focused on topics related to [insert proper subject here]. If a visitor asks about an unrelated topic, politely redirect the conversation to how you can assist them with this subject. - Do not make up links to pages. Only use specific links you see in your knowledgebase. - Keep your responses short, concise, and to the point. Provide clear and direct answers suitable for a chatbot interaction. - Provide answers based on the knowledge available to you. If you do not have an answer to a specific question, let the visitor know that you don’t have the information.', 'model' => 'gpt-4o', 'rate_limit_logged_in' => '100', 'rate_limit_logged_out' => '100', 'rate_limit_message' => 'Rate limit exceeded. Please try again later.', 'enable_email_block' => '', 'email_blocker_header_content' => "
Let's get started. Enter your email to begin chatting with us.
", 'email_blocker_button_text' => 'Start Chat', 'top_bar_title' => 'MxChat', 'intro_message' => 'Hello! How can I assist you today?', 'input_copy' => 'How can I assist?', 'append_to_body' => 'off', 'close_button_color' => '#fff', 'chatbot_bg_color' => '#fff', 'user_message_bg_color' => '#fff', 'user_message_font_color' => '#212121', 'bot_message_bg_color' => '#212121', 'bot_message_font_color' => '#fff', 'top_bar_bg_color' => '#212121', 'send_button_font_color' => '#212121', 'chat_input_font_color' => '#212121', 'chatbot_background_color' => '#212121', 'icon_color' => '#fff', 'enable_woocommerce_integration' => '0', 'link_target_toggle' => 'off', 'pre_chat_message' => 'Hey there! Ask me anything!', // New fields for Loops Integration 'loops_api_key' => '', 'loops_mailing_list' => '', 'triggered_phrase_response' => 'Would you like to join our mailing list? Please provide your email below.', 'email_capture_response' => 'Thank you for providing your email! You\'ve been added to our list.', 'popular_question_1' => '', 'popular_question_2' => '', 'popular_question_3' => '', 'pdf_intent_trigger_text' => "Please provide the URL to the PDF you'd like to discuss.", 'pdf_intent_success_text' => "I've processed the PDF. What questions do you have about it?", 'pdf_intent_error_text' => "Sorry, I couldn't process the PDF. Please ensure it's a valid file.", 'pdf_max_pages' => 69, // Live Agent Integration 'live_agent_webhook_url' => '', 'live_agent_secret_key' => '', 'live_agent_bot_token' => '', 'live_agent_message_bg_color' => '#ffffff', 'live_agent_message_font_color' => '#333333', 'chat_toolbar_toggle' => 'off', 'mode_indicator_bg_color' => '#767676', 'mode_indicator_font_color' => '#ffffff', 'toolbar_icon_color' => '#212121', ); // Merge existing options with defaults $existing_options = get_option('mxchat_options', array()); $merged_options = wp_parse_args($existing_options, $default_options); // Update the options if they have changed if ($existing_options !== $merged_options) { update_option('mxchat_options', $merged_options); } // Update the $this->options property $this->options = $merged_options; } public function mxchat_add_plugin_page() { // Main menu page add_menu_page( 'MxChat Settings', 'MxChat', 'manage_options', 'mxchat-max', array($this, 'mxchat_create_admin_page'), 'dashicons-testimonial', 6 ); // Submenu page for Knowledge add_submenu_page( 'mxchat-max', 'Prompts', 'Knowledge', 'manage_options', 'mxchat-prompts', array($this, 'mxchat_create_prompts_page') ); // Submenu page for Chat Transcripts add_submenu_page( 'mxchat-max', // Corrected parent slug to match the main menu 'Chat Transcripts', 'Transcripts', 'manage_options', 'mxchat-transcripts', array($this, 'mxchat_create_transcripts_page') // Prefixed function name with mxchat_ ); // Submenu page for Intents add_submenu_page( 'mxchat-max', // Parent slug 'MxChat Intents', // Page title 'Intents', // Menu title 'manage_options', // Capability 'mxchat-intents', // Menu slug array($this, 'mxchat_intents_page_html') // Callback function ); // Submenu page for Activation Key add_submenu_page( 'mxchat-max', 'Pro Upgrade', 'Pro Upgrade', 'manage_options', 'mxchat-activation', array($this, 'mxchat_create_activation_page') ); } public function mxchat_handle_content_submission() { // Check if the form was submitted and the user has sufficient permissions if (!isset($_POST['submit_content']) || !current_user_can('manage_options')) { return; } // Verify the nonce field for security $nonce = isset($_POST['mxchat_submit_content_nonce']) ? sanitize_text_field(wp_unslash($_POST['mxchat_submit_content_nonce'])) : ''; if (!wp_verify_nonce($nonce, 'mxchat_submit_content_action')) { wp_die('Nonce verification failed.'); } // Sanitize the content input $article_content = sanitize_textarea_field($_POST['article_content']); // Sanitize the URL input (optional URL) $article_url = isset($_POST['article_url']) ? esc_url_raw($_POST['article_url']) : ''; // Default to empty if not provided // Generate the embedding vector for the content $embedding_vector = $this->mxchat_generate_embedding($article_content); global $wpdb; $table_name = $wpdb->prefix . 'mxchat_system_prompt_content'; // Check if the 'source_url' column exists in the table and add it if it doesn't if ($wpdb->get_var($wpdb->prepare("SHOW COLUMNS FROM {$table_name} LIKE %s", 'source_url')) != 'source_url') { // Use wpdb::query and a prepared statement to avoid SQL injection $wpdb->query($wpdb->prepare("ALTER TABLE {$table_name} ADD source_url VARCHAR(255) DEFAULT ''")); } if (is_array($embedding_vector)) { // Serialize the embedding vector before storing it $embedding_vector_serialized = serialize($embedding_vector); // Insert the content, embedding vector, and source URL into the database, using a prepared statement $inserted = $wpdb->insert( $table_name, array( 'article_content' => $article_content, 'embedding_vector' => $embedding_vector_serialized, 'source_url' => $article_url, // Insert the URL, empty string if not provided ), array( '%s', // Format for article_content (string) '%s', // Format for embedding_vector (serialized string) '%s', // Format for source_url (string) ) ); if ($inserted === false) { //error_log('Error inserting content: ' . $wpdb->last_error); set_transient('mxchat_admin_notice_error', 'Error inserting content into the database. Please try again.', 30); } else { set_transient('mxchat_admin_notice_success', 'Content successfully submitted!', 30); } } else { //error_log('Embedding generation failed for article content: ' . $article_content); set_transient('mxchat_admin_notice_error', 'Embedding generation failed. Please ensure your API key is correct and try again.', 30); } // Redirect after setting the transient wp_safe_redirect(esc_url(admin_url('admin.php?page=mxchat-prompts'))); exit; } public function mxchat_display_admin_notice() { // Success notice if ($message = get_transient('mxchat_admin_notice_success')) { ?>' . esc_html__('All knowledge has been deleted successfully.', 'mxchat') . '
| ID | Article Content | URL | Actions |
|---|---|---|---|
| id); ?> | article_content))); ?> | source_url)) : ?> source_url); ?> N/A | Delete |
' . esc_html__('Intent updated successfully.', 'mxchat') . '
| intent_label ); ?> | phrases ); ?> | |||
Set the maximum number of messages a logged-in user can send within a 24-hour period.
'; echo 'Set the maximum number of messages a logged-out user can send within a 24-hour period.
'; echo ''; echo 'Automatically syncs new product additions, updates, and removals to the knowledge base. For existing products, submit your product sitemap in the Knowledge Base section to add them initially.'; echo '
'; if (!$this->is_activated) { echo ''; } echo 'The OpenAI API key is required even when using other models as it is used for vector embedding functionality.
'; } public function xai_api_key_callback() { // Check if the feature is activated (paid feature) $disabled = $this->is_activated ? '' : 'disabled'; // Disable input if not activated $class = $this->is_activated ? 'pro-feature-wrapper active' : 'pro-feature-wrapper inactive'; // CSS class to style the wrapper based on activation status // Render the input field for the X.AI API key echo 'Enter your Loops API Key here. (See FAQ for details)
'; } public function mxchat_loops_mailing_list_callback() { // Retrieve Loops API key and lists $loops_api_key = isset($this->options['loops_api_key']) ? $this->options['loops_api_key'] : ''; $selected_list = isset($this->options['loops_mailing_list']) ? $this->options['loops_mailing_list'] : ''; if ($loops_api_key) { // Fetch lists from Loops API $lists = $this->mxchat_fetch_loops_mailing_lists($loops_api_key); if ($lists) { echo ''; } else { echo 'No lists found. Please verify your API Key.
'; } } else { echo 'Enter a valid Loops API Key to load mailing lists.
'; } } public function mxchat_triggered_phrase_response_callback() { $triggered_response = isset($this->options['triggered_phrase_response']) ? $this->options['triggered_phrase_response'] : ''; echo ''; echo 'Enter the chatbot response when a trigger keyword is detected, prompting the user to share their email.
'; } public function mxchat_email_capture_response_callback() { $email_capture_response = isset($this->options['email_capture_response']) ? $this->options['email_capture_response'] : 'Thank you for providing your email! You\'ve been added to our list.'; echo ''; echo 'Enter the message to send when a user provides their email.
'; } public function mxchat_pre_chat_message_callback() { printf( '', isset($this->options['pre_chat_message']) ? esc_textarea($this->options['pre_chat_message']) : '' ); } // Callback for AI Instructions textarea public function system_prompt_instructions_callback() { printf( '', isset($this->options['system_prompt_instructions']) ? esc_textarea($this->options['system_prompt_instructions']) : '' ); } public function mxchat_model_callback() { $models = array( 'X.AI Models' => array( 'grok-beta' => 'grok-beta (Early Beta)' ), 'Claude Models' => array( 'claude-3-5-sonnet-20241022' => 'Claude 3.5 Sonnet (Most Intelligent)', 'claude-3-opus-20240229' => 'Claude 3 Opus (Highly Complex Tasks)', 'claude-3-sonnet-20240229' => 'Claude 3 Sonnet (Balanced)', 'claude-3-haiku-20240307' => 'Claude 3 Haiku (Fastest)' ), 'OpenAI Models' => array( 'gpt-4o' => 'GPT-4o (Recommended)', 'gpt-4o-mini' => 'GPT-4o Mini (Fast and Lightweight)', 'gpt-4-turbo' => 'GPT-4 Turbo (High-Performance)', 'gpt-4' => 'GPT-4 (High Intelligence)', 'gpt-3.5-turbo' => 'GPT-3.5 Turbo (Affordable and Fast)' ) ); $selected_model = isset($this->options['model']) ? $this->options['model'] : 'gpt-3.5-turbo'; echo ''; } public function mxchat_top_bar_title_callback() { printf( '', isset($this->options['top_bar_title']) ? esc_attr($this->options['top_bar_title']) : '' ); } public function enable_email_block_callback() { $email_block_checked = isset($this->options['enable_email_block']) && $this->options['enable_email_block'] === '1' ? 'checked' : ''; echo ''; echo 'Enable to require email before a user chats. Their email will appear at the top of transcript.
'; } public function email_blocker_header_content_callback() { // Grab the current stored value or default to empty $content = isset($this->options['email_blocker_header_content']) ? $this->options['email_blocker_header_content'] : ''; // Use esc_textarea to safely escape existing content in the