### Start Metro Server for Example App Source: https://github.com/frejun-tech/react-native-softphone-sdk/blob/main/CONTRIBUTING.md Starts the Metro bundler, which is required to run the example application. This command is executed from the project's root directory. ```sh yarn example start ``` -------------------------------- ### Run Example App on iOS Source: https://github.com/frejun-tech/react-native-softphone-sdk/blob/main/CONTRIBUTING.md Builds and runs the example application on an iOS simulator or device. This command is executed from the project's root directory. ```sh yarn example ios ``` -------------------------------- ### Install React Native Softphone SDK and Dependencies Source: https://context7.com/frejun-tech/react-native-softphone-sdk/llms.txt Installs the core SDK package along with necessary libraries for WebRTC, encrypted storage, phone number handling, JWT decoding, and event management. Also includes a step to install native iOS dependencies. ```bash npm install react-native-softphone-sdk npm install react-native-webrtc react-native-encrypted-storage google-libphonenumber jwt-decode sip.js buffer events cd ios && pod install ``` -------------------------------- ### Run Example App on Android Source: https://github.com/frejun-tech/react-native-softphone-sdk/blob/main/CONTRIBUTING.md Builds and runs the example application on an Android device or emulator. This command is executed from the project's root directory. ```sh yarn example android ``` -------------------------------- ### Install Project Dependencies with Yarn Source: https://github.com/frejun-tech/react-native-softphone-sdk/blob/main/CONTRIBUTING.md Installs all necessary project dependencies using Yarn workspaces. This command should be run in the root directory of the project. ```sh yarn ``` -------------------------------- ### Install React Native Softphone SDK Source: https://github.com/frejun-tech/react-native-softphone-sdk/blob/main/README.md Installs the react-native-softphone-sdk package using npm or yarn. This is the first step to integrate the SDK into your React Native project. ```bash npm install react-native-softphone-sdk # or yarn add react-native-softphone-sdk ``` -------------------------------- ### Install Peer Dependencies for Softphone SDK Source: https://github.com/frejun-tech/react-native-softphone-sdk/blob/main/README.md Installs essential peer dependencies required by the react-native-softphone-sdk. These include native modules for WebRTC, encrypted storage, and utility libraries. ```bash npm install react-native-webrtc react-native-encrypted-storage google-libphonenumber jwt-decode sip.js buffer events ``` -------------------------------- ### Starting SDK Engine and Event Listeners Source: https://github.com/frejun-tech/react-native-softphone-sdk/blob/main/README.md Starts the SDK engine to establish a WebSocket connection and register event listeners for call status updates and session events. This is a crucial step before making or receiving calls. The `useEffect` hook ensures this logic runs when the `softphone` instance is available. ```typescript useEffect(() => { if (!softphone) return; const listeners = { onConnectionStateChange: (type, state, isError) => { console.log(`Status: ${state}`); // e.g., Registered, Connected, Disconnected }, // ARGS: Type ('Incoming'/'Outgoing'), Session Object, Details onCallCreated: (type, session, details) => { console.log(`Call: ${type}, Candidate: ${details.candidate}`); activeSession.current = session; // IMPORTANT: Store session ref if (type === 'Incoming') { // Show incoming call UI } }, onCallAnswered: (session) => { /* Call is live */ }, onCallHangup: (session) => { // IGNORE "Ghost Hangups" from call forking if (activeSession.current && activeSession.current !== session) return; activeSession.current = null; }, onSessionRefresh: (payload) => { console.log("Session was refreshed automatically. New tokens:", payload); // Optionally, save these new tokens to your app's state management or storage } }; softphone.start(listeners).then(() => { console.log("SDK started and ready to make calls!"); }); }, [softphone]); ``` -------------------------------- ### iOS Pod Installation for Softphone SDK Source: https://github.com/frejun-tech/react-native-softphone-sdk/blob/main/README.md Installs native iOS dependencies using CocoaPods after adding the SDK and its peer dependencies. Navigate to the ios directory before running this command. ```bash cd ios && pod install && cd .. ``` -------------------------------- ### Start Softphone with Event Listeners (TypeScript) Source: https://context7.com/frejun-tech/react-native-softphone-sdk/llms.txt Connects the WebSocket transport, registers the SIP user agent, fetches the user profile, and attaches event listeners. This method must be called after successful authentication to enable calling functionality. It requires the `Softphone` instance and an object containing various event listener callbacks. ```typescript import { Softphone } from 'react-native-softphone-sdk'; import { useRef } from 'react'; const activeSession = useRef(null); const startSoftphone = (softphone: Softphone) => { const listeners = { // Connection state changes (UserAgentState or RegistererState) onConnectionStateChange: ( type: 'UserAgentState' | 'RegistererState', state: string, isError: boolean, error?: any ) => { console.log(`[${type}] State: ${state}, Error: ${isError}`); if (state === 'Registered') { console.log('Ready to make and receive calls'); } else if (state === 'Disconnected' && isError) { console.warn('Connection lost, will auto-reconnect on foreground'); } }, // Called when a new call is created (incoming or outgoing) onCallCreated: ( type: 'Incoming' | 'Outgoing', session: Session, details: { candidate?: string } ) => { console.log(`${type} call: ${details.candidate}`); activeSession.current = session; // Store session reference if (type === 'Incoming') { // Show incoming call UI showIncomingCallScreen(details.candidate); } }, // Called when outgoing call starts ringing onCallRinging: (session: Session) => { console.log('Call is ringing...'); }, // Called when call is answered and media is established onCallAnswered: (session: Session) => { console.log('Call connected'); showActiveCallScreen(); }, // Called when call ends (handle call forking "ghost hangups") onCallHangup: (session: Session) => { // IMPORTANT: Ignore hangups from forked sessions if (activeSession.current && activeSession.current !== session) { console.log('Ignoring ghost hangup from forked session'); return; } console.log('Call ended'); activeSession.current = null; showDialerScreen(); }, // Called when session tokens are automatically refreshed onSessionRefresh: (payload: { accessToken: string; refreshToken: string; email: string }) => { console.log('Tokens refreshed automatically'); // Optionally sync new tokens with your app state or backend updateStoredTokens(payload); }, }; softphone.start(listeners).then(() => { console.log('Softphone started successfully'); }).catch((error) => { console.error('Failed to start softphone:', error); }); }; ``` -------------------------------- ### Making and Managing Calls Source: https://github.com/frejun-tech/react-native-softphone-sdk/blob/main/README.md Provides examples for initiating outgoing calls and managing incoming calls. Outgoing calls can be made using a default caller ID or a specific virtual number. Incoming calls can be answered or hung up using the `activeSession.current` reference. ```typescript // --- OUTGOING --- // Option 1: Use default caller ID from user profile await softphone.makeCall('+919876543210'); // Option 2: Use a specific Virtual Number (Caller ID) await softphone.makeCall('+919876543210', '+918012345678'); // --- INCOMING --- // Answer an incoming call await activeSession.current.answer(); // Hangup or Reject a call await activeSession.current.hangup(); ``` -------------------------------- ### Get Session Tokens - TypeScript Source: https://context7.com/frejun-tech/react-native-softphone-sdk/llms.txt Retrieves the current session tokens, including the access token, refresh token, and user's email. This is valuable for synchronizing authentication state with a backend or for use in app state management. The function returns a TokenPayload object or null if no active session exists. ```typescript import { Softphone } from 'react-native-softphone-sdk'; interface TokenPayload { accessToken: string; refreshToken: string; email: string; } const getCurrentTokens = (softphone: Softphone): TokenPayload | null => { const tokens = softphone.getTokens(); if (tokens) { console.log('Current session:'); console.log(`- Email: ${tokens.email}`); console.log(`- Access Token: ${tokens.accessToken.substring(0, 20)}...`); console.log(`- Refresh Token: ${tokens.refreshToken.substring(0, 20)}...`); return tokens; } else { console.log('No active session'); return null; } }; // Sync tokens with your backend after refresh const syncTokensWithBackend = async (softphone: Softphone) => { const tokens = softphone.getTokens(); if (tokens) { await fetch('https://your-api.com/sync-tokens', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify(tokens), }); } }; ``` -------------------------------- ### Get Virtual Numbers (Caller IDs) - TypeScript Source: https://context7.com/frejun-tech/react-native-softphone-sdk/llms.txt Retrieves a list of virtual numbers (caller IDs) available for the authenticated user. This function is useful for populating a caller ID selection UI. It returns an array of VirtualNumber objects, each containing details like ID, name, country code, number, and type. ```typescript import { Softphone } from 'react-native-softphone-sdk'; interface VirtualNumber { id: number; name: string; country_code: string; number: string; location: string; type: string; default_calling_number: boolean; default_sms_number: boolean; } const displayCallerIdOptions = (softphone: Softphone) => { const virtualNumbers: VirtualNumber[] = softphone.getVirtualNumbers(); console.log('Available Caller IDs:'); virtualNumbers.forEach((vn) => { const fullNumber = `${vn.country_code}${vn.number}`; const isDefault = vn.default_calling_number ? ' (Default)' : ''; console.log(`- ${vn.name}: ${fullNumber}${isDefault}`); }); // Find the default caller ID const defaultNumber = virtualNumbers.find((vn) => vn.default_calling_number); if (defaultNumber) { console.log(`Default: ${defaultNumber.country_code}${defaultNumber.number}`); } return virtualNumbers; }; // Example: Build a caller ID picker component const CallerIdPicker = ({ softphone, onSelect }) => { const numbers = softphone.getVirtualNumbers(); return ( {numbers.map((vn) => ( onSelect(`${vn.country_code}${vn.number}`)} > {vn.name} {`${vn.country_code}${vn.number}`} {vn.default_calling_number && Default} ))} ); }; ``` -------------------------------- ### Softphone.start Source: https://context7.com/frejun-tech/react-native-softphone-sdk/llms.txt Connects the WebSocket transport, registers the SIP user agent, fetches the user profile, and attaches event listeners. This method must be called after successful authentication to enable calling functionality. ```APIDOC ## Softphone.start ### Description Connects the WebSocket transport, registers the SIP user agent, fetches the user profile, and attaches event listeners. This method must be called after successful authentication to enable calling functionality. ### Method POST ### Endpoint /softphone/start ### Parameters #### Request Body - **listeners** (object) - Required - An object containing event listener callbacks for connection state changes, call events, and session refreshes. - **onConnectionStateChange** (function) - Callback for connection state changes. - **onCallCreated** (function) - Callback when a new call is created. - **onCallRinging** (function) - Callback when an outgoing call starts ringing. - **onCallAnswered** (function) - Callback when a call is answered and media is established. - **onCallHangup** (function) - Callback when a call ends. - **onSessionRefresh** (function) - Callback when session tokens are automatically refreshed. ### Request Example ```json { "listeners": { "onConnectionStateChange": "(type, state, isError, error) => { ... }", "onCallCreated": "(type, session, details) => { ... }", "onCallRinging": "(session) => { ... }", "onCallAnswered": "(session) => { ... }", "onCallHangup": "(session) => { ... }", "onSessionRefresh": "(payload) => { ... }" } } ``` ### Response #### Success Response (200) - **message** (string) - Indicates successful start of the softphone. #### Response Example ```json { "message": "Softphone started successfully" } ``` ``` -------------------------------- ### Direct Login with Credentials Source: https://github.com/frejun-tech/react-native-softphone-sdk/blob/main/README.md Initializes the SDK by passing access tokens, email, and refresh tokens directly. This method is useful when you have already obtained these credentials through your own authentication flow. The refreshToken is mandatory for session continuity, and clientId/clientSecret can be provided for automatic token refresh. ```typescript const handleDirectLogin = async () => { try { // Pass credentials (accessToken, email, refreshToken) directly // Note: refreshToken is mandatory to ensure session continuity const softphoneInstance = await Softphone.login({ accessToken: "YOUR_ACCESS_TOKEN", email: "user@example.com", refreshToken: "YOUR_REFRESH_TOKEN", // Optional: Provide these to enable auto-refresh if the accessToken is already expired clientId: "YOUR_CLIENT_ID", clientSecret: "YOUR_CLIENT_SECRET" }); if (softphoneInstance) { setSoftphone(softphoneInstance); console.log("Logged in successfully!"); } } catch (e) { console.error("Direct login failed", e); } }; ``` -------------------------------- ### Initialize React Native Softphone SDK Source: https://github.com/frejun-tech/react-native-softphone-sdk/blob/main/README.md Initializes the Softphone SDK with client credentials and attempts to restore an existing session from storage. This should be called once, typically at the application's root. ```typescript import { Softphone } from 'react-native-softphone-sdk'; const CREDENTIALS = { clientId: 'YOUR_CLIENT_ID', clientSecret: 'YOUR_CLIENT_SECRET', }; // ... inside useEffect const init = async () => { // Restore session from storage const restoredSoftphone = await Softphone.initialize(CREDENTIALS); if (restoredSoftphone) { setSoftphone(restoredSoftphone); } }; init(); ``` -------------------------------- ### Troubleshooting Source: https://github.com/frejun-tech/react-native-softphone-sdk/blob/main/README.md Common issues and their solutions for the React Native Softphone SDK. ```APIDOC ## Troubleshooting ### `TypeError: answer is not a function` #### Description This error occurs when the `onCallCreated` listener does not receive the correct number of arguments. The `answer()` method should be called on the `session` object, not the `details` object. #### Fix Ensure your `onCallCreated` listener receives **3 arguments**: `(type, session, details)`. Call `.answer()` on the `session` object. ### Calls drop immediately with "Ghost Hangup" #### Description This issue is caused by SIP Call Forking. To prevent this, the `onCallHangup` listener must verify if the session being hung up is the currently active one. #### Fix In your `onCallHangup` listener, add a check: `if (activeSession.current !== session) return;`. ### 401 Unauthorized Errors #### Description The SDK automatically handles 401 Unauthorized errors using its Auto-Refresh mechanism. It refreshes session tokens using the stored refresh token and retries the failed request. #### Fix No action is required from the user. The SDK handles this automatically. #### Note To be notified when tokens are refreshed (e.g., to update your app's state or storage), use the `onSessionRefresh` event listener passed to the `start()` method. ``` -------------------------------- ### Initialize Softphone SDK and Restore Session (TypeScript) Source: https://context7.com/frejun-tech/react-native-softphone-sdk/llms.txt Initializes the Softphone SDK using client credentials and attempts to restore a previous session from encrypted storage. This function should be called once at application startup before any other SDK operations. It returns a Softphone instance if a session is restored, otherwise null. ```typescript import { Softphone } from 'react-native-softphone-sdk'; const CREDENTIALS = { clientId: 'YOUR_CLIENT_ID', clientSecret: 'YOUR_CLIENT_SECRET', }; // Initialize and restore session const initializeSoftphone = async () => { try { const softphone = await Softphone.initialize(CREDENTIALS); if (softphone) { console.log('Session restored successfully'); // User is already logged in, proceed to start() return softphone; } else { console.log('No previous session found, login required'); return null; } } catch (error) { console.error('Initialization failed:', error); return null; } }; // Usage in React component useEffect(() => { initializeSoftphone().then(setSoftphone); }, []); ``` -------------------------------- ### Handle Browser OAuth Flow for Login (TypeScript) Source: https://context7.com/frejun-tech/react-native-softphone-sdk/llms.txt Initiates the FreJun OAuth authentication by opening the system browser. After successful authentication, it handles the redirect URL to complete the login process and set the Softphone instance. Requires linking event listener for the OAuth redirect. ```typescript import { Softphone } from 'react-native-softphone-sdk'; import { Linking } from 'react-native'; // Step 1: Trigger browser login const handleLoginButton = async () => { try { await Softphone.login(); // Opens browser to FreJun login page } catch (error) { console.error('Failed to open login:', error); } }; // Step 2: Handle the OAuth redirect deep link useEffect(() => { const subscription = Linking.addEventListener('url', async (event) => { if (event.url.includes('?code=')) { try { const softphone = await Softphone.handleRedirect(event.url); console.log('Login successful'); setSoftphone(softphone); } catch (error) { console.error('Login failed:', error); Alert.alert('Login Error', 'Authentication failed. Please try again.'); } } }); return () => subscription.remove(); }, []); ``` -------------------------------- ### Publish New Versions with release-it Source: https://github.com/frejun-tech/react-native-softphone-sdk/blob/main/CONTRIBUTING.md Automates the process of publishing new versions of the package to npm, including version bumping, tagging, and release creation. This command is run from the project's root directory. ```sh yarn release ``` -------------------------------- ### Softphone Class Methods Source: https://github.com/frejun-tech/react-native-softphone-sdk/blob/main/README.md Methods for initializing, authenticating, managing calls, and handling sessions within the Softphone SDK. ```APIDOC ## Softphone Class ### `initialize(creds)` #### Description Configures SDK with credentials, restores a previous session from storage, and checks permissions. #### Method `static initialize` #### Returns `Promise` ### `login(params?)` #### Description Logs in directly if parameters are provided, or initiates the standard browser OAuth flow if no parameters are given. `refreshToken` is required when providing parameters. `clientId` and `clientSecret` are used for token refresh if the `accessToken` is expired. #### Method `static login` #### Parameters ##### Query Parameters - **accessToken** (string) - Required - The access token for direct login. - **email** (string) - Required - The user's email. - **refreshToken** (string) - Required - The refresh token for session renewal. - **clientId** (string) - Optional - Client ID for token refresh. - **clientSecret** (string) - Optional - Client secret for token refresh. #### Returns `Promise` ### `handleRedirect(url)` #### Description Exchanges the authorization code from a deep link URL for session tokens and completes the browser login flow. #### Method `static handleRedirect` #### Parameters ##### Query Parameters - **url** (string) - Required - The deep link URL containing the authorization code. #### Returns `Promise` ### `start(listeners)` #### Description Connects the WebSocket, registers the SIP user agent, fetches the user profile, and attaches event listeners. Includes `onSessionRefresh` listener. #### Method `start` #### Parameters ##### Query Parameters - **listeners** (object) - Optional - An object containing event listeners, including `onSessionRefresh`. #### Returns `Promise` ### `connect()` #### Description Manually attempts to reconnect the transport and re-register the SIP user agent. #### Method `connect` #### Returns `Promise` ### `makeCall(to, [from])` #### Description Initiates an outbound call. Updates the user's primary virtual number if `from` differs from the current default. #### Method `makeCall` #### Parameters ##### Path Parameters - **to** (string) - Required - The destination number for the call. - **from** (string) - Optional - The caller ID (virtual number) to use for the call. #### Returns `Promise` ### `getVirtualNumbers()` #### Description Returns an array of available caller IDs (virtual numbers) for the authenticated user. #### Method `getVirtualNumbers` #### Returns `VirtualNumber[]` ### `getTokens()` #### Description Returns the current session tokens (`accessToken`, `refreshToken`, `email`). #### Method `getTokens` #### Returns `TokenPayload | null` ### `logout()` #### Description Destroys the current session, unregisters the SIP user agent, and clears all credentials from secure storage. #### Method `logout` #### Returns `Promise` ``` -------------------------------- ### Run Unit Tests with Jest Source: https://github.com/frejun-tech/react-native-softphone-sdk/blob/main/CONTRIBUTING.md Executes the project's unit tests using the Jest testing framework. This command is run from the project's root directory. ```sh yarn test ``` -------------------------------- ### Standard Browser Login Flow for Softphone SDK Source: https://github.com/frejun-tech/react-native-softphone-sdk/blob/main/README.md Initiates the Standard Browser OAuth flow by opening the system browser for user authentication. After successful login, the SDK handles the redirect back to the application via a deep link. ```typescript import { Linking } from 'react-native'; const handleLogin = async () => { // 1. Opens Browser await Softphone.login(); }; // 2. Handle Redirect (Deep Link) useEffect(() => { const sub = Linking.addEventListener('url', async (event) => { if (event.url.includes('?code=')) { try { // Exchange code for token const softphoneInstance = await Softphone.handleRedirect(event.url); setSoftphone(softphoneInstance); } catch (e) { console.error("Login failed", e); } } }); return () => sub.remove(); }, []); ``` -------------------------------- ### Lint Project Files with ESLint Source: https://github.com/frejun-tech/react-native-softphone-sdk/blob/main/CONTRIBUTING.md Applies ESLint to check for code style and potential errors according to the project's linting rules. This command is run from the project's root directory. ```sh yarn lint ``` -------------------------------- ### Softphone SDK Exception Handling (TypeScript) Source: https://context7.com/frejun-tech/react-native-softphone-sdk/llms.txt Demonstrates how to handle typed exceptions thrown by the SDK for robust error management. It includes a switch statement to differentiate between various exception types and log specific details. ```typescript import { Softphone, Exceptions } from 'react-native-softphone-sdk'; const handleSoftphoneError = (error: Error) => { switch (error.name) { case 'MissingParameterException': // Required parameters were not provided console.error('Missing required parameters:', error.details); break; case 'InvalidValueException': // A parameter has an invalid value (e.g., malformed phone number) console.error('Invalid value:', error.details); break; case 'UnauthorizedException': // Authentication failed or session expired console.error('Auth error:', error.details); break; case 'InvalidTokenException': // Token is invalid or expired (auto-refresh failed) console.error('Token error:', error.details); break; case 'PermissionDeniedException': // User lacks required permissions console.error('Permission denied:', error.details); break; case 'UnknownException': // Unexpected error console.error('Unknown error:', error.details); break; default: console.error('Error:', error.message); } }; ``` -------------------------------- ### Session Class Methods Source: https://github.com/frejun-tech/react-native-softphone-sdk/blob/main/README.md Methods for managing an active call session. ```APIDOC ## Session Class ### `answer()` #### Description Accepts an incoming call. #### Method `answer` ### `hangup()` #### Description Ends the current call (can be used to cancel, reject, or terminate). #### Method `hangup` ``` -------------------------------- ### iOS Info.plist Configuration for Softphone SDK Source: https://github.com/frejun-tech/react-native-softphone-sdk/blob/main/README.md Adds the Microphone usage description key to the iOS Info.plist file. This is required by Apple to inform the user why the application needs microphone access for VoIP calls. ```xml NSMicrophoneUsageDescription We need access to your microphone to make VoIP calls. ``` -------------------------------- ### Perform Direct Login with Credentials (TypeScript) Source: https://context7.com/frejun-tech/react-native-softphone-sdk/llms.txt Authenticates the user directly using provided access, refresh, and email tokens, bypassing the browser. This method is suitable for custom integrations where tokens are obtained through other means. It requires client ID and secret for potential auto-refresh functionality. ```typescript import { Softphone } from 'react-native-softphone-sdk'; const handleDirectLogin = async (credentials: { accessToken: string; email: string; refreshToken: string; }) => { try { const softphone = await Softphone.login({ accessToken: credentials.accessToken, email: credentials.email, refreshToken: credentials.refreshToken, // Required for session continuity // Optional: provide these to enable auto-refresh if token is already expired clientId: 'YOUR_CLIENT_ID', clientSecret: 'YOUR_CLIENT_SECRET', }); if (softphone) { console.log('Direct login successful'); return softphone; } } catch (error) { if (error.name === 'InvalidTokenException') { console.error('Token is invalid or expired'); } else if (error.name === 'PermissionDeniedException') { console.error('User does not have SDK permissions'); } throw error; } }; // Example usage with tokens from your backend const loginWithBackendTokens = async () => { const response = await fetch('https://your-api.com/auth/frejun-tokens'); const { accessToken, refreshToken, email } = await response.json(); const softphone = await handleDirectLogin({ accessToken, refreshToken, email }); setSoftphone(softphone); }; ``` -------------------------------- ### Type-Check Project Files with TypeScript Source: https://github.com/frejun-tech/react-native-softphone-sdk/blob/main/CONTRIBUTING.md Verifies the TypeScript types across the project to ensure code quality and prevent type-related errors. This command is run from the project's root directory. ```sh yarn typecheck ``` -------------------------------- ### Android Deep Linking for Softphone SDK OAuth Source: https://github.com/frejun-tech/react-native-softphone-sdk/blob/main/README.md Configures an intent filter in AndroidManifest.xml to handle deep linking for the Standard Browser OAuth flow. This allows the app to receive the redirect from the FreJun login page. ```xml ``` -------------------------------- ### Make VoIP Call with React Native Softphone SDK (TypeScript) Source: https://context7.com/frejun-tech/react-native-softphone-sdk/llms.txt Initiates an outbound VoIP call to a specified phone number. Optionally, a virtual number can be provided as the caller ID. The SDK handles virtual number switching and server reconnection. Phone numbers must be in E.164 format. ```typescript import { Softphone } from 'react-native-softphone-sdk'; // Make a call using the default caller ID const makeCallDefault = async (softphone: Softphone, destination: string) => { try { // Phone number must be in E.164 format: +[CountryCode][Number] const success = await softphone.makeCall('+919876543210'); if (success) { console.log('Call initiated successfully'); } else { console.log('Failed to initiate call'); } } catch (error) { if (error.name === 'MissingParameterException') { console.error('Phone number is required'); } else if (error.name === 'InvalidValueException') { console.error('Invalid phone number format. Use E.164 format.'); } else if (error.name === 'PermissionDeniedException') { console.error('User does not have outbound call permission'); } } }; // Make a call with a specific caller ID (virtual number) const makeCallWithCallerId = async (softphone: Softphone) => { try { const destination = '+919876543210'; const callerId = '+918012345678'; // Virtual number to display const success = await softphone.makeCall(destination, callerId); console.log('Call initiated with custom caller ID'); } catch (error) { console.error('Call failed:', error); } }; // Make a call with metadata for tracking const makeCallWithMetadata = async (softphone: Softphone) => { const success = await softphone.makeCall('+919876543210', null, { metadata: { transactionId: 'txn_12345', jobId: 'job_67890', candidateId: 'cand_11111', }, }); }; ``` -------------------------------- ### Fix Linting Errors with ESLint Source: https://github.com/frejun-tech/react-native-softphone-sdk/blob/main/CONTRIBUTING.md Automatically fixes code formatting and style issues identified by ESLint. This command is run from the project's root directory. ```sh yarn lint --fix ``` -------------------------------- ### Connect to Softphone Service - TypeScript Source: https://context7.com/frejun-tech/react-native-softphone-sdk/llms.txt Manually initiates a reconnection attempt to the softphone service. This is useful for providing users with a manual retry option if automatic reconnection fails. The function returns a Promise that resolves on successful reconnection or rejects with an error. ```typescript import { Softphone } from 'react-native-softphone-sdk'; import { Alert } from 'react-native'; const handleManualReconnect = async (softphone: Softphone) => { try { console.log('Attempting manual reconnection...'); await softphone.connect(); console.log('Reconnected successfully'); Alert.alert('Connected', 'Successfully reconnected to the server.'); } catch (error) { console.error('Reconnection failed:', error); Alert.alert( 'Connection Failed', 'Unable to reconnect. Please check your internet connection and try again.' ); } }; // Example: Retry button component const ConnectionStatusBar = ({ softphone, isConnected }) => { if (isConnected) return null; return ( Disconnected from server handleManualReconnect(softphone)}> Tap to Reconnect ); }; ``` -------------------------------- ### Softphone.makeCall Source: https://context7.com/frejun-tech/react-native-softphone-sdk/llms.txt Initiates an outbound VoIP call to the specified phone number. Optionally specify a virtual number (caller ID) to use instead of the user's default. The SDK automatically handles virtual number switching and server reconnection if needed. ```APIDOC ## Softphone.makeCall ### Description Initiates an outbound VoIP call to the specified phone number. Optionally specify a virtual number (caller ID) to use instead of the user's default. The SDK automatically handles virtual number switching and server reconnection if needed. ### Method POST ### Endpoint /softphone/makeCall ### Parameters #### Path Parameters - **destination** (string) - Required - The phone number to call, in E.164 format (e.g., '+1234567890'). - **callerId** (string) - Optional - The virtual number to use as the caller ID. If not provided, the user's default caller ID is used. - **metadata** (object) - Optional - Additional metadata to associate with the call for tracking purposes. - **transactionId** (string) - Optional - Transaction identifier. - **jobId** (string) - Optional - Job identifier. - **candidateId** (string) - Optional - Candidate identifier. ### Request Example ```json { "destination": "+919876543210", "callerId": "+918012345678", "metadata": { "transactionId": "txn_12345", "jobId": "job_67890", "candidateId": "cand_11111" } } ``` ### Response #### Success Response (200) - **success** (boolean) - Indicates whether the call was successfully initiated. #### Response Example ```json { "success": true } ``` #### Error Response - **name** (string) - The name of the exception (e.g., 'MissingParameterException', 'InvalidValueException', 'PermissionDeniedException'). - **message** (string) - A detailed error message. ``` -------------------------------- ### Android Permissions for Softphone SDK Source: https://github.com/frejun-tech/react-native-softphone-sdk/blob/main/README.md Declares necessary permissions in AndroidManifest.xml for the softphone SDK to function, including internet, audio recording, network state access, foreground services, and Bluetooth for Android 12+. ```xml ``` -------------------------------- ### Session Answer Call Functionality (TypeScript) Source: https://context7.com/frejun-tech/react-native-softphone-sdk/llms.txt Accepts an incoming call. This method is intended to be called on incoming call sessions received via the `onCallCreated` listener. It includes error handling for the call answering process. ```typescript import { Session } from 'react-native-softphone-sdk'; // Answer an incoming call const handleAnswerCall = async (session: Session) => { try { await session.answer(); console.log('Call answered'); } catch (error) { console.error('Failed to answer call:', error); } }; // Example: Incoming call screen component const IncomingCallScreen = ({ session, callerNumber }) => { return ( {callerNumber} Incoming Call session.hangup()} > Decline session.answer()} > Answer ); }; ``` -------------------------------- ### Manual Reconnection Source: https://github.com/frejun-tech/react-native-softphone-sdk/blob/main/README.md Allows for manual reconnection to the service if the connection drops. This function can be triggered by the user or implemented as part of an error handling strategy. An alert is shown to the user if reconnection fails. ```typescript try { await softphone.connect(); } catch (e) { Alert.alert("Reconnection failed", "Please check your network connection."); } ``` -------------------------------- ### Fetching Virtual Numbers Source: https://github.com/frejun-tech/react-native-softphone-sdk/blob/main/README.md Retrieves a list of virtual numbers assigned to the user, which can be used to populate a UI for selecting the caller ID. The returned data includes the number's name, country code, and the number itself, along with a flag indicating if it's the default calling number. ```typescript const numbers = softphone.getVirtualNumbers(); // Returns: [{ name: "Office", country_code: "+91", number: "...", default_calling_number: true }, ...] ``` -------------------------------- ### Softphone Logout Functionality (TypeScript) Source: https://context7.com/frejun-tech/react-native-softphone-sdk/llms.txt Destroys the current session, unregisters the SIP user agent, and clears credentials. This function should be called when a user logs out of the application. It handles success and error scenarios, including resetting application state. ```typescript import { Softphone } from 'react-native-softphone-sdk'; const handleLogout = async (softphone: Softphone) => { try { await softphone.logout(); console.log('Logged out successfully'); // Reset app state setSoftphone(null); navigateToLoginScreen(); } catch (error) { console.error('Logout error:', error); // Force local cleanup even if logout fails setSoftphone(null); } }; // Example: Logout confirmation dialog const LogoutButton = ({ softphone }) => { const confirmLogout = () => { Alert.alert( 'Logout', 'Are you sure you want to logout?', [ { text: 'Cancel', style: 'cancel' }, { text: 'Logout', style: 'destructive', onPress: () => handleLogout(softphone) }, ] ); }; return ( Logout ); }; ``` -------------------------------- ### Session Hangup Call Functionality (TypeScript) Source: https://context7.com/frejun-tech/react-native-softphone-sdk/llms.txt Ends the current call. This method can be used to cancel outgoing calls, reject incoming calls, or terminate active calls, depending on the session's current state. It includes error handling for the call termination process. ```typescript import { Session } from 'react-native-softphone-sdk'; // Hang up / end / reject a call const handleHangup = async (session: Session) => { try { await session.hangup(); console.log('Call ended'); } catch (error) { console.error('Failed to end call:', error); } }; // Example: Active call screen with end call button const ActiveCallScreen = ({ session, duration, callerNumber }) => { return ( {callerNumber} {formatDuration(duration)} session.hangup()} > End Call ); }; ``` === COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.