label. */ function avca_get_tabs() { return array( 'general' => __( 'General', 'avi-support-assistant' ), 'appearance' => __( 'Appearance', 'avi-support-assistant' ), 'conversation' => __( 'Questions & Answers', 'avi-support-assistant' ), 'leads' => __( 'Search & Leads', 'avi-support-assistant' ), 'contact' => __( 'Call & WhatsApp', 'avi-support-assistant' ), 'display' => __( 'Display Rules', 'avi-support-assistant' ), 'license' => __( 'Licence Key', 'avi-support-assistant' ), ); } /** * Register the admin menu. */ function avca_admin_menu() { add_menu_page( __( 'Avi Support Assistant', 'avi-support-assistant' ), __( 'Support Assistant', 'avi-support-assistant' ), 'manage_options', AVCA_MENU_SLUG, 'avca_render_settings_page', 'dashicons-format-chat', 58 ); add_submenu_page( AVCA_MENU_SLUG, __( 'Avi Support Assistant Settings', 'avi-support-assistant' ), __( 'Settings', 'avi-support-assistant' ), 'manage_options', AVCA_MENU_SLUG, 'avca_render_settings_page' ); add_submenu_page( AVCA_MENU_SLUG, __( 'Licence Key', 'avi-support-assistant' ), __( 'Licence Key', 'avi-support-assistant' ), 'manage_options', 'avinya_lic_' . AVCA_MENU_SLUG, 'avca_render_license_page' ); add_submenu_page( AVCA_MENU_SLUG, __( 'Unanswered Questions', 'avi-support-assistant' ), __( 'Unanswered Questions', 'avi-support-assistant' ), 'manage_options', 'avca-unanswered', 'avca_render_unanswered_page' ); if ( ! avca_pro_active() ) { add_submenu_page( AVCA_MENU_SLUG, __( 'Upgrade to Pro', 'avi-support-assistant' ), '★ ' . __( 'Upgrade to Pro', 'avi-support-assistant' ) . '', 'manage_options', 'avca-upgrade', 'avca_render_upgrade_page' ); } } add_action( 'admin_menu', 'avca_admin_menu' ); /** * Standalone Licence Key admin page callback. */ function avca_render_license_page() { if ( ! current_user_can( 'manage_options' ) ) { return; } if ( class_exists( 'Avinya_License_Client' ) ) { $client = Avinya_License_Client::get_instance( 'avi-support-assistant' ); if ( $client ) { $client->render_page( false ); return; } } ?>

render_page( true ); return; } } ?>

