=' ); } /** @return array */ public function get_status() { $status = array( 'available' => shortcode_exists( 'aimogen-chat-form' ), 'api_version' => self::API_VERSION, 'edition' => defined( 'AIMOGEN_IS_PRO' ) ? 'pro' : 'free', 'plugin_version' => function_exists( 'aimogen_get_version' ) ? aimogen_get_version() : '', 'pro_plugin_version' => function_exists( 'aimogenpro_get_version' ) ? aimogenpro_get_version() : '', ); return apply_filters( 'aimogen_integration_status', $status, $this ); } /** @return array */ public function get_capabilities() { $capabilities = array( 'chat' => shortcode_exists( 'aimogen-chat-form' ), 'chatbots' => true, 'text' => false, 'images' => false, 'embeddings' => false, 'knowledge_bases' => false, 'streaming' => true, 'voice' => false, 'persistent_chat' => false, 'lead_capture' => false, 'workflows' => false, 'agents' => false, 'automation' => false, 'provider_management' => false, 'usage_controls' => false, ); $capabilities = apply_filters( 'aimogen_integration_capabilities', $capabilities, $this ); $normalized = array(); foreach ( (array) $capabilities as $capability => $supported ) { $key = sanitize_key( $capability ); if ( '' !== $key ) { $normalized[ $key ] = (bool) $supported; } } return $normalized; } /** @param string $capability Capability name. @return bool */ public function supports( $capability ) { $capabilities = $this->get_capabilities(); $capability = sanitize_key( $capability ); return ! empty( $capabilities[ $capability ] ); } /** * Return normalized chatbots available to the active Aimogen renderer. * * @return array> */ public function get_chatbots() { $chatbots = array( array( 'id' => 'default', 'title' => __( 'Aimogen Chatbot', 'aimogen' ), 'description' => __( 'Uses the chatbot configured in Aimogen.', 'aimogen' ), 'avatar' => '', 'source' => 'aimogen-free', ), ); $chatbots = apply_filters( 'aimogen_integration_chatbots', $chatbots, $this ); return $this->normalize_resources( $chatbots, false ); } /** * Backward-compatible alias for early integration consumers. * * @deprecated 1.1.0 Use get_chatbots(). * @return array> */ public function get_assistants() { return $this->get_chatbots(); } /** * Extensible resource discovery for future approved integrations. * * Supported resource types are intentionally filter-driven. Aimogen Pro can * expose knowledge bases or workflows without changing the public contract. * * @param string $type Resource type. * @return array> */ public function get_resources( $type ) { $type = sanitize_key( $type ); $resources = apply_filters( 'aimogen_integration_resources_' . $type, array(), $this ); return $this->normalize_resources( $resources, false ); } /** * Render an approved chatbot instance through Aimogen's registered shortcode. * * @param string $chatbot_id Chatbot ID. * @param array $args Approved presentation and feature arguments. * @return string|WP_Error */ public function render_chatbot( $chatbot_id = 'default', $args = array() ) { if ( ! $this->supports( 'chat' ) || ! shortcode_exists( 'aimogen-chat-form' ) ) { return new WP_Error( 'aimogen_chat_unavailable', __( 'Aimogen chat is not available.', 'aimogen' ) ); } $chatbot_id = sanitize_key( (string) $chatbot_id ); $chatbot_id = '' === $chatbot_id ? 'default' : $chatbot_id; $valid_ids = wp_list_pluck( $this->get_chatbots(), 'id' ); if ( ! in_array( $chatbot_id, $valid_ids, true ) ) { return new WP_Error( 'aimogen_invalid_chatbot', __( 'The selected Aimogen chatbot is not available.', 'aimogen' ) ); } $approved = $this->sanitize_chatbot_args( (array) $args ); global $shortcode_tags; $callback = isset( $shortcode_tags['aimogen-chat-form'] ) ? $shortcode_tags['aimogen-chat-form'] : null; if ( ! is_callable( $callback ) ) { return new WP_Error( 'aimogen_chat_unavailable', __( 'Aimogen chat is not available.', 'aimogen' ) ); } $buffer_level = ob_get_level(); try { ob_start(); $result = call_user_func( $callback, $approved, null, 'aimogen-chat-form' ); $captured = ob_get_clean(); } catch ( Throwable $error ) { while ( ob_get_level() > $buffer_level ) { ob_end_clean(); } return new WP_Error( 'aimogen_chat_render_failed', __( 'Aimogen could not render this chatbot.', 'aimogen' ) ); } return (string) $captured . ( is_string( $result ) ? $result : '' ); } /** @param string $area Admin destination. @return string */ public function get_admin_url( $area = 'chatbot' ) { $chatbot_url = admin_url( 'admin.php?page=aimogen_chatbot_panel' ); $urls = array( 'chatbot' => $chatbot_url, 'assistants' => $chatbot_url, 'settings' => admin_url( 'admin.php?page=aimogen_admin_settings' ), ); $urls = apply_filters( 'aimogen_integration_admin_urls', $urls, $this ); $area = sanitize_key( $area ); return isset( $urls[ $area ] ) ? esc_url_raw( $urls[ $area ] ) : ''; } /** @param array $args Raw arguments. @return array */ private function sanitize_chatbot_args( $args ) { $output = array(); $text_limits = array( 'ai_first_message' => 600, 'placeholder' => 180, 'submit' => 80, 'ai_name' => 120, 'ai_role' => 120, ); foreach ( $text_limits as $key => $limit ) { if ( isset( $args[ $key ] ) ) { $output[ $key ] = $this->limit( sanitize_text_field( $args[ $key ] ), $limit ); } } foreach ( array( 'ai_avatar', 'user_avatar' ) as $key ) { if ( ! empty( $args[ $key ] ) ) { $output[ $key ] = esc_url_raw( $args[ $key ] ); } } $enums = array( 'show_in_window' => array( 'on', 'off' ), 'window_location' => array( 'bottom-right', 'bottom-left', 'top-right', 'top-left' ), 'show_header' => array( 'show', 'hide' ), 'show_ai_avatar' => array( 'show', 'hide' ), 'show_user_avatar' => array( 'show', 'hide' ), 'bubble_alignment' => array( 'left', 'center', 'right' ), 'bubble_user_alignment'=> array( 'left', 'center', 'right' ), ); foreach ( $enums as $key => $allowed ) { if ( isset( $args[ $key ] ) && in_array( (string) $args[ $key ], $allowed, true ) ) { $output[ $key ] = (string) $args[ $key ]; } } foreach ( array( 'background', 'general_background', 'user_font_color', 'user_background_color', 'ai_font_color', 'ai_background_color', 'input_text_color', 'input_placeholder_color', 'input_border_color', 'submit_color', 'submit_text_color' ) as $key ) { if ( isset( $args[ $key ] ) ) { $color = sanitize_hex_color( $args[ $key ] ); if ( $color ) { $output[ $key ] = $color; } } } foreach ( array( 'font_size', 'height', 'minheight', 'width', 'bubble_width' ) as $key ) { if ( isset( $args[ $key ] ) && preg_match( '/^(?:\d+(?:\.\d+)?)(?:px|%|em|rem|vh|vw)$/', (string) $args[ $key ] ) ) { $output[ $key ] = (string) $args[ $key ]; } } if ( $this->supports( 'persistent_chat' ) && isset( $args['persistent'] ) && in_array( $args['persistent'], array( 'off', 'on', 'history', 'logs' ), true ) ) { $output['persistent'] = $args['persistent']; } if ( $this->supports( 'embeddings' ) ) { if ( isset( $args['embeddings'] ) && in_array( $args['embeddings'], array( 'enabled', 'disabled' ), true ) ) { $output['embeddings'] = $args['embeddings']; } if ( ! empty( $args['embeddings_namespace'] ) ) { $output['embeddings_namespace'] = $this->limit( sanitize_text_field( $args['embeddings_namespace'] ), 190 ); } } if ( $this->supports( 'lead_capture' ) && isset( $args['store_data'] ) && in_array( $args['store_data'], array( 'on', 'off' ), true ) ) { $output['store_data'] = $args['store_data']; } if ( $this->supports( 'voice' ) && isset( $args['chatbot_text_speech'] ) && in_array( $args['chatbot_text_speech'], array( '', 'off', 'free' ), true ) ) { $output['chatbot_text_speech'] = $args['chatbot_text_speech']; } return apply_filters( 'aimogen_integration_chatbot_args', $output, $args, $this ); } /** @param array $resources Resources. @param bool $allow_default Whether an empty ID is valid. @return array> */ private function normalize_resources( $resources, $allow_default ) { $output = array(); $seen = array(); foreach ( (array) $resources as $resource ) { if ( ! is_array( $resource ) || ! array_key_exists( 'id', $resource ) || empty( $resource['title'] ) ) { continue; } $id = sanitize_text_field( (string) $resource['id'] ); if ( '' === $id && ! $allow_default ) { continue; } if ( isset( $seen[ $id ] ) ) { continue; } $seen[ $id ] = true; $output[] = array( 'id' => $id, 'title' => sanitize_text_field( $resource['title'] ), 'description' => isset( $resource['description'] ) ? sanitize_text_field( $resource['description'] ) : '', 'avatar' => isset( $resource['avatar'] ) ? esc_url_raw( $resource['avatar'] ) : '', 'source' => isset( $resource['source'] ) ? sanitize_key( $resource['source'] ) : 'aimogen', ); } return $output; } /** @param string $value Value. @param int $maximum Maximum length. @return string */ private function limit( $value, $maximum ) { return function_exists( 'mb_substr' ) ? mb_substr( (string) $value, 0, $maximum ) : substr( (string) $value, 0, $maximum ); } } } if ( ! function_exists( 'aimogen_integration' ) ) { /** @return Aimogen_Integration_API */ function aimogen_integration() { return Aimogen_Integration_API::instance(); } } add_action( 'plugins_loaded', static function () { do_action( 'aimogen_integration_ready', aimogen_integration() ); }, 25 );