option_name); $daily_limit = isset($opts['daily_token_limit']) ? intval($opts['daily_token_limit']) : \AiChatbotBuilder\Admin\Settings::DEFAULT_DAILY_TOKEN_LIMIT; $daily_usage = $this->get_daily_usage(); wp_localize_script( 'aichatbotbuilder-chat', 'aichatbotbuilderChatSettings', array( 'ajax_url' => admin_url('admin-ajax.php'), 'nonce' => wp_create_nonce('aichatbotbuilder_send_message_nonce'), 'daily_limit' => $daily_limit, 'daily_usage' => $daily_usage, ) ); } // Add daily usage helper methods. /** * Gets the current daily token usage. * * @return int Number of tokens used today. */ private function get_daily_usage(): int { $usage_data = get_option('aichatbotbuilder_daily_usage', array('date' => '', 'count' => 0)); $today = current_time('Y-m-d'); if (! isset($usage_data['date']) || $usage_data['date'] !== $today) { return 0; } return intval($usage_data['count']); } /** * Increments the daily token usage count. * * @param int $tokens Number of tokens to add. * @return void */ private function increment_daily_usage(int $tokens): void { $today = current_time('Y-m-d'); $usage_data = get_option('aichatbotbuilder_daily_usage', array('date' => '', 'count' => 0)); if (! isset($usage_data['date']) || $usage_data['date'] !== $today) { $usage_data = array( 'date' => $today, 'count' => 0, ); } $usage_data['count'] = intval($usage_data['count']) + $tokens; update_option('aichatbotbuilder_daily_usage', $usage_data, false); } /** * Renders the chat UI via shortcode. * * @param array $atts Shortcode attributes. * @return string HTML markup for chat. */ public function render_chat_shortcode($atts): string { $atts = shortcode_atts(array('id' => 0), $atts, 'aichatbot_chat'); $chat_id = absint($atts['id']); // If no chat ID provided, use the first published chat instance if (! $chat_id) { $all_chats = get_posts( array( 'post_type' => 'aichatbot_chat', 'numberposts' => 1, 'post_status' => 'publish', 'fields' => 'ids', ) ); if (! empty($all_chats)) { $chat_id = absint($all_chats[0]); } } // Fetch configuration and metadata. $initial_prompt = $chat_id ? get_post_meta($chat_id, 'aichatbotbuilder_initial_prompt', true) : ''; $bg_color = $chat_id ? get_post_meta($chat_id, 'aichatbotbuilder_bg_color', true) : ''; $user_color = $chat_id ? get_post_meta($chat_id, 'aichatbotbuilder_user_color', true) : ''; $bot_color = $chat_id ? get_post_meta($chat_id, 'aichatbotbuilder_bot_color', true) : ''; // Determine chat position; respect explicit inline (empty) if set in meta if ($chat_id && metadata_exists('post', $chat_id, 'aichatbotbuilder_position')) { $position = sanitize_text_field(get_post_meta($chat_id, 'aichatbotbuilder_position', true)); } else { $position = 'bottom-right'; } $z_index_raw = $chat_id ? get_post_meta($chat_id, 'aichatbotbuilder_z_index', true) : ''; $z_index = '' === $z_index_raw ? 9999 : intval($z_index_raw); // Context memory settings $memory_enabled = $chat_id && get_post_meta($chat_id, 'aichatbotbuilder_memory_enabled', true) === '1' ? '1' : '0'; $memory_length = $chat_id ? absint(get_post_meta($chat_id, 'aichatbotbuilder_memory_length', true)) : 0; // Style fields $container_border_color = $chat_id ? get_post_meta($chat_id, 'aichatbotbuilder_container_border_color', true) : ''; $container_border_width = $chat_id ? get_post_meta($chat_id, 'aichatbotbuilder_container_border_width', true) : ''; $container_border_radius = $chat_id ? get_post_meta($chat_id, 'aichatbotbuilder_container_border_radius', true) : ''; // Container max width setting $container_max_width = $chat_id ? get_post_meta($chat_id, 'aichatbotbuilder_container_max_width', true) : ''; $container_min_height = $chat_id ? get_post_meta($chat_id, 'aichatbotbuilder_container_min_height', true) : ''; $container_min_height = $container_min_height ?: 450; $input_bg_color = $chat_id ? get_post_meta($chat_id, 'aichatbotbuilder_input_bg_color', true) : ''; $input_text_color = $chat_id ? get_post_meta($chat_id, 'aichatbotbuilder_input_text_color', true) : ''; $input_border_color = $chat_id ? get_post_meta($chat_id, 'aichatbotbuilder_input_border_color', true) : ''; $input_border_radius = $chat_id ? get_post_meta($chat_id, 'aichatbotbuilder_input_border_radius', true) : ''; $input_border_width = $chat_id ? get_post_meta($chat_id, 'aichatbotbuilder_input_border_width', true) : ''; $button_bg_color = $chat_id ? get_post_meta($chat_id, 'aichatbotbuilder_button_bg_color', true) : ''; $button_text_color = $chat_id ? get_post_meta($chat_id, 'aichatbotbuilder_button_text_color', true) : ''; $button_border_color = $chat_id ? get_post_meta($chat_id, 'aichatbotbuilder_button_border_color', true) : ''; $button_border_radius = $chat_id ? get_post_meta($chat_id, 'aichatbotbuilder_button_border_radius', true) : ''; $button_border_width = $chat_id ? get_post_meta($chat_id, 'aichatbotbuilder_button_border_width', true) : ''; // Clear button styles $clear_bg_color = $chat_id ? get_post_meta($chat_id, 'aichatbotbuilder_clear_bg_color', true) : ''; $clear_text_color = $chat_id ? get_post_meta($chat_id, 'aichatbotbuilder_clear_text_color', true) : ''; $clear_border_color = $chat_id ? get_post_meta($chat_id, 'aichatbotbuilder_clear_border_color', true) : ''; $clear_border_width = $chat_id ? get_post_meta($chat_id, 'aichatbotbuilder_clear_border_width', true) : ''; $clear_border_radius = $chat_id ? get_post_meta($chat_id, 'aichatbotbuilder_clear_border_radius', true) : ''; // Launcher button meta and defaults $launcher_bg_color = $chat_id ? get_post_meta($chat_id, 'aichatbotbuilder_launcher_bg_color', true) : ''; $launcher_icon_color = $chat_id ? get_post_meta($chat_id, 'aichatbotbuilder_launcher_icon_color', true) : ''; // Launcher enabled flag $launcher_enabled = $chat_id ? get_post_meta($chat_id, 'aichatbotbuilder_launcher_enabled', true) : ''; $launcher_enabled = $launcher_enabled === '' ? '1' : $launcher_enabled; // Launcher position is fixed above the chat container $launcher_position = 'above'; // Disable floating button for inline embeds if ('inline' === $position) { $launcher_enabled = '0'; } // Text labels $placeholder_text = $chat_id ? get_post_meta($chat_id, 'aichatbotbuilder_placeholder_text', true) : ''; $send_button_text = $chat_id ? get_post_meta($chat_id, 'aichatbotbuilder_send_button_text', true) : ''; $clear_button_text = $chat_id ? get_post_meta($chat_id, 'aichatbotbuilder_clear_button_text', true) : ''; // Greeting message and styles $greeting_message = $chat_id ? get_post_meta($chat_id, 'aichatbotbuilder_greeting_message', true) : ''; $greeting_message = $greeting_message ?: __('How can we help you?', 'ai-chatbot-builder'); $greeting_bg_color = $chat_id ? get_post_meta($chat_id, 'aichatbotbuilder_greeting_bg_color', true) : ''; $greeting_text_color = $chat_id ? get_post_meta($chat_id, 'aichatbotbuilder_greeting_text_color', true) : ''; $greeting_border_color = $chat_id ? get_post_meta($chat_id, 'aichatbotbuilder_greeting_border_color', true) : ''; $greeting_border_width = $chat_id ? get_post_meta($chat_id, 'aichatbotbuilder_greeting_border_width', true) : ''; $greeting_border_radius = $chat_id ? get_post_meta($chat_id, 'aichatbotbuilder_greeting_border_radius', true) : ''; // Apply default greeting styles if empty $greeting_bg_color = $greeting_bg_color ?: '#f1f1f1'; $greeting_text_color = $greeting_text_color ?: '#000000'; $greeting_border_color = $greeting_border_color ?: '#ccc'; $greeting_border_width = '' !== $greeting_border_width ? absint($greeting_border_width) : 1; $greeting_border_radius = '' !== $greeting_border_radius ? absint($greeting_border_radius) : 4; // Apply defaults if empty $placeholder_text = $placeholder_text ?: __('Type a message...', 'ai-chatbot-builder'); $send_button_text = $send_button_text ?: __('Send', 'ai-chatbot-builder'); $clear_button_text = $clear_button_text ?: __('Clear', 'ai-chatbot-builder'); // Header Title and Subtitle $header_title = $chat_id ? get_post_meta($chat_id, 'aichatbotbuilder_header_title', true) : ''; $header_title = $header_title ?: __('Send a message', 'ai-chatbot-builder'); $header_subtitle = $chat_id ? get_post_meta($chat_id, 'aichatbotbuilder_header_subtitle', true) : ''; $header_subtitle = $header_subtitle ?: __('We usually respond in a few hours', 'ai-chatbot-builder'); // Typing indicator color setting $typing_color = $chat_id ? get_post_meta($chat_id, 'aichatbotbuilder_typing_color', true) : ''; $typing_color = $typing_color ?: $bot_color ?: '#333333'; // Apply appearance presets or custom CSS vars $style_preset = $chat_id ? get_post_meta($chat_id, 'aichatbotbuilder_style_preset', true) : 'apple'; $style_preset = $style_preset ?: 'apple'; $css_vars = ''; if ('custom' !== $style_preset) { switch ($style_preset) { case 'google': $css_vars = '--aichatbotbuilder-bg-color:#f1f3f4;--aichatbotbuilder-container-border-color:transparent;--aichatbotbuilder-container-border-width:1px;--aichatbotbuilder-container-border-radius:8px;--aichatbotbuilder-user-color:#cfe8fd;--aichatbotbuilder-user-text-color:#000000;--aichatbotbuilder-bot-color:#f1f3f4;--aichatbotbuilder-bot-text-color:#000000;--aichatbotbuilder-input-bg-color:#ffffff;--aichatbotbuilder-input-text-color:#202124;--aichatbotbuilder-input-border-color:#dadce0;--aichatbotbuilder-input-border-width:1px;--aichatbotbuilder-input-border-radius:24px;--aichatbotbuilder-button-bg-color:#1a73e8;--aichatbotbuilder-button-text-color:#ffffff;--aichatbotbuilder-button-border-color:#1a73e8;--aichatbotbuilder-button-border-width:1px;--aichatbotbuilder-button-border-radius:24px;--aichatbotbuilder-clear-bg-color:#e0e0e0;--aichatbotbuilder-clear-text-color:#000000;--aichatbotbuilder-clear-border-color:#dadce0;--aichatbotbuilder-clear-border-width:1px;--aichatbotbuilder-clear-border-radius:24px;--aichatbotbuilder-button-bg-hover:#1765c1;--aichatbotbuilder-input-border-hover:#1765c1;'; break; case 'apple': $css_vars = '--aichatbotbuilder-bg-color:#ffffff;--aichatbotbuilder-container-border-color:#e0e0e0;--aichatbotbuilder-container-border-width:1px;--aichatbotbuilder-container-border-radius:8px;--aichatbotbuilder-user-color:#007aff;--aichatbotbuilder-user-text-color:#ffffff;--aichatbotbuilder-bot-color:#f2f2f2;--aichatbotbuilder-bot-text-color:#000000;--aichatbotbuilder-input-bg-color:#f2f2f2;--aichatbotbuilder-input-text-color:#000000;--aichatbotbuilder-input-border-color:#d1d1d6;--aichatbotbuilder-input-border-width:1px;--aichatbotbuilder-input-border-radius:18px;--aichatbotbuilder-button-bg-color:#007aff;--aichatbotbuilder-button-text-color:#ffffff;--aichatbotbuilder-button-border-color:#007aff;--aichatbotbuilder-button-border-width:1px;--aichatbotbuilder-button-border-radius:18px;--aichatbotbuilder-clear-bg-color:#d1d1d6;--aichatbotbuilder-clear-text-color:#000000;--aichatbotbuilder-clear-border-color:#d1d1d6;--aichatbotbuilder-clear-border-width:1px;--aichatbotbuilder-clear-border-radius:18px;--aichatbotbuilder-button-bg-hover:#005ecb;--aichatbotbuilder-input-border-hover:#005ecb;'; break; case 'whatsapp': $css_vars = '--aichatbotbuilder-bg-color:#ece5dd;--aichatbotbuilder-container-border-color:transparent;--aichatbotbuilder-container-border-width:1px;--aichatbotbuilder-container-border-radius:0;--aichatbotbuilder-user-color:#daf8cb;--aichatbotbuilder-user-text-color:#000000;--aichatbotbuilder-bot-color:#ece5dd;--aichatbotbuilder-bot-text-color:#000000;--aichatbotbuilder-input-bg-color:#ffffff;--aichatbotbuilder-input-text-color:#000000;--aichatbotbuilder-input-border-color:#cccccc;--aichatbotbuilder-input-border-width:1px;--aichatbotbuilder-input-border-radius:16px;--aichatbotbuilder-button-bg-color:#075e54;--aichatbotbuilder-button-text-color:#ffffff;--aichatbotbuilder-button-border-color:#075e54;--aichatbotbuilder-button-border-width:1px;--aichatbotbuilder-button-border-radius:16px;--aichatbotbuilder-clear-bg-color:#e0e0e0;--aichatbotbuilder-clear-text-color:#000000;--aichatbotbuilder-clear-border-color:#cccccc;--aichatbotbuilder-clear-border-width:1px;--aichatbotbuilder-clear-border-radius:16px;--aichatbotbuilder-button-bg-hover:#064c47;--aichatbotbuilder-input-border-hover:#064c47;'; break; case 'facebook': $css_vars = '--aichatbotbuilder-bg-color:#f0f2f5;--aichatbotbuilder-container-border-color:transparent;--aichatbotbuilder-container-border-width:1px;--aichatbotbuilder-container-border-radius:6px;--aichatbotbuilder-user-color:#0084ff;--aichatbotbuilder-user-text-color:#ffffff;--aichatbotbuilder-bot-color:#e4e6eb;--aichatbotbuilder-bot-text-color:#000000;--aichatbotbuilder-input-bg-color:#ffffff;--aichatbotbuilder-input-text-color:#050505;--aichatbotbuilder-input-border-color:#ccd0d5;--aichatbotbuilder-input-border-width:1px;--aichatbotbuilder-input-border-radius:20px;--aichatbotbuilder-button-bg-color:#0084ff;--aichatbotbuilder-button-text-color:#ffffff;--aichatbotbuilder-button-border-color:#0084ff;--aichatbotbuilder-button-border-width:1px;--aichatbotbuilder-button-border-radius:20px;--aichatbotbuilder-clear-bg-color:#e4e6eb;--aichatbotbuilder-clear-text-color:#050505;--aichatbotbuilder-clear-border-color:#ccd0d5;--aichatbotbuilder-clear-border-width:1px;--aichatbotbuilder-clear-border-radius:20px;--aichatbotbuilder-button-bg-hover:#006fd6;--aichatbotbuilder-input-border-hover:#006fd6;'; break; case 'telegram': $css_vars = '--aichatbotbuilder-bg-color:#f7f7f7;--aichatbotbuilder-container-border-color:transparent;--aichatbotbuilder-container-border-width:1px;--aichatbotbuilder-container-border-radius:12px;--aichatbotbuilder-user-color:#dcf8c6;--aichatbotbuilder-user-text-color:#000000;--aichatbotbuilder-bot-color:#f7f7f7;--aichatbotbuilder-bot-text-color:#000000;--aichatbotbuilder-input-bg-color:#ffffff;--aichatbotbuilder-input-text-color:#000000;--aichatbotbuilder-input-border-color:#dcdcdc;--aichatbotbuilder-input-border-width:1px;--aichatbotbuilder-input-border-radius:20px;--aichatbotbuilder-button-bg-color:#0088cc;--aichatbotbuilder-button-text-color:#ffffff;--aichatbotbuilder-button-border-color:#0088cc;--aichatbotbuilder-button-border-width:1px;--aichatbotbuilder-button-border-radius:20px;--aichatbotbuilder-clear-bg-color:#e0e0e0;--aichatbotbuilder-clear-text-color:#000000;--aichatbotbuilder-clear-border-color:#dcdcdc;--aichatbotbuilder-clear-border-width:1px;--aichatbotbuilder-clear-border-radius:20px;--aichatbotbuilder-button-bg-hover:#007ab8;--aichatbotbuilder-input-border-hover:#007ab8;'; break; case 'slack': $css_vars = '--aichatbotbuilder-bg-color:#f8f8f8;--aichatbotbuilder-container-border-color:transparent;--aichatbotbuilder-container-border-width:1px;--aichatbotbuilder-container-border-radius:4px;--aichatbotbuilder-user-color:#e01e5a;--aichatbotbuilder-user-text-color:#ffffff;--aichatbotbuilder-bot-color:#e1e1e1;--aichatbotbuilder-bot-text-color:#000000;--aichatbotbuilder-input-bg-color:#ffffff;--aichatbotbuilder-input-text-color:#000000;--aichatbotbuilder-input-border-color:#dddddd;--aichatbotbuilder-input-border-width:1px;--aichatbotbuilder-input-border-radius:4px;--aichatbotbuilder-button-bg-color:#3e5aac;--aichatbotbuilder-button-text-color:#ffffff;--aichatbotbuilder-button-border-color:#3e5aac;--aichatbotbuilder-button-border-width:1px;--aichatbotbuilder-button-border-radius:4px;--aichatbotbuilder-clear-bg-color:#e0e0e0;--aichatbotbuilder-clear-text-color:#000000;--aichatbotbuilder-clear-border-color:#dddddd;--aichatbotbuilder-clear-border-width:1px;--aichatbotbuilder-clear-border-radius:4px;--aichatbotbuilder-button-bg-hover:#2d417a;--aichatbotbuilder-input-border-hover:#2d417a;'; break; case 'chatgpt': $css_vars = '--aichatbotbuilder-bg-color:#ffffff;--aichatbotbuilder-container-border-color:#e5e7eb;--aichatbotbuilder-container-border-width:1px;--aichatbotbuilder-container-border-radius:8px;--aichatbotbuilder-user-color:#f9fafb;--aichatbotbuilder-user-text-color:#000000;--aichatbotbuilder-bot-color:#f3f4f6;--aichatbotbuilder-bot-text-color:#000000;--aichatbotbuilder-input-bg-color:#ffffff;--aichatbotbuilder-input-text-color:#000000;--aichatbotbuilder-input-border-color:#d1d5db;--aichatbotbuilder-input-border-width:1px;--aichatbotbuilder-input-border-radius:6px;--aichatbotbuilder-button-bg-color:#000000;--aichatbotbuilder-button-text-color:#ffffff;--aichatbotbuilder-button-border-color:#000000;--aichatbotbuilder-button-border-width:1px;--aichatbotbuilder-button-border-radius:6px;--aichatbotbuilder-clear-bg-color:#f3f4f6;--aichatbotbuilder-clear-text-color:#555555;--aichatbotbuilder-clear-border-color:#d1d5db;--aichatbotbuilder-clear-border-width:1px;--aichatbotbuilder-clear-border-radius:6px;--aichatbotbuilder-button-bg-hover:#333333;--aichatbotbuilder-input-border-hover:#a0a0a0;--aichatbotbuilder-header-bg-color:#000000;--aichatbotbuilder-header-text-color:#ffffff;--aichatbotbuilder-typing-color:#555555;'; break; case 'gemini': $css_vars = '--aichatbotbuilder-bg-color:#f0f4f9;--aichatbotbuilder-container-border-color:transparent;--aichatbotbuilder-container-border-width:0px;--aichatbotbuilder-container-border-radius:12px;--aichatbotbuilder-user-color:#e8e8f0;--aichatbotbuilder-user-text-color:#1f1f1f;--aichatbotbuilder-bot-color:#dde3ea;--aichatbotbuilder-bot-text-color:#1f1f1f;--aichatbotbuilder-input-bg-color:#ffffff;--aichatbotbuilder-input-text-color:#1f1f1f;--aichatbotbuilder-input-border-color:#c4c7c5;--aichatbotbuilder-input-border-width:1px;--aichatbotbuilder-input-border-radius:24px;--aichatbotbuilder-button-bg-color:#1a73e8;--aichatbotbuilder-button-text-color:#ffffff;--aichatbotbuilder-button-border-color:#1a73e8;--aichatbotbuilder-button-border-width:1px;--aichatbotbuilder-button-border-radius:24px;--aichatbotbuilder-clear-bg-color:#e0e0e0;--aichatbotbuilder-clear-text-color:#444746;--aichatbotbuilder-clear-border-color:#c4c7c5;--aichatbotbuilder-clear-border-width:1px;--aichatbotbuilder-clear-border-radius:24px;--aichatbotbuilder-button-bg-hover:#0b57d0;--aichatbotbuilder-input-border-hover:#0b57d0;--aichatbotbuilder-header-bg-color:#1f1f1f;--aichatbotbuilder-header-text-color:#e3e3e3;--aichatbotbuilder-typing-color:#444746;'; break; default: $style_preset = 'custom'; break; } } // Apply custom CSS var declarations only when in 'custom' preset if ('custom' === $style_preset) { if ($bg_color) { $css_vars .= '--aichatbotbuilder-bg-color:' . esc_attr($bg_color) . ';'; } if ($container_border_color) { $css_vars .= '--aichatbotbuilder-container-border-color:' . esc_attr($container_border_color) . ';'; } if ($container_border_width !== '') { $css_vars .= '--aichatbotbuilder-container-border-width:' . intval($container_border_width) . 'px;'; } if ($container_border_radius !== '') { $css_vars .= '--aichatbotbuilder-container-border-radius:' . intval($container_border_radius) . 'px;'; } if ($container_max_width !== '') { $css_vars .= '--aichatbotbuilder-container-max-width:' . intval($container_max_width) . 'px;'; } if ($container_min_height !== '') { $css_vars .= '--aichatbotbuilder-container-min-height:' . intval($container_min_height) . 'px;'; } if ($user_color) { $css_vars .= '--aichatbotbuilder-user-color:' . esc_attr($user_color) . ';'; } if ($bot_color) { $css_vars .= '--aichatbotbuilder-bot-color:' . esc_attr($bot_color) . ';'; } if ($input_bg_color) { $css_vars .= '--aichatbotbuilder-input-bg-color:' . esc_attr($input_bg_color) . ';'; } if ($input_text_color) { $css_vars .= '--aichatbotbuilder-input-text-color:' . esc_attr($input_text_color) . ';'; } if ($input_border_color) { $css_vars .= '--aichatbotbuilder-input-border-color:' . esc_attr($input_border_color) . ';'; } if ($input_border_width !== '') { $css_vars .= '--aichatbotbuilder-input-border-width:' . intval($input_border_width) . 'px;'; } if ($input_border_radius !== '') { $css_vars .= '--aichatbotbuilder-input-border-radius:' . intval($input_border_radius) . 'px;'; } if ($button_bg_color) { $css_vars .= '--aichatbotbuilder-button-bg-color:' . esc_attr($button_bg_color) . ';'; } if ($button_text_color) { $css_vars .= '--aichatbotbuilder-button-text-color:' . esc_attr($button_text_color) . ';'; } if ($button_border_color) { $css_vars .= '--aichatbotbuilder-button-border-color:' . esc_attr($button_border_color) . ';'; } if ($button_border_width !== '') { $css_vars .= '--aichatbotbuilder-button-border-width:' . intval($button_border_width) . 'px;'; } if ($button_border_radius !== '') { $css_vars .= '--aichatbotbuilder-button-border-radius:' . intval($button_border_radius) . 'px;'; } // Add hover state variable based on button bg color if ($button_bg_color) { // Simple darken function placeholder - adjust logic if needed $hover_color = $button_bg_color; // TODO: Implement a real darken function if needed $css_vars .= '--aichatbotbuilder-button-bg-hover:' . esc_attr($hover_color) . ';'; } if ($clear_bg_color) { $css_vars .= '--aichatbotbuilder-clear-bg-color:' . esc_attr($clear_bg_color) . ';'; } if ($clear_text_color) { $css_vars .= '--aichatbotbuilder-clear-text-color:' . esc_attr($clear_text_color) . ';'; } if ($clear_border_color) { $css_vars .= '--aichatbotbuilder-clear-border-color:' . esc_attr($clear_border_color) . ';'; } if ($clear_border_width !== '') { $css_vars .= '--aichatbotbuilder-clear-border-width:' . intval($clear_border_width) . 'px;'; } if ($clear_border_radius !== '') { $css_vars .= '--aichatbotbuilder-clear-border-radius:' . intval($clear_border_radius) . 'px;'; } // Greeting style vars if ($greeting_bg_color) { $css_vars .= '--aichatbotbuilder-greeting-bg-color:' . esc_attr($greeting_bg_color) . ';'; } if ($greeting_text_color) { $css_vars .= '--aichatbotbuilder-greeting-text-color:' . esc_attr($greeting_text_color) . ';'; } if ($greeting_border_color) { $css_vars .= '--aichatbotbuilder-greeting-border-color:' . esc_attr($greeting_border_color) . ';'; } if ($greeting_border_width !== '') { $css_vars .= '--aichatbotbuilder-greeting-border-width:' . intval($greeting_border_width) . 'px;'; } if ($greeting_border_radius !== '') { $css_vars .= '--aichatbotbuilder-greeting-border-radius:' . intval($greeting_border_radius) . 'px;'; } // Launcher style vars if ($launcher_bg_color) { $css_vars .= '--aichatbotbuilder-launcher-bg-color:' . esc_attr($launcher_bg_color) . ';'; } // Header color from custom button color or fallback if ($button_bg_color) { $css_vars .= '--aichatbotbuilder-header-bg-color:' . esc_attr($button_bg_color) . ';'; } else { $css_vars .= '--aichatbotbuilder-header-bg-color:#de4452;'; } $css_vars .= '--aichatbotbuilder-header-text-color:#fff;'; // Typing indicator color $css_vars .= '--aichatbotbuilder-typing-color:' . esc_attr($typing_color) . ';'; } // Add default greeting vars for non-custom presets if ('custom' !== $style_preset) { $css_vars .= '--aichatbotbuilder-greeting-bg-color:var(--aichatbotbuilder-bg-color);'; $css_vars .= '--aichatbotbuilder-greeting-text-color:var(--aichatbotbuilder-bot-text-color);'; $css_vars .= '--aichatbotbuilder-greeting-border-color:var(--aichatbotbuilder-container-border-color);'; $css_vars .= '--aichatbotbuilder-greeting-border-width:var(--aichatbotbuilder-container-border-width);'; $css_vars .= '--aichatbotbuilder-greeting-border-radius:var(--aichatbotbuilder-container-border-radius);'; // Launcher defaults for non-custom presets $css_vars .= '--aichatbotbuilder-launcher-bg-color:var(--aichatbotbuilder-button-bg-color);'; // Header color from button color $css_vars .= '--aichatbotbuilder-header-bg-color:var(--aichatbotbuilder-button-bg-color,#de4452);'; $css_vars .= '--aichatbotbuilder-header-text-color:#fff;'; // Typing indicator fallback to bot text color $css_vars .= '--aichatbotbuilder-typing-color:var(--aichatbotbuilder-bot-text-color);'; } if ($container_max_width) { $css_vars .= '--aichatbotbuilder-container-max-width:' . intval($container_max_width) . 'px;'; } if ($container_min_height) { $css_vars .= '--aichatbotbuilder-container-min-height:' . intval($container_min_height) . 'px;'; } if ($z_index) { $css_vars .= '--aichatbotbuilder-z-index:' . esc_attr($z_index) . ';'; } // Container classes and styles $position_class = $position ? ' aichatbotbuilder-position-' . esc_attr($position) : ''; // Escape late: $css_vars is output in an HTML attribute context. $style_attr = $css_vars ? ' style="' . esc_attr($css_vars) . '"' : ''; // Add unique instance class for custom CSS targeting $instance_class = ' aichatbotbuilder-chat-instance-' . esc_attr($chat_id); // Wrap chat in launcher-enabled wrapper $open_class = '1' === $launcher_enabled ? '' : ' open'; if ('inline' === $position) { $launcher_pos_class = ''; } else { $launcher_pos_class = ' aichatbotbuilder-launcher-pos-' . esc_attr($launcher_position); } $html = '
'; // close widget-wrapper return $html; } /** * Handles AJAX request to send message to OpenAI. */ public function handle_ajax_send_message(): void { check_ajax_referer('aichatbotbuilder_send_message_nonce', 'nonce'); $message = isset($_POST['message']) ? sanitize_text_field(wp_unslash($_POST['message'])) : ''; if (empty($message)) { wp_send_json_error(array('message' => esc_html__('Message cannot be empty.', 'ai-chatbot-builder'))); } $opts = get_option($this->option_name); $api_key = $opts['openai_api_key'] ?? ''; $model = $opts['openai_model'] ?? 'gpt-4o'; // Determine initial prompt from chat instance. $chat_id = isset($_POST['chat_id']) ? absint(wp_unslash($_POST['chat_id'])) : 0; $initial_prompt = $chat_id ? get_post_meta($chat_id, 'aichatbotbuilder_initial_prompt', true) : ''; $system_content = $initial_prompt ? $initial_prompt : 'You are a helpful assistant.'; // Collect history if provided and sanitize each entry. $history = array(); if (isset($_POST['history']) && $opts) { // Unsplash and sanitize JSON input $history_json = sanitize_textarea_field(wp_unslash($_POST['history'])); $decoded = json_decode($history_json, true); if (is_array($decoded)) { foreach ($decoded as $entry) { $role_raw = $entry['role'] ?? ''; $content_raw = $entry['content'] ?? ''; $role = sanitize_key($role_raw); $content = sanitize_text_field($content_raw); if (in_array($role, array('user', 'assistant'), true)) { $history[] = array( 'role' => $role, 'content' => $content, ); } } } } // Enforce daily token limit $daily_limit = isset($opts['daily_token_limit']) ? intval($opts['daily_token_limit']) : 0; $current_usage = $this->get_daily_usage(); if ($daily_limit > 0 && $current_usage >= $daily_limit) { wp_send_json_error(array('message' => esc_html__('Daily token limit reached.', 'ai-chatbot-builder')), 429); } if (empty($api_key)) { wp_send_json_error(array('message' => esc_html__('API key is not set in the settings page.', 'ai-chatbot-builder'))); } // Build chat messages array with memory $messages = array(array('role' => 'system', 'content' => $system_content)); if (! empty($history)) { $messages = array_merge($messages, $history); } $messages[] = array('role' => 'user', 'content' => $message); $args = array( 'headers' => array( 'Authorization' => 'Bearer ' . $api_key, 'Content-Type' => 'application/json', ), 'body' => wp_json_encode(array('model' => $model, 'messages' => $messages)), 'timeout' => 60, ); $response = wp_remote_post('https://api.openai.com/v1/chat/completions', $args); if (is_wp_error($response)) { wp_send_json_error(array('message' => $response->get_error_message())); } $code = wp_remote_retrieve_response_code($response); $body = wp_remote_retrieve_body($response); $data = json_decode($body, true); if (200 !== $code || empty($data['choices'][0]['message']['content'])) { wp_send_json_error(array('message' => esc_html__('Error retrieving response from API.', 'ai-chatbot-builder'))); } // Update daily usage count if (isset($data['usage']['total_tokens'])) { $this->increment_daily_usage(intval($data['usage']['total_tokens'])); } $reply = $data['choices'][0]['message']['content']; // Prepare usage data for response $current_usage = $this->get_daily_usage(); $daily_limit = isset($opts['daily_token_limit']) ? intval($opts['daily_token_limit']) : 0; wp_send_json_success( array( 'reply' => wp_kses_post($reply), 'usage' => array( 'used' => $current_usage, 'limit' => $daily_limit, ), ) ); } }