'array', 'sanitize_callback' => 'avca_sanitize_settings', 'default' => avca_get_defaults(), ) ); foreach ( avca_get_tabs() as $tab => $label ) { add_settings_section( 'avca_section_' . $tab, '', '__return_false', 'avca-tab-' . $tab ); } $fields = array( // General. 'enabled' => array( 'general', __( 'Show Support Assistant', 'avi-support-assistant' ) ), 'bot_name' => array( 'general', __( 'Bot Name', 'avi-support-assistant' ) ), 'subtitle' => array( 'general', __( 'Bot Subtitle', 'avi-support-assistant' ) ), 'tooltip' => array( 'general', __( 'Launcher Label', 'avi-support-assistant' ) ), 'welcome' => array( 'general', __( 'Welcome Message', 'avi-support-assistant' ) ), 'fallback' => array( 'general', __( 'No-Answer Message', 'avi-support-assistant' ) ), // Appearance. 'launcher' => array( 'appearance', __( 'Launcher Style', 'avi-support-assistant' ) ), 'bot_icon' => array( 'appearance', __( 'Bot Icon', 'avi-support-assistant' ) ), 'color' => array( 'appearance', __( 'Theme Colour', 'avi-support-assistant' ) ), 'theme' => array( 'appearance', __( 'Chat Window Theme', 'avi-support-assistant' ) ), 'position' => array( 'appearance', __( 'Position', 'avi-support-assistant' ) ), // Conversation. 'faqs' => array( 'conversation', __( 'Questions & Answers', 'avi-support-assistant' ) ), 'max_suggestions' => array( 'conversation', __( 'Suggested Questions Shown', 'avi-support-assistant' ) ), 'quick_links' => array( 'conversation', __( 'Quick Link Buttons', 'avi-support-assistant' ) ), // Search & leads. 'site_search' => array( 'leads', __( 'Site Search', 'avi-support-assistant' ) ), 'search_types' => array( 'leads', __( 'Search In', 'avi-support-assistant' ) ), 'lead_form' => array( 'leads', __( 'Lead Form', 'avi-support-assistant' ) ), 'lead_phone' => array( 'leads', __( 'Phone Field', 'avi-support-assistant' ) ), 'lead_prompt' => array( 'leads', __( 'Lead Form Message', 'avi-support-assistant' ) ), 'lead_button' => array( 'leads', __( 'Lead Button Label', 'avi-support-assistant' ) ), 'lead_thanks' => array( 'leads', __( 'Thank-You Message', 'avi-support-assistant' ) ), 'lead_email' => array( 'leads', __( 'Send Leads To', 'avi-support-assistant' ) ), 'log_unanswered' => array( 'leads', __( 'Unanswered Questions Log', 'avi-support-assistant' ) ), // Call & WhatsApp. 'call_number' => array( 'contact', __( 'Phone Number', 'avi-support-assistant' ) ), 'call_label' => array( 'contact', __( 'Call Button Label', 'avi-support-assistant' ) ), 'callback' => array( 'contact', __( 'Callback Requests', 'avi-support-assistant' ) ), 'callback_label' => array( 'contact', __( 'Callback Button Label', 'avi-support-assistant' ) ), 'whatsapp_number' => array( 'contact', __( 'WhatsApp Number', 'avi-support-assistant' ) ), 'whatsapp_label' => array( 'contact', __( 'WhatsApp Button Label', 'avi-support-assistant' ) ), 'whatsapp_text' => array( 'contact', __( 'WhatsApp Message', 'avi-support-assistant' ) ), 'contact_show' => array( 'contact', __( 'Show Contact Buttons', 'avi-support-assistant' ) ), // Display rules. 'auto_open' => array( 'display', __( 'Auto-Open', 'avi-support-assistant' ) ), 'devices' => array( 'display', __( 'Show On', 'avi-support-assistant' ) ), 'exclude_pages' => array( 'display', __( 'Hide On Pages', 'avi-support-assistant' ) ), 'delete_data' => array( 'display', __( 'Uninstall', 'avi-support-assistant' ) ), ); foreach ( $fields as $key => $field ) { add_settings_field( 'avca_' . $key, $field[1], 'avca_render_field', 'avca-tab-' . $field[0], 'avca_section_' . $field[0], array( 'key' => $key, 'label_for' => 'avca_' . $key, ) ); } } add_action( 'admin_init', 'avca_register_settings' ); /** * Field name attribute. * * @param string $key Setting key. * @return string */ function avca_field_name( $key ) { return AVCA_OPTION . '[' . $key . ']'; } /** * Render a checkbox. * * @param string $key Setting key. * @param string $label Label. */ function avca_render_checkbox( $key, $label ) { ?> $value ) { echo ' ' . esc_attr( $attr ) . '="' . esc_attr( $value ) . '"'; } ?> /> ' . esc_html( $text ) . '

'; } /** * Render any settings field. * * @param array $args Field args (key). */ function avca_render_field( $args ) { $key = $args['key']; switch ( $key ) { case 'enabled': avca_render_checkbox( $key, __( 'Show the support assistant on the site (untick to hide it everywhere)', 'avi-support-assistant' ) ); break; case 'bot_name': avca_render_input( $key ); avca_render_help( __( 'Shown in the chat window header.', 'avi-support-assistant' ) ); break; case 'subtitle': avca_render_input( $key ); avca_render_help( __( 'Short line under the bot name.', 'avi-support-assistant' ) ); break; case 'tooltip': avca_render_input( $key ); avca_render_help( __( 'Shown on hover (or on the button for the "Button with label" style) and read by screen readers.', 'avi-support-assistant' ) ); break; case 'welcome': avca_render_textarea( $key ); avca_render_help( __( 'First message shown when the chat opens.', 'avi-support-assistant' ) ); break; case 'fallback': avca_render_textarea( $key ); avca_render_help( __( 'Shown when no answer and no matching page is found.', 'avi-support-assistant' ) ); break; case 'launcher': case 'theme': case 'position': case 'devices': case 'contact_show': avca_render_select( $key ); break; case 'bot_icon': avca_render_icon_field(); break; case 'color': avca_render_input( $key, 'text', array( 'data-default-color' => avca_get_defaults()['color'] ) ); avca_render_help( __( 'Used for the header, buttons and the visitor\'s messages.', 'avi-support-assistant' ) ); break; case 'faqs': avca_render_faqs_field(); break; case 'max_suggestions': avca_render_input( $key, 'number', array( 'min' => '0', 'max' => '50' ) ); avca_render_help( __( 'How many questions to show as quick-reply buttons. 0 shows all of them.', 'avi-support-assistant' ) ); break; case 'quick_links': avca_render_textarea( $key, 4 ); avca_render_help( __( 'Buttons that open a page, one per line as "Label | URL". Example: Contact Us | https://example.com/contact/ (up to 10).', 'avi-support-assistant' ) ); break; case 'site_search': avca_render_checkbox( $key, __( 'When no FAQ matches, search your site and suggest up to 3 pages', 'avi-support-assistant' ) ); break; case 'search_types': avca_render_search_types_field(); break; case 'lead_form': avca_render_checkbox( $key, __( 'When no answer is found, offer a form so visitors can leave their details', 'avi-support-assistant' ) ); avca_render_help( __( 'Leads are saved under Support Assistant → Leads and emailed to you.', 'avi-support-assistant' ) ); break; case 'lead_phone': avca_render_checkbox( $key, __( 'Ask for a phone number (optional for the visitor)', 'avi-support-assistant' ) ); break; case 'lead_prompt': case 'lead_thanks': avca_render_textarea( $key, 2 ); break; case 'lead_button': avca_render_input( $key ); break; case 'lead_email': avca_render_input( $key, 'email', array( 'placeholder' => get_option( 'admin_email' ) ) ); avca_render_help( __( 'Leave empty to use the site admin email.', 'avi-support-assistant' ) ); break; case 'log_unanswered': avca_render_checkbox( $key, __( 'Keep a list of questions the bot could not answer', 'avi-support-assistant' ) ); avca_render_help( __( 'Only the question text is stored, never the visitor\'s details. See Support Assistant → Unanswered Questions.', 'avi-support-assistant' ) ); break; case 'call_number': avca_render_input( $key, 'tel', array( 'placeholder' => '+91 98765 43210' ) ); avca_render_help( __( 'Adds a click-to-call button. On mobile it dials this number. Leave empty to hide it.', 'avi-support-assistant' ) ); break; case 'call_label': case 'callback_label': case 'whatsapp_label': avca_render_input( $key ); break; case 'callback': avca_render_checkbox( $key, __( 'Show a "Request a callback" button (name, phone and preferred time)', 'avi-support-assistant' ) ); avca_render_help( __( 'Callback requests are saved under Support Assistant → Leads and emailed to you.', 'avi-support-assistant' ) ); break; case 'whatsapp_number': avca_render_input( $key, 'tel', array( 'placeholder' => '919876543210' ) ); avca_render_help( __( 'Adds a button that continues the chat on WhatsApp. Full number with country code, digits only. Leave empty to hide it.', 'avi-support-assistant' ) ); break; case 'whatsapp_text': avca_render_textarea( $key, 2 ); avca_render_help( __( 'Pre-filled WhatsApp message. Use {question} to include the visitor\'s last question.', 'avi-support-assistant' ) ); break; case 'auto_open': avca_render_input( $key, 'number', array( 'min' => '0', 'max' => '600' ) ); echo ' ' . esc_html__( 'seconds', 'avi-support-assistant' ); avca_render_help( __( 'Open the chat automatically after this many seconds, once per visit. 0 turns it off.', 'avi-support-assistant' ) ); break; case 'exclude_pages': avca_render_input( $key, 'text', array( 'placeholder' => '12, 45' ) ); avca_render_help( __( 'Comma-separated page or post IDs where the assistant should not appear (for example checkout).', 'avi-support-assistant' ) ); break; case 'delete_data': avca_render_checkbox( $key, __( 'Delete all settings, leads and logs when the plugin is deleted', 'avi-support-assistant' ) ); break; } } /** * Bot icon field. */ function avca_render_icon_field() { $icon = avca_get_setting( 'bot_icon' ); ?>
/>

$label ) : ?>
'', 'keywords' => '', 'answer' => '', ); ?>
( ) ' . esc_html( $count ) . '' ); ?>
$faq ) { avca_render_faq_row( $index, wp_parse_args( (array) $faq, $empty ) ); } ?>

