base_url ) . ltrim( $endpoint, '/' ); $args = array( 'method' => $method, 'timeout' => 20, 'headers' => array( 'Content-Type' => 'application/json', ), ); if ( ! empty( $token ) ) { // Backend middleware expects raw JWT in Authorization header. $args['headers']['Authorization'] = sanitize_text_field( $token ); } if ( ! empty( $body ) ) { $args['body'] = wp_json_encode( $body ); } $response = wp_remote_request( $url, $args ); if ( is_wp_error( $response ) ) { return array( 'success' => false, 'code' => 0, 'message' => $response->get_error_message(), 'data' => array(), ); } $code = (int) wp_remote_retrieve_response_code( $response ); $raw = wp_remote_retrieve_body( $response ); $data = json_decode( $raw, true ); if ( ! is_array( $data ) ) { $data = array(); } $success = $code >= 200 && $code < 300; $message = isset( $data['message'] ) ? sanitize_text_field( $data['message'] ) : ''; if ( ! empty( $data['error'] ) && is_string( $data['error'] ) ) { $error_text = sanitize_text_field( $data['error'] ); if ( empty( $message ) || 'Bad Request' === $message || 'Request failed.' === $message ) { $message = $error_text; } } if ( empty( $message ) ) { $message = $success ? 'Request successful.' : 'Request failed.'; } return array( 'success' => $success, 'code' => $code, 'message' => $message, 'data' => $data, ); } public function sign_in( $email, $password ) { return $this->request( 'POST', 'auth/signIn', array( 'email' => sanitize_email( $email ), 'password' => (string) $password, ) ); } public function sign_up( $name, $email, $password, $phone, $store_url, $store_name = '' ) { $body = array( 'name' => sanitize_text_field( $name ), 'email' => sanitize_email( $email ), 'phone' => sanitize_text_field( $phone ), 'password' => (string) $password, 'storeUrl' => esc_url_raw( $store_url ), ); if ( ! empty( $store_name ) ) { $body['storeName'] = sanitize_text_field( $store_name ); } return $this->request( 'POST', 'auth/signUp', $body ); } public function verify_email_otp( $email, $otp ) { $otp_value = sanitize_text_field( $otp ); if ( ctype_digit( $otp_value ) ) { $otp_value = (int) $otp_value; } return $this->request( 'POST', 'auth/verifyEmail', array( 'email' => sanitize_email( $email ), 'otp' => $otp_value, ) ); } public function resend_otp( $email ) { return $this->request( 'POST', 'auth/sendOtp', array( 'email' => sanitize_email( $email ), ) ); } public function reset_password( $email, $password, $confirm_password ) { return $this->request( 'POST', 'auth/resetPassword', array( 'email' => sanitize_email( $email ), 'password' => (string) $password, 'confirmPassword' => (string) $confirm_password, ) ); } public function fetch_chatbot_config( $email, $token ) { $email = sanitize_email( $email ); $candidates = array( array( 'GET', 'chatbot', array() ), array( 'POST', 'chatbot/config', array( 'email' => $email ) ), array( 'POST', 'chatbot/get-config', array( 'email' => $email ) ), array( 'GET', 'chatbot/config?email=' . rawurlencode( $email ), array() ), array( 'GET', 'chatbot/get-config?email=' . rawurlencode( $email ), array() ), ); $response = array( 'success' => false, 'code' => 0, 'message' => 'Config endpoint not reachable.', 'data' => array(), ); foreach ( $candidates as $candidate ) { $attempt = $this->request( $candidate[0], $candidate[1], $candidate[2], $token ); if ( $attempt['success'] ) { $response = $attempt; break; } $response = $attempt; } $payload = isset( $response['data']['data'] ) && is_array( $response['data']['data'] ) ? $response['data']['data'] : $response['data']; $embed_token = ''; if ( isset( $payload['chatbotToken'] ) ) { $embed_token = sanitize_text_field( $payload['chatbotToken'] ); } elseif ( isset( $payload['token'] ) ) { $embed_token = sanitize_text_field( $payload['token'] ); } elseif ( isset( $payload['secretKey'] ) ) { $embed_token = sanitize_text_field( $payload['secretKey'] ); } $script_url = ''; if ( ! empty( $payload['scriptUrl'] ) ) { $script_url = esc_url_raw( $payload['scriptUrl'] ); } $onboarding_url = ''; if ( ! empty( $payload['onboardingUrl'] ) ) { $onboarding_url = esc_url_raw( $payload['onboardingUrl'] ); } $response['normalized'] = array( 'chatbot_embed_token' => $embed_token, 'chatbot_script_url' => $script_url, 'onboarding_url' => $onboarding_url, ); /* if ( empty( $response['normalized']['chatbot_embed_token'] ) ) { $response['normalized']['chatbot_embed_token'] = sanitize_text_field( $token ); } */ return $response; } public function connect_woocommerce( $consumer_key, $consumer_secret, $store_url ) { $settings = get_option( 'recomai_settings' ); $token = ! empty( $settings['api_token'] ) ? $settings['api_token'] : ''; return $this->request( 'POST', 'woocommerce/connect', array( 'WC_BASE_URL' => esc_url_raw( $store_url ), 'WC_CONSUMER_KEY' => sanitize_text_field( $consumer_key ), 'WC_CONSUMER_SECRET' => sanitize_text_field( $consumer_secret ), ), $token ); } }