@revrag-ai/embed-react-native
Version:
A powerful React Native library for integrating AI-powered voice agents into mobile applications. Features real-time voice communication, intelligent speech processing, customizable UI components, and comprehensive event handling for building conversation
248 lines (226 loc) • 8.69 kB
JavaScript
;
import { getAgentData, setAgentData } from "../store/store.key.js";
/**
* APIService class that ensures proper initialization before API calls
*/
export class APIService {
static instance = null;
apiBaseUrl = null;
isInitialized = false;
constructor() {}
/**
* Get singleton instance of APIService
*/
static getInstance() {
if (!APIService.instance) {
APIService.instance = new APIService();
}
return APIService.instance;
}
/**
* Initialize the API service with the base URL
*/
async initialize() {
if (this.isInitialized && this.apiBaseUrl) {
return; // Already initialized
}
const AgentData = await getAgentData();
console.log('AgentData', AgentData);
if (AgentData?.embedUrl) {
this.apiBaseUrl = AgentData.embedUrl;
this.isInitialized = true;
console.log('API_BASE_URL initialized:', this.apiBaseUrl);
} else {
throw new Error('API base URL not found in keychain');
}
}
/**
* Ensure the service is initialized before making API calls
*/
async ensureInitialized() {
if (!this.isInitialized || !this.apiBaseUrl) {
await this.initialize();
}
}
/**
* Get headers with stored API key
*/
async getHeaders() {
const AgentData = await getAgentData();
if (!AgentData?.apiKey) {
throw new Error('API key not found in keychain');
}
return {
'Content-Type': 'application/json',
'Authorization': `Bearer ${AgentData.apiKey}`,
'X-Revrag-Embedded-Key': AgentData.apiKey
};
}
/**
* Register a new user/device on initialization
* @returns Promise with registration response
*/
async registerOnInitialize() {
try {
await this.ensureInitialized();
console.log('registerOnInitialize ApiData', this.apiBaseUrl);
const headers = await this.getHeaders();
const response = await fetch(`${this.apiBaseUrl}/embedded-agent/initialize`, {
method: 'GET',
headers: headers
});
const data = await response.json();
console.log('dat config data after register', data);
await setAgentData(data, '@config_data');
if (!response.ok) {
console.log('registerOnInitialize error', data.error);
throw new Error(data.error || 'Registration failed');
}
return {
success: true,
data: data
};
} catch (error) {
console.log('registerOnInitialize error', error);
// Enhanced error handling for common iOS network issues
let errorMessage = 'Unknown error occurred';
if (error instanceof Error) {
errorMessage = error.message;
// iOS ATS related errors
if (error.message.includes('The resource could not be loaded') || error.message.includes('App Transport Security')) {
errorMessage = `Network request blocked by iOS App Transport Security. ` + `Please configure ATS exceptions in Info.plist for HTTP endpoints, ` + `or use HTTPS instead. Error: ${error.message}`;
}
// Network connectivity errors
if (error.message.includes('Network request failed') || error.message.includes('Failed to fetch')) {
errorMessage = `Network request failed. Please check your internet connection ` + `and ensure the API endpoint (${this.apiBaseUrl}) is accessible. ` + `Error: ${error.message}`;
}
// Timeout errors
if (error.message.includes('timeout')) {
errorMessage = `Request timeout. The API server may be slow to respond or unreachable. ` + `Error: ${error.message}`;
}
}
return {
success: false,
error: errorMessage
};
}
}
/**
* Update user data
* @param params Update parameters including userId and data to update
* @returns Promise with update response
*/
async updateUserData(params) {
try {
await this.ensureInitialized();
console.log('params', params, `${this.apiBaseUrl}/embedded-agent/user-context/update?app_user_id=${params.data.app_user_id}`);
console.log('updateUserData');
const headers = await this.getHeaders();
const response = await fetch(`${this.apiBaseUrl}/embedded-agent/user-context/update?app_user_id=${params.data.app_user_id}`, {
method: 'PUT',
headers,
body: JSON.stringify({
[params.eventKey]: params.data
})
});
const data = await response.json();
console.log('data after update', data);
if (!response.ok) {
throw new Error(data.error || 'Update failed');
}
return {
success: true
};
} catch (error) {
console.log('updateUserData error', error);
// Enhanced error handling for common iOS network issues
let errorMessage = 'Unknown error occurred';
if (error instanceof Error) {
errorMessage = error.message;
// iOS ATS related errors
if (error.message.includes('The resource could not be loaded') || error.message.includes('App Transport Security')) {
errorMessage = `Network request blocked by iOS App Transport Security. ` + `Please configure ATS exceptions in Info.plist for HTTP endpoints, ` + `or use HTTPS instead. Error: ${error.message}`;
}
// Network connectivity errors
if (error.message.includes('Network request failed') || error.message.includes('Failed to fetch')) {
errorMessage = `Network request failed. Please check your internet connection ` + `and ensure the API endpoint (${this.apiBaseUrl}) is accessible. ` + `Error: ${error.message}`;
}
// Timeout errors
if (error.message.includes('timeout')) {
errorMessage = `Request timeout. The API server may be slow to respond or unreachable. ` + `Error: ${error.message}`;
}
}
return {
success: false,
error: errorMessage
};
}
}
/**
* Get token details for a user
* @param params Parameters including app_user_id and call_type
* @returns Promise with token details
*/
async getTokenDetails(params) {
try {
await this.ensureInitialized();
const headers = await this.getHeaders();
console.log('params', this.apiBaseUrl, params, headers, `${this.apiBaseUrl}/embedded-agent/token`);
const response = await fetch(`${this.apiBaseUrl}/embedded-agent/token`, {
method: 'POST',
headers,
body: JSON.stringify(params)
});
const data = await response.json();
console.log('data', data);
if (!response.ok) {
throw new Error(data.error || 'Failed to get token details');
}
return {
success: true,
data: data
};
} catch (error) {
console.log('getTokenDetails error', error);
// Enhanced error handling for common iOS network issues
let errorMessage = 'Unknown error occurred';
if (error instanceof Error) {
errorMessage = error.message;
// iOS ATS related errors
if (error.message.includes('The resource could not be loaded') || error.message.includes('App Transport Security')) {
errorMessage = `Network request blocked by iOS App Transport Security. ` + `Please configure ATS exceptions in Info.plist for HTTP endpoints, ` + `or use HTTPS instead. Error: ${error.message}`;
}
// Network connectivity errors
if (error.message.includes('Network request failed') || error.message.includes('Failed to fetch')) {
errorMessage = `Network request failed. Please check your internet connection ` + `and ensure the API endpoint (${this.apiBaseUrl}) is accessible. ` + `Error: ${error.message}`;
}
// Timeout errors
if (error.message.includes('timeout')) {
errorMessage = `Request timeout. The API server may be slow to respond or unreachable. ` + `Error: ${error.message}`;
}
}
return {
success: false,
error: errorMessage
};
}
}
}
// Export convenience functions for backward compatibility
export const initializeApi = async () => {
const apiService = APIService.getInstance();
await apiService.initialize();
};
export const registerOnInitialize = async () => {
const apiService = APIService.getInstance();
return await apiService.registerOnInitialize();
};
export const updateUserData = async params => {
const apiService = APIService.getInstance();
return await apiService.updateUserData(params);
};
export const getTokenDetails = async params => {
const apiService = APIService.getInstance();
return await apiService.getTokenDetails(params);
};
//# sourceMappingURL=api.js.map