$label ) : ?>

$teaser ) : ?>

[avi_support_assistant]' ); ?>

$entry ) : ?>
tab label, title, intro and feature list. */ function avca_get_pro_teasers() { if ( avca_pro_active() ) { return array(); } return array( 'pro-ai' => array( 'tab' => __( 'AI Answers', 'avi-support-assistant' ), 'title' => __( 'Let AI answer what your FAQs cannot', 'avi-support-assistant' ), 'intro' => __( 'When no FAQ matches, the assistant answers with AI using your own API key, so visitors get a helpful reply instead of "I don\'t know".', 'avi-support-assistant' ), 'features' => array( __( 'Works with OpenAI (ChatGPT), Google Gemini, Anthropic Claude, OpenRouter and DeepSeek', 'avi-support-assistant' ), __( 'Uses your questions and answers and matching pages from your site', 'avi-support-assistant' ), __( 'Remembers the conversation for follow-up questions', 'avi-support-assistant' ), __( 'Replies in the visitor\'s language', 'avi-support-assistant' ), __( 'Monthly and per-visitor limits to control API costs', 'avi-support-assistant' ), ), ), 'pro-voice' => array( 'tab' => __( 'Voice Chat', 'avi-support-assistant' ), 'title' => __( 'Visitors can talk to your assistant', 'avi-support-assistant' ), 'intro' => __( 'A microphone button lets visitors speak their question, and the assistant can read its answer aloud.', 'avi-support-assistant' ), 'features' => array( __( 'Speak instead of typing, great on mobile', 'avi-support-assistant' ), __( 'Spoken replies, always or only after a voice question', 'avi-support-assistant' ), __( 'Mute button for visitors', 'avi-support-assistant' ), __( 'Follows your site language', 'avi-support-assistant' ), ), ), 'pro-crm' => array( 'tab' => __( 'Zoho CRM', 'avi-support-assistant' ), 'title' => __( 'Send every lead to your CRM automatically', 'avi-support-assistant' ), 'intro' => __( 'Chat leads and callback requests are created in Zoho CRM the moment a visitor submits them.', 'avi-support-assistant' ), 'features' => array( __( 'Zoho CRM Leads, all data centres (India, US, EU and more)', 'avi-support-assistant' ), __( 'Webhook for Zapier, Make, n8n, HubSpot and other CRMs', 'avi-support-assistant' ), __( 'Sync status shown in your Leads list', 'avi-support-assistant' ), ), ), 'pro-analytics' => array( 'tab' => __( 'History & Analytics', 'avi-support-assistant' ), 'title' => __( 'See every conversation and what visitors ask', 'avi-support-assistant' ), 'intro' => __( 'Read full chat transcripts and find out how well your assistant is answering.', 'avi-support-assistant' ), 'features' => array( __( 'Conversation history with full transcripts', 'avi-support-assistant' ), __( 'How questions were answered: FAQ, AI, products, site search or no answer', 'avi-support-assistant' ), __( 'Top visitor questions and conversations per day', 'avi-support-assistant' ), __( 'CSV export and automatic clean-up of old chats', 'avi-support-assistant' ), ), ), 'pro-woo' => array( 'tab' => __( 'WooCommerce', 'avi-support-assistant' ), 'title' => __( 'Sell and support customers inside the chat', 'avi-support-assistant' ), 'intro' => __( 'Visitors can find products and check their orders without leaving the chat.', 'avi-support-assistant' ), 'features' => array( __( '"Find a product" search with prices, images and Add to cart', 'avi-support-assistant' ), __( '"Track my order" with order number and billing email', 'avi-support-assistant' ), __( 'Optional product suggestions when no FAQ matches', 'avi-support-assistant' ), ), ), 'pro-hours' => array( 'tab' => __( 'Office Hours & Languages', 'avi-support-assistant' ), 'title' => __( 'Right message, right time, right language', 'avi-support-assistant' ), 'intro' => __( 'Tell visitors when you are closed and serve every language on your site.', 'avi-support-assistant' ), 'features' => array( __( 'Opening hours for each day, with a closed message', 'avi-support-assistant' ), __( 'Hide Call and WhatsApp buttons while closed', 'avi-support-assistant' ), __( 'Translate bot texts and FAQs with WPML or Polylang', 'avi-support-assistant' ), ), ), ); } /** * Render one locked Pro tab. * * @param array $teaser Teaser data. */ function avca_render_pro_teaser( $teaser ) { ?>

__( 'Starter', 'avi-support-assistant' ), 'sites' => __( '1 website', 'avi-support-assistant' ), 'yearly' => '₹2,499', 'monthly' => '₹299', 'lifetime' => '₹7,999', ), array( 'name' => __( 'Pro', 'avi-support-assistant' ), 'sites' => __( '3 websites', 'avi-support-assistant' ), 'yearly' => '₹4,999', 'monthly' => '₹549', 'lifetime' => '₹14,999', 'popular' => true, ), array( 'name' => __( 'Agency', 'avi-support-assistant' ), 'sites' => __( '25 websites', 'avi-support-assistant' ), 'yearly' => '₹11,999', 'monthly' => '', 'lifetime' => '₹29,999', ), ); } /** * Render the Upgrade to Pro page. */ function avca_render_upgrade_page() { if ( ! current_user_can( 'manage_options' ) ) { return; } $features = array( __( 'AI answers with your own API key: OpenAI (ChatGPT), Google Gemini, Anthropic Claude, OpenRouter or DeepSeek', 'avi-support-assistant' ), __( 'AI uses your FAQs and site content, and replies in the visitor\'s language', 'avi-support-assistant' ), __( 'Voice chat: visitors speak their question and hear the answer', 'avi-support-assistant' ), __( 'Zoho CRM lead sync, plus a webhook for any other CRM', 'avi-support-assistant' ), __( 'Chat history, analytics dashboard and CSV export', 'avi-support-assistant' ), __( 'WooCommerce product search and order tracking in the chat', 'avi-support-assistant' ), __( 'Office hours with a different message when you are closed', 'avi-support-assistant' ), __( 'Multi-language with WPML and Polylang', 'avi-support-assistant' ), __( 'Priority email support and all updates while your licence is active', 'avi-support-assistant' ), ); ?>

'avca-unanswered', 'avca_notice' => '' === $key ? 'cleared' : 'deleted', ), admin_url( 'admin.php' ) ) ); exit; } add_action( 'admin_post_avca_delete_unanswered', 'avca_handle_delete_unanswered' ); /** * Admin assets for the plugin screens. * * @param string $hook_suffix Current admin page hook. */ function avca_admin_assets( $hook_suffix ) { if ( 'toplevel_page_' . AVCA_MENU_SLUG !== $hook_suffix ) { return; } wp_enqueue_media(); wp_enqueue_style( 'wp-color-picker' ); wp_enqueue_style( 'avca-admin', AVCA_URL . 'assets/css/admin.css', array(), AVCA_VERSION ); wp_enqueue_script( 'avca-admin', AVCA_URL . 'assets/js/admin.js', array( 'jquery', 'wp-color-picker' ), AVCA_VERSION, true ); wp_localize_script( 'avca-admin', 'avcaAdmin', array( 'mediaTitle' => __( 'Choose bot icon', 'avi-support-assistant' ), 'mediaButton' => __( 'Use this image', 'avi-support-assistant' ), ) ); wp_localize_script( 'avca-admin', 'avcaFaqConfig', array( 'isPro' => avca_pro_active(), 'maxFree' => 3, 'templates' => function_exists( 'avca_get_faq_templates' ) ? avca_get_faq_templates() : array(), 'upgradeUrl' => admin_url( 'admin.php?page=avca-upgrade' ), 'i18n' => array( 'confirmReplace' => __( 'Do you want to replace your existing FAQs with this template? Click OK to replace existing questions, or Cancel to append up to the allowed limit.', 'avi-support-assistant' ), 'limitReached' => __( 'Free Plan Limit: You can have at most 3 FAQs on the Free plan. Upgrade to Pro for unlimited questions.', 'avi-support-assistant' ), ), ) ); } add_action( 'admin_enqueue_scripts', 'avca_admin_assets' ); /** * Small style for the unanswered page's inline forms. */ function avca_admin_unanswered_style() { $screen = get_current_screen(); if ( $screen && ( false !== strpos( $screen->id, 'avca-unanswered' ) || false !== strpos( $screen->id, 'avca-upgrade' ) || false !== strpos( $screen->id, 'avinya_lic_' ) ) ) { wp_enqueue_style( 'avca-admin', AVCA_URL . 'assets/css/admin.css', array(), AVCA_VERSION ); } } add_action( 'admin_enqueue_scripts', 'avca_admin_unanswered_style', 20 ); /** * Add a "Settings" link on the Plugins screen. * * @param array $links Existing links. * @return array */ function avca_action_links( $links ) { $settings_link = '' . esc_html__( 'Settings', 'avi-support-assistant' ) . ''; array_unshift( $links, $settings_link ); if ( ! avca_pro_active() ) { $links[] = '' . esc_html__( 'Go Pro', 'avi-support-assistant' ) . ''; } return $links; } add_filter( 'plugin_action_links_' . plugin_basename( AVCA_FILE ), 'avca_action_links' );