) // ─── LIVE CHAT DB SETUP ─────────────────────────────────────────────────────── add_action('init', 'cgm_live_chat_db_setup'); function cgm_live_chat_db_setup() { if (get_option('cgm_live_chat_db_v1')) return; global $wpdb; $charset = $wpdb->get_charset_collate(); // Messages table $wpdb->query("CREATE TABLE IF NOT EXISTS wp_cgm_live_messages ( id BIGINT UNSIGNED NOT NULL AUTO_INCREMENT, lead_id BIGINT UNSIGNED NOT NULL, sender ENUM('visitor','agent','system') DEFAULT 'visitor', message LONGTEXT NOT NULL, is_read TINYINT DEFAULT 0, created_at DATETIME DEFAULT CURRENT_TIMESTAMP, PRIMARY KEY (id), KEY lead_id (lead_id) ) $charset;"); // Add chat_mode column to leads table if not exists $cols = $wpdb->get_results("SHOW COLUMNS FROM wp_cgm_chat_leads LIKE 'chat_mode'"); if (empty($cols)) { $wpdb->query("ALTER TABLE wp_cgm_chat_leads ADD COLUMN chat_mode VARCHAR(20) DEFAULT 'ai' AFTER status"); } $cols2 = $wpdb->get_results("SHOW COLUMNS FROM wp_cgm_chat_leads LIKE 'last_visitor_msg'"); if (empty($cols2)) { $wpdb->query("ALTER TABLE wp_cgm_chat_leads ADD COLUMN last_visitor_msg DATETIME NULL AFTER chat_mode"); } update_option('cgm_live_chat_db_v1', '1'); } // ─── LIVE MODE TOGGLE ───────────────────────────────────────────────────────── add_action('wp_ajax_cgm_live_toggle', 'cgm_live_toggle'); function cgm_live_toggle() { $mode = sanitize_text_field($_POST['mode'] ?? 'off'); update_option('cgm_live_chat_mode', $mode); if ($mode === 'on') { update_option('cgm_live_chat_last_activity', time()); } wp_send_json_success(['mode' => $mode]); } add_action('wp_ajax_cgm_live_get_mode', 'cgm_live_get_mode'); add_action('wp_ajax_nopriv_cgm_live_get_mode', 'cgm_live_get_mode'); function cgm_live_get_mode() { $mode = get_option('cgm_live_chat_mode', 'off'); $last = (int) get_option('cgm_live_chat_last_activity', 0); // Auto-off after 10 minutes inactivity if ($mode === 'on' && (time() - $last) > 600) { update_option('cgm_live_chat_mode', 'off'); $mode = 'off'; } wp_send_json_success(['mode' => $mode]); } add_action('wp_ajax_cgm_live_ping', 'cgm_live_ping'); function cgm_live_ping() { update_option('cgm_live_chat_last_activity', time()); wp_send_json_success(); } // ─── VISITOR: SEND MESSAGE ──────────────────────────────────────────────────── add_action('wp_ajax_cgm_visitor_send', 'cgm_visitor_send'); add_action('wp_ajax_nopriv_cgm_visitor_send', 'cgm_visitor_send'); function cgm_visitor_send() { check_ajax_referer('cgm_chat_nonce', 'nonce'); global $wpdb; $lead_id = intval($_POST['lead_id'] ?? 0); $message = sanitize_textarea_field($_POST['message'] ?? ''); if (!$lead_id || !$message) wp_send_json_error('Invalid.'); // Store message $wpdb->insert('wp_cgm_live_messages', [ 'lead_id' => $lead_id, 'sender' => 'visitor', 'message' => $message, 'is_read' => 0, 'created_at' => current_time('mysql'), ]); // Update last visitor message time $wpdb->update('wp_cgm_chat_leads', ['last_visitor_msg' => current_time('mysql')], ['id' => $lead_id]); // Check live mode $mode = get_option('cgm_live_chat_mode', 'off'); if ($mode === 'on') { // Update lead chat_mode to live $wpdb->update('wp_cgm_chat_leads', ['chat_mode' => 'live'], ['id' => $lead_id]); wp_send_json_success(['mode' => 'live', 'message_id' => $wpdb->insert_id]); } else { // AI mode — match answer $match = cgm_match_answer($message); $reply = $match ? $match->answer : "Thank you for your message! I don't have a specific answer for that right now.\n\nPlease contact us directly:\n📧 **info@crossglobemarketing.com**\n📞 **+91 93520-55466**"; $quick_replies = $match ? array_filter(array_map('trim', explode(',', $match->quick_replies))) : ['Contact Us', 'Book a Call']; // Store AI reply $wpdb->insert('wp_cgm_live_messages', [ 'lead_id' => $lead_id, 'sender' => 'agent', 'message' => $reply, 'is_read' => 1, 'created_at' => current_time('mysql'), ]); wp_send_json_success([ 'mode' => 'ai', 'reply' => $reply, 'quick_replies' => array_values($quick_replies), ]); } } // ─── VISITOR: POLL FOR NEW MESSAGES ────────────────────────────────────────── add_action('wp_ajax_cgm_visitor_poll', 'cgm_visitor_poll'); add_action('wp_ajax_nopriv_cgm_visitor_poll', 'cgm_visitor_poll'); function cgm_visitor_poll() { check_ajax_referer('cgm_chat_nonce', 'nonce'); global $wpdb; $lead_id = intval($_POST['lead_id'] ?? 0); $last_id = intval($_POST['last_id'] ?? 0); if (!$lead_id) wp_send_json_error(); $messages = $wpdb->get_results($wpdb->prepare( "SELECT * FROM wp_cgm_live_messages WHERE lead_id=%d AND id>%d AND sender='agent' ORDER BY id ASC", $lead_id, $last_id )); // Mark as read if (!empty($messages)) { $wpdb->query($wpdb->prepare( "UPDATE wp_cgm_live_messages SET is_read=1 WHERE lead_id=%d AND sender='agent' AND is_read=0", $lead_id )); } // Check if agent is typing $typing = get_transient('cgm_agent_typing_' . $lead_id); wp_send_json_success([ 'messages' => $messages, 'typing' => (bool) $typing, 'mode' => get_option('cgm_live_chat_mode', 'off'), ]); } // ─── AGENT: GET ALL ACTIVE CHATS ───────────────────────────────────────────── add_action('wp_ajax_cgm_agent_get_chats', 'cgm_agent_get_chats'); function cgm_agent_get_chats() { global $wpdb; $chats = $wpdb->get_results(" SELECT l.id, l.name, l.email, l.phone, l.chat_mode, l.last_visitor_msg, (SELECT COUNT(*) FROM wp_cgm_live_messages m WHERE m.lead_id=l.id AND m.sender='visitor' AND m.is_read=0) as unread, (SELECT message FROM wp_cgm_live_messages m WHERE m.lead_id=l.id ORDER BY m.id DESC LIMIT 1) as last_message, (SELECT created_at FROM wp_cgm_live_messages m WHERE m.lead_id=l.id ORDER BY m.id DESC LIMIT 1) as last_message_time FROM wp_cgm_chat_leads l WHERE l.id IN (SELECT DISTINCT lead_id FROM wp_cgm_live_messages) ORDER BY last_message_time DESC LIMIT 50 "); wp_send_json_success($chats); } // ─── AGENT: GET MESSAGES FOR A CHAT ────────────────────────────────────────── add_action('wp_ajax_cgm_agent_get_messages', 'cgm_agent_get_messages'); function cgm_agent_get_messages() { global $wpdb; $lead_id = intval($_GET['lead_id'] ?? 0); $last_id = intval($_GET['last_id'] ?? 0); if (!$lead_id) wp_send_json_error(); $messages = $wpdb->get_results($wpdb->prepare( "SELECT * FROM wp_cgm_live_messages WHERE lead_id=%d AND id>%d ORDER BY id ASC", $lead_id, $last_id )); // Mark visitor messages as read $wpdb->query($wpdb->prepare( "UPDATE wp_cgm_live_messages SET is_read=1 WHERE lead_id=%d AND sender='visitor' AND is_read=0", $lead_id )); wp_send_json_success($messages); } // ─── AGENT: SEND MESSAGE ────────────────────────────────────────────────────── add_action('wp_ajax_cgm_agent_send', 'cgm_agent_send'); function cgm_agent_send() { global $wpdb; $lead_id = intval($_POST['lead_id'] ?? 0); $message = sanitize_textarea_field($_POST['message'] ?? ''); if (!$lead_id || !$message) wp_send_json_error(); $wpdb->insert('wp_cgm_live_messages', [ 'lead_id' => $lead_id, 'sender' => 'agent', 'message' => $message, 'is_read' => 0, 'created_at' => current_time('mysql'), ]); // Update activity update_option('cgm_live_chat_last_activity', time()); // Clear typing indicator delete_transient('cgm_agent_typing_' . $lead_id); wp_send_json_success(['message_id' => $wpdb->insert_id]); } // ─── AGENT: TYPING INDICATOR ────────────────────────────────────────────────── add_action('wp_ajax_cgm_agent_typing', 'cgm_agent_typing'); function cgm_agent_typing() { $lead_id = intval($_POST['lead_id'] ?? 0); if ($lead_id) set_transient('cgm_agent_typing_' . $lead_id, 1, 5); update_option('cgm_live_chat_last_activity', time()); wp_send_json_success(); } // ─── AGENT: TAKE OVER CHAT ──────────────────────────────────────────────────── add_action('wp_ajax_cgm_agent_takeover', 'cgm_agent_takeover'); function cgm_agent_takeover() { global $wpdb; $lead_id = intval($_POST['lead_id'] ?? 0); if (!$lead_id) wp_send_json_error(); $wpdb->update('wp_cgm_chat_leads', ['chat_mode' => 'live'], ['id' => $lead_id]); // Send system message to visitor $wpdb->insert('wp_cgm_live_messages', [ 'lead_id' => $lead_id, 'sender' => 'agent', 'message' => "You are now connected with a live agent from Cross Globe Marketing. How can I help you?", 'is_read' => 0, 'created_at' => current_time('mysql'), ]); update_option('cgm_live_chat_last_activity', time()); wp_send_json_success(); } // ─── AGENT: HAND BACK TO AI ─────────────────────────────────────────────────── add_action('wp_ajax_cgm_agent_handback', 'cgm_agent_handback'); function cgm_agent_handback() { global $wpdb; $lead_id = intval($_POST['lead_id'] ?? 0); if (!$lead_id) wp_send_json_error(); $wpdb->update('wp_cgm_chat_leads', ['chat_mode' => 'ai'], ['id' => $lead_id]); $wpdb->insert('wp_cgm_live_messages', [ 'lead_id' => $lead_id, 'sender' => 'system', 'message' => "You have been transferred back to our AI assistant. Type your question and I will help you!", 'is_read' => 0, 'created_at' => current_time('mysql'), ]); wp_send_json_success(); } // Store history messages before lead capture add_action('wp_ajax_cgm_store_history_msg', 'cgm_store_history_msg'); add_action('wp_ajax_nopriv_cgm_store_history_msg', 'cgm_store_history_msg'); function cgm_store_history_msg() { global $wpdb; $lead_id = intval($_POST['lead_id'] ?? 0); $sender = sanitize_text_field($_POST['sender'] ?? 'visitor'); $message = sanitize_textarea_field($_POST['message'] ?? ''); if (!$lead_id || !$message) wp_send_json_error(); $wpdb->insert('wp_cgm_live_messages', [ 'lead_id' => $lead_id, 'sender' => in_array($sender, ['visitor','agent','system']) ? $sender : 'visitor', 'message' => $message, 'is_read' => 1, 'created_at' => current_time('mysql'), ]); wp_send_json_success(); } https://crossglobemarketing.com/post-sitemap.xml 2026-06-03T09:00:23+00:00 https://crossglobemarketing.com/page-sitemap.xml 2026-05-19T10:44:02+00:00 https://crossglobemarketing.com/category-sitemap.xml 2026-06-03T09:00:23+00:00 https://crossglobemarketing.com/author-sitemap.xml 2026-04-18T11:01:51+00:00