Changeset 3419567
- Timestamp:
- 12/14/2025 09:18:50 PM (3 months ago)
- Location:
- maio-the-new-ai-geo-seo-tool/trunk
- Files:
-
- 5 added
- 2 edited
-
css/maio_activity.css (added)
-
js/maio_activity.js (added)
-
maio-activity-api.php (added)
-
maio-main.php (modified) (19 diffs)
-
maio_activity.php (added)
-
pages/maio-settings.php (added)
-
readme.txt (modified) (4 diffs)
Legend:
- Unmodified
- Added
- Removed
-
maio-the-new-ai-geo-seo-tool/trunk/maio-main.php
r3376694 r3419567 4 4 * Plugin URI: https://maioai.com 5 5 * Description: This plugin helps optimize your Website for AI-powered discovery tools such as ChatGPT, Perplexity, Claude, Google Gemini, Google AI Overviews, Meta Llama and many more. It combines the best of traditional SEO and emerging AIO strategies to ensure your brand is accurately and favorably represented in AI-generated content. 6 * Version: 5. 2.176 * Version: 5.3.10 7 7 * Requires at least: 5.0 8 8 * Requires PHP: 7.2 … … 16 16 17 17 // Define plugin constants 18 define('MAIO_VERSION', '5. 2.17');18 define('MAIO_VERSION', '5.3.10'); 19 19 define('MAIO_PLUGIN_DIR', plugin_dir_path(__FILE__)); 20 20 define('MAIO_PLUGIN_URL', plugin_dir_url(__FILE__)); 21 21 define('MAIO_NONCE_KEY', 'maio_nonce'); 22 22 23 require_once MAIO_PLUGIN_DIR . 'maio_a nalytics.php';23 require_once MAIO_PLUGIN_DIR . 'maio_activity.php'; 24 24 require_once MAIO_PLUGIN_DIR . 'maio-ai-scanner.php'; 25 require_once MAIO_PLUGIN_DIR . 'maio-a nalytics-api.php'; // REST API endpoints for dashboard25 require_once MAIO_PLUGIN_DIR . 'maio-activity-api.php'; // REST API endpoints for dashboard 26 26 require_once MAIO_PLUGIN_DIR . 'maio-llm-referral-tracking.php'; // LLM referral tracking 27 27 … … 349 349 ); 350 350 351 // Add A nalyticssubmenu (2nd)351 // Add Activity submenu (2nd) 352 352 add_submenu_page( 353 353 'maio-ai-scanner', 354 'A nalytics',355 'A nalytics',354 'Activity', 355 'Activity', 356 356 'manage_options', 357 'maio_a nalytics',358 'maio_a nalytics_page'357 'maio_activity', 358 'maio_activity_page' 359 359 ); 360 360 361 // Add GEO Academy submenu (3rd) 361 // Add Analytics submenu (3rd) 362 add_submenu_page( 363 'maio-ai-scanner', 364 esc_html__('AI Analytics', 'maio-the-new-ai-geo-seo-tool'), 365 esc_html__('AI Analytics', 'maio-the-new-ai-geo-seo-tool'), 366 'manage_options', 367 'maio-analytics', 368 'maio_settings_page' 369 ); 370 371 // Add GEO Academy submenu (4th) 362 372 add_submenu_page( 363 373 'maio-ai-scanner', … … 369 379 ); 370 380 371 // Add About submenu ( 4th)381 // Add About submenu (5th) 372 382 add_submenu_page( 373 383 'maio-ai-scanner', … … 410 420 }); 411 421 422 /** 423 * Make sure bridge token remains within safe limits. 424 */ 425 function maio_sanitize_bridge_token($token) { 426 $option_name = 'maio_plugin_bridge_token'; 427 $current_value = get_option($option_name, ''); 428 429 if (!is_string($token)) { 430 $token = ''; 431 } 432 433 $token = trim(wp_unslash($token)); 434 435 // Check if this is an intentional deletion (from the delete button) 436 // phpcs:ignore WordPress.Security.NonceVerification.Missing -- Handled by settings_fields() 437 $is_delete_intent = isset($_POST['maio_delete_token_intent']) && sanitize_text_field(wp_unslash($_POST['maio_delete_token_intent'])) === '1'; 438 439 if ($token === '') { 440 // Allow empty value if it's an intentional deletion 441 if ($is_delete_intent) { 442 return ''; // Allow deletion 443 } 444 445 // Otherwise, show error and keep current value 446 add_settings_error( 447 'maio_settings_token_group', 448 'maio_token_empty', 449 esc_html__('Token field cannot be empty. Paste the token from the MAIO website dashboard.', 'maio-the-new-ai-geo-seo-tool'), 450 'error' 451 ); 452 return $current_value; 453 } 454 455 if (!preg_match('/^[0-9a-f]{64}$/', $token)) { 456 add_settings_error( 457 'maio_settings_token_group', 458 'maio_token_format', 459 esc_html__('Token format is invalid. Token must be exactly as issued in the MAIO website dashboard.', 'maio-the-new-ai-geo-seo-tool'), 460 'error' 461 ); 462 return $current_value; 463 } 464 465 return sanitize_text_field($token); 466 } 467 468 /** 469 * Determine the base MAIO API URL depending on environment. 470 */ 471 function maio_get_api_base_url() { 472 $env_api_url = getenv('MAIO_API_URL'); 473 if ($env_api_url !== false && !empty($env_api_url)) { 474 return rtrim($env_api_url, '/'); 475 } 476 477 if (defined('MAIO_API_URL')) { 478 return rtrim(MAIO_API_URL, '/'); 479 } 480 481 $hostname = gethostname(); 482 if ($hostname && strpos($hostname, 'maio-wordpress') !== false) { 483 return 'http://maio-api:5000'; 484 } 485 486 $host = isset($_SERVER['HTTP_HOST']) ? sanitize_text_field(wp_unslash($_SERVER['HTTP_HOST'])) : ''; 487 if ( 488 strpos($host, 'localhost') !== false || 489 strpos($host, '127.0.0.1') !== false || 490 strpos($host, '.local') !== false 491 ) { 492 return 'http://localhost:5000'; 493 } 494 495 return 'https://api.maioai.com'; 496 } 497 498 /** 499 * Store a transient notice so the Analytics page can show token status feedback. 500 */ 501 function maio_set_bridge_token_notice($type, $message) { 502 set_transient( 503 'maio_settings_token_notice', 504 array( 505 'type' => $type, 506 'message' => $message, 507 'time' => time(), 508 ), 509 MINUTE_IN_SECONDS 510 ); 511 } 512 513 /** 514 * After the bridge token option changes, notify the MAIO API so the dashboard can trust this site. 515 */ 516 function maio_register_bridge_token_with_api($old_value, $value, $option) { 517 if ($value === $old_value) { 518 return; 519 } 520 521 $token = trim((string) $value); 522 if ($token === '') { 523 // Token is being deleted - notify both Flask API and dashboard 524 $old_token = trim((string) $old_value); 525 526 if ($old_token !== '') { 527 $site_uuid = get_option('maio_site_uuid'); 528 529 // Step 1: Notify Flask API about deletion 530 if ($site_uuid) { 531 $flask_endpoint = rtrim(maio_get_api_base_url(), '/') . '/api/v1/plugin/delete-token'; 532 533 $flask_payload = array( 534 'site_uuid' => $site_uuid, 535 'site_url' => home_url(), 536 ); 537 538 $flask_response = wp_remote_post( 539 $flask_endpoint, 540 array( 541 'method' => 'POST', 542 'timeout' => 10, 543 'headers' => array( 544 'Content-Type' => 'application/json', 545 'X-Install-Token' => 'dummy_plugin_token', 546 ), 547 'body' => wp_json_encode($flask_payload), 548 ) 549 ); 550 551 // Log only errors (best effort - don't block deletion) 552 if (is_wp_error($flask_response)) { 553 error_log('MAIO Token Deletion: Flask API error - ' . $flask_response->get_error_message()); 554 } else { 555 $flask_status = wp_remote_retrieve_response_code($flask_response); 556 if ($flask_status < 200 || $flask_status >= 300) { 557 error_log('MAIO Token Deletion: Flask API returned ' . $flask_status); 558 } 559 } 560 } 561 562 // Step 2: Notify maioai.com dashboard that token is deleted 563 $dashboard_endpoint = 'https://www.maioai.com/api/plugin/token/status'; 564 565 $dashboard_payload = array( 566 'token' => $old_token, 567 'status' => 'deleted', 568 ); 569 570 $dashboard_response = wp_remote_post( 571 $dashboard_endpoint, 572 array( 573 'method' => 'POST', 574 'timeout' => 10, 575 'headers' => array( 576 'Content-Type' => 'application/json', 577 'x-yossi-api-key' => 'yssi_sk_live_abc123xyz789def456ghi012jkl345mno678pqr901stu234vwx567', 578 ), 579 'body' => wp_json_encode($dashboard_payload), 580 ) 581 ); 582 583 // Log only errors (best effort - don't block deletion) 584 if (is_wp_error($dashboard_response)) { 585 error_log('MAIO Token Deletion: Dashboard API error - ' . $dashboard_response->get_error_message()); 586 } else { 587 $dashboard_status = wp_remote_retrieve_response_code($dashboard_response); 588 if ($dashboard_status < 200 || $dashboard_status >= 300) { 589 error_log('MAIO Token Deletion: Dashboard API returned ' . $dashboard_status); 590 } 591 } 592 } 593 594 maio_set_bridge_token_notice( 595 'success', 596 esc_html__('Token deleted successfully. Dashboard access is now disabled.', 'maio-the-new-ai-geo-seo-tool') 597 ); 598 return; 599 } 600 601 $site_uuid = get_option('maio_site_uuid'); 602 if (!$site_uuid) { 603 $site_uuid = wp_generate_uuid4(); 604 update_option('maio_site_uuid', $site_uuid); 605 } 606 607 // Step 1: Register with Flask API (for analytics broker) 608 $flask_endpoint = rtrim(maio_get_api_base_url(), '/') . '/api/v1/plugin/register-token'; 609 610 $flask_payload = array( 611 'site_uuid' => $site_uuid, 612 'site_url' => home_url(), 613 'plugin_version' => defined('MAIO_VERSION') ? MAIO_VERSION : 'dev', 614 'wp_version' => get_bloginfo('version'), 615 'php_version' => phpversion(), 616 'bridge_token' => $token, 617 ); 618 619 $flask_response = wp_remote_post( 620 $flask_endpoint, 621 array( 622 'method' => 'POST', 623 'timeout' => 10, 624 'headers' => array( 625 'Content-Type' => 'application/json', 626 'X-Install-Token' => 'dummy_plugin_token', 627 ), 628 'body' => wp_json_encode($flask_payload), 629 ) 630 ); 631 632 if (is_wp_error($flask_response)) { 633 error_log('MAIO Token Registration Error: Flask API - ' . $flask_response->get_error_message()); 634 maio_set_bridge_token_notice( 635 'error', 636 sprintf( 637 /* translators: %s: error message */ 638 esc_html__('Could not register token with MAIO API: %s', 'maio-the-new-ai-geo-seo-tool'), 639 esc_html($flask_response->get_error_message()) 640 ) 641 ); 642 return; 643 } 644 645 $flask_status = wp_remote_retrieve_response_code($flask_response); 646 $flask_body = wp_remote_retrieve_body($flask_response); 647 $flask_decoded = json_decode($flask_body, true); 648 649 if ($flask_status < 200 || $flask_status >= 300) { 650 error_log('MAIO Token Registration Error: Flask API returned ' . $flask_status . ' - ' . $flask_body); 651 $error_message = isset($flask_decoded['error']) ? $flask_decoded['error'] : $flask_body; 652 if (!is_string($error_message) || $error_message === '') { 653 $error_message = esc_html__('Unexpected response from MAIO API.', 'maio-the-new-ai-geo-seo-tool'); 654 } 655 656 maio_set_bridge_token_notice( 657 'error', 658 sprintf( 659 /* translators: %s: error message */ 660 esc_html__('Token save failed: %s', 'maio-the-new-ai-geo-seo-tool'), 661 esc_html($error_message) 662 ) 663 ); 664 return; 665 } 666 667 // Step 2: Notify maioai.com dashboard that token is configured 668 $dashboard_endpoint = 'https://www.maioai.com/api/plugin/token/status'; 669 670 $dashboard_payload = array( 671 'token' => $token, 672 'status' => 'configured', 673 ); 674 675 $dashboard_response = wp_remote_post( 676 $dashboard_endpoint, 677 array( 678 'method' => 'POST', 679 'timeout' => 10, 680 'headers' => array( 681 'Content-Type' => 'application/json', 682 'x-yossi-api-key' => 'yssi_sk_live_abc123xyz789def456ghi012jkl345mno678pqr901stu234vwx567', 683 ), 684 'body' => wp_json_encode($dashboard_payload), 685 ) 686 ); 687 688 if (is_wp_error($dashboard_response)) { 689 error_log('MAIO Token Registration Error: Dashboard API - ' . $dashboard_response->get_error_message()); 690 maio_set_bridge_token_notice( 691 'warning', 692 sprintf( 693 /* translators: %s: error message */ 694 esc_html__('Token registered with API but dashboard notification failed: %s', 'maio-the-new-ai-geo-seo-tool'), 695 esc_html($dashboard_response->get_error_message()) 696 ) 697 ); 698 return; 699 } 700 701 $dashboard_status = wp_remote_retrieve_response_code($dashboard_response); 702 $dashboard_body = wp_remote_retrieve_body($dashboard_response); 703 $dashboard_decoded = json_decode($dashboard_body, true); 704 705 if ($dashboard_status >= 200 && $dashboard_status < 300) { 706 maio_set_bridge_token_notice( 707 'success', 708 esc_html__('Token registered successfully. You can now view analytics on the MAIO dashboard.', 'maio-the-new-ai-geo-seo-tool') 709 ); 710 return; 711 } 712 713 // Dashboard notification failed but Flask registration succeeded 714 $dashboard_error = isset($dashboard_decoded['error']) ? $dashboard_decoded['error'] : 715 (isset($dashboard_decoded['message']) ? $dashboard_decoded['message'] : 'Unknown error'); 716 717 error_log('MAIO Token Registration Error: Dashboard API returned ' . $dashboard_status . ' - ' . $dashboard_error); 718 719 maio_set_bridge_token_notice( 720 'warning', 721 sprintf( 722 /* translators: %s: error message */ 723 esc_html__('Token registered with API but dashboard returned: %s (Status: %d)', 'maio-the-new-ai-geo-seo-tool'), 724 esc_html($dashboard_error), 725 $dashboard_status 726 ) 727 ); 728 } 729 // Hook for updating existing token 730 add_action('update_option_maio_plugin_bridge_token', 'maio_register_bridge_token_with_api', 10, 3); 731 732 // Hook for adding NEW token (first time save) 733 add_action('add_option_maio_plugin_bridge_token', function($option, $value) { 734 // Call the same function but with empty old value 735 maio_register_bridge_token_with_api('', $value, $option); 736 }, 10, 2); 737 412 738 // Register settings 413 739 add_action('admin_init', function() { … … 619 945 'type' => 'string', 620 946 'sanitize_callback' => 'sanitize_textarea_field', 947 'default' => '' 948 )); 949 950 // Settings submenu: token for plugin ↔ dashboard bridge 951 register_setting('maio_settings_token_group', 'maio_plugin_bridge_token', array( 952 'type' => 'string', 953 'sanitize_callback' => 'maio_sanitize_bridge_token', 621 954 'default' => '' 622 955 )); … … 635 968 636 969 /** 637 * A nalyticspage content970 * Activity page content 638 971 */ 639 function maio_a nalytics_page() {972 function maio_activity_page() { 640 973 if (!current_user_can('manage_options')) { 641 974 return; … … 644 977 // Output the page wrapper 645 978 ?> 646 <div class="wrap maio_a nalytics_wrapper">647 <h1>MAIO A nalytics</h1>648 <?php do_action('maio_a nalytics_page_content'); ?>979 <div class="wrap maio_activity_wrapper"> 980 <h1>MAIO Activity</h1> 981 <?php do_action('maio_activity_page_content'); ?> 649 982 </div> 650 983 <?php … … 669 1002 // Include the AI-friendly article page 670 1003 require_once MAIO_PLUGIN_DIR . 'articles/maio-ai-friendly-article.php'; 1004 } 1005 1006 // Analytics page callback 1007 function maio_settings_page() { 1008 if (!current_user_can('manage_options')) { 1009 return; 1010 } 1011 1012 require_once MAIO_PLUGIN_DIR . 'pages/maio-settings.php'; 671 1013 } 672 1014 … … 1863 2205 1864 2206 // Verify nonce 1865 if (!isset($_POST['maio_nonce']) || !wp_verify_nonce(sanitize_key($_POST['maio_nonce']), 'maio_a nalytics_nonce')) {2207 if (!isset($_POST['maio_nonce']) || !wp_verify_nonce(sanitize_key($_POST['maio_nonce']), 'maio_activity_nonce')) { 1866 2208 wp_send_json_error('Invalid nonce'); 1867 2209 return ''; … … 1908 2250 1909 2251 // Verify nonce 1910 if (!isset($_POST['maio_nonce']) || !wp_verify_nonce(sanitize_key($_POST['maio_nonce']), 'maio_a nalytics_nonce')) {2252 if (!isset($_POST['maio_nonce']) || !wp_verify_nonce(sanitize_key($_POST['maio_nonce']), 'maio_activity_nonce')) { 1911 2253 wp_send_json_error('Invalid nonce'); 1912 2254 return; … … 2011 2353 } 2012 2354 2013 // Add nonce field to the a nalyticspage2014 function maio_add_a nalytics_nonce() {2015 wp_nonce_field('maio_a nalytics_nonce', 'maio_nonce');2355 // Add nonce field to the activity page 2356 function maio_add_activity_nonce() { 2357 wp_nonce_field('maio_activity_nonce', 'maio_nonce'); 2016 2358 } 2017 add_action('admin_footer-maio_page_maio_a nalytics', 'maio_add_analytics_nonce');2018 2019 // Cypress/Testing: AJAX endpoint to reset all MAIO a nalytics/statistics (for test isolation)2020 add_action('wp_ajax_maio_reset_a nalytics', function() {2359 add_action('admin_footer-maio_page_maio_activity', 'maio_add_activity_nonce'); 2360 2361 // Cypress/Testing: AJAX endpoint to reset all MAIO activity/statistics (for test isolation) 2362 add_action('wp_ajax_maio_reset_activity', function() { 2021 2363 if (!current_user_can('manage_options')) wp_die('forbidden'); 2022 2364 global $wpdb; … … 2026 2368 // Clear relevant caches 2027 2369 wp_cache_flush(); 2028 wp_send_json_success('A nalyticstable truncated.');2370 wp_send_json_success('Activity table truncated.'); 2029 2371 }); 2030 2372 … … 2035 2377 2036 2378 // Check nonce 2037 if (!isset($_POST['maio_nonce']) || !wp_verify_nonce(sanitize_text_field(wp_unslash($_POST['maio_nonce'])), 'maio_a nalytics_nonce')) {2379 if (!isset($_POST['maio_nonce']) || !wp_verify_nonce(sanitize_text_field(wp_unslash($_POST['maio_nonce'])), 'maio_activity_nonce')) { 2038 2380 wp_send_json_error('Invalid nonce', 400); 2039 2381 } … … 2071 2413 2072 2414 // Check nonce 2073 if (!isset($_POST['maio_nonce']) || !wp_verify_nonce(sanitize_text_field(wp_unslash($_POST['maio_nonce'])), 'maio_a nalytics_nonce')) {2415 if (!isset($_POST['maio_nonce']) || !wp_verify_nonce(sanitize_text_field(wp_unslash($_POST['maio_nonce'])), 'maio_activity_nonce')) { 2074 2416 wp_send_json_error('Invalid nonce', 400); 2075 2417 } … … 2106 2448 2107 2449 // Check nonce 2108 if (!isset($_POST['nonce']) || !wp_verify_nonce(sanitize_text_field(wp_unslash($_POST['nonce'])), 'maio_a nalytics_nonce')) {2450 if (!isset($_POST['nonce']) || !wp_verify_nonce(sanitize_text_field(wp_unslash($_POST['nonce'])), 'maio_activity_nonce')) { 2109 2451 wp_send_json_error('Invalid nonce', 400); 2110 2452 } … … 2137 2479 2138 2480 // Check nonce 2139 if (!isset($_POST['maio_nonce']) || !wp_verify_nonce(sanitize_text_field(wp_unslash($_POST['maio_nonce'])), 'maio_a nalytics_nonce')) {2481 if (!isset($_POST['maio_nonce']) || !wp_verify_nonce(sanitize_text_field(wp_unslash($_POST['maio_nonce'])), 'maio_activity_nonce')) { 2140 2482 wp_send_json_error('Invalid nonce', 400); 2141 2483 } … … 2301 2643 // For logged-in users, require nonce 2302 2644 if (is_user_logged_in()) { 2303 if (!isset($_POST['maio_nonce']) || !wp_verify_nonce(sanitize_text_field(wp_unslash($_POST['maio_nonce'])), 'maio_a nalytics_nonce')) {2645 if (!isset($_POST['maio_nonce']) || !wp_verify_nonce(sanitize_text_field(wp_unslash($_POST['maio_nonce'])), 'maio_activity_nonce')) { 2304 2646 wp_send_json_error('Invalid nonce', 400); 2305 2647 return; … … 2335 2677 add_action('wp_ajax_maio_get_nonce', function() { 2336 2678 if (!current_user_can('manage_options')) wp_send_json_error('forbidden', 403); 2337 wp_send_json_success(['nonce' => wp_create_nonce('maio_a nalytics_nonce')]);2679 wp_send_json_success(['nonce' => wp_create_nonce('maio_activity_nonce')]); 2338 2680 }); 2339 2681 -
maio-the-new-ai-geo-seo-tool/trunk/readme.txt
r3376694 r3419567 1 1 === MAIO - The new AI GEO / SEO tool === 2 2 Contributors: ashleysmith1 3 Tags: geo, seo, ai, chatgpt, google ai overviews3 Tags: ai, ai seo, chatgpt, claude, gemini 4 4 Requires at least: 5.0 5 5 Tested up to: 6.8.2 6 Stable tag: 5. 2.176 Stable tag: 5.3.10 7 7 License: GPLv2 or later 8 8 License URI: http://www.gnu.org/licenses/gpl-2.0.html 9 9 10 This plugin helps Optimize your website for AI-powered discovery tools like ChatGPT, Perplexity, Claude, Gemini, and more. AI SEOfor the future.10 This plugin helps optimize your website for AI-powered discovery tools like ChatGPT, Perplexity, Claude, Gemini, and more. AI GEO (Generative Engine Optimization) for the future. 11 11 12 12 == Description == 13 13 14 This plugin helps optimize your Website for AI-powered discovery tools such as ChatGPT (OpenAI), Perplexity, Claude (Anthropic), Google Gemini, Meta AI, and more. It combines the best of traditional SEO and emerging AIO strategies to ensure your brand is accurately and favorably represented in AI-generated content. MAIO now includes advanced analytics and detection for the latest AI bots14 This plugin helps optimize your Website for AI-powered discovery tools such as ChatGPT (OpenAI), Perplexity, Claude (Anthropic), Google Gemini, Meta AI, and more. MAIO focuses on AI GEO (Generative Engine Optimization) strategies to ensure your brand is accurately and favorably represented in AI-generated content. The plugin includes advanced analytics and detection for the latest AI bots and LLM crawlers 15 15 16 16 == Installation == … … 18 18 1. Upload the plugin files to the `/wp-content/plugins/maio-the-new-ai-geo-seo-tool` directory, or install the plugin through the WordPress plugins screen directly. 19 19 2. Activate the plugin through the 'Plugins' screen in WordPress 20 3. Use the Settings->MAIO screen to configure the plugin20 3. That's it! MAIO works out of the box with no configuration needed 21 21 22 22 == Frequently Asked Questions == … … 24 24 = What is MAIO? = 25 25 26 MAIO is a WordPress plugin that helps optimize your website for AI-powered discovery tools. It combines traditional SEO with AI-specific optimization strategies, and now includes analytics and detection for the latest AI and LLM crawlers and user-initiated fetchers.26 MAIO is a WordPress plugin that helps optimize your website for AI-powered discovery tools. It focuses on AI GEO (Generative Engine Optimization) strategies to ensure your content is discoverable and accurately represented by AI systems. The plugin includes advanced analytics and detection for the latest AI and LLM crawlers. 27 27 28 28 = How does MAIO work? = 29 29 30 MAIO adds structured data and metadata to your website that helps AI tools better understand and represent your content. It also detects and logs visits from major AI bots, including:31 * OpenAI 30 MAIO optimizes your website for AI discovery by adding structured signals that help AI tools accurately understand and represent your content. The plugin automatically tracks engagement from major AI systems, including: 31 * OpenAI ChatGPT 32 32 * Anthropic Claude 33 33 * Perplexity AI … … 35 35 * Meta AI 36 36 37 The plugin is extensible, so you can add detection for new AI bots as they appear.37 MAIO provides real-time analytics showing which AI systems are discovering your content, what pages they're indexing, and how your brand appears in AI-generated responses. 38 38 39 39 == Changelog == 40 = 5.3.10 = 41 * Added AI Analytics submenu for MAIO web dashboard integration 42 * Analytics Dashboard Access - Direct link to view website analytics on maioai.com 40 43 41 44 = 5.2.17 =
Note: See TracChangeset
for help on using the changeset viewer.