UNPKG

@pngme/react-native-sms-pngme-android

Version:

Module for Pngme partners to build credit score from phone information

292 lines (253 loc) 8.42 kB
import { NativeModules, Platform } from 'react-native'; const ANDROID_OS_NAME = 'android'; export type GoParams = { clientKey: string; firstName?: string; lastName?: string; email?: string; phoneNumber?: string; externalId: string; companyName: string; }; export type PngmeDialogStyle = { primaryColor?: string; backgroundColor?: string; textColor?: string; buttonBackgroundColor?: string; buttonTextColor?: string; titleTextSize?: number; bodyTextSize?: number; buttonTextSize?: number; customTitle?: string; customSmsDescription?: string; customPrivacyDescription?: string; customButtonText?: string; buttonCornerRadius?: number; buttonElevation?: number; privacyPolicyUrl?: string; eulaUrl?: string; }; export type PngmeError = { code: string; message: string; }; // Response constants const SDK_FLOW_ERROR = 'E_ON_SDK'; const SDK_IOS_INCOMPATIBLE = 'E_IOS_IS_NOT_COMPATIBLE'; const SDK_SUCCESS = 'success'; const E_INVALID_PARAMS = 'E_INVALID_PARAMS'; const E_ACTIVITY_DOES_NOT_EXIST = 'E_ACTIVITY_DOES_NOT_EXIST'; /** * Validate required parameters before calling SDK */ function validateParams(params: GoParams): PngmeError | null { if (!params.clientKey || params.clientKey.trim() === '') { return { code: E_INVALID_PARAMS, message: 'ClientKey is required' }; } if (!params.externalId || params.externalId.trim() === '') { return { code: E_INVALID_PARAMS, message: 'ExternalId is required' }; } if (!params.companyName || params.companyName.trim() === '') { return { code: E_INVALID_PARAMS, message: 'CompanyName is required' }; } // Validate client key format (adjust as needed) if (params.clientKey.length < 32) { return { code: E_INVALID_PARAMS, message: 'ClientKey appears to be invalid (too short)' }; } return null; } /** * Simple status handling - the SDK only returns success or error codes */ function handleSDKResponse(status: string, errorMessage?: string): string { if (status === SDK_SUCCESS) { return status; } // For any non-success status, throw an error with descriptive message const errorMsg = errorMessage || 'Unknown error occurred'; switch (status) { case E_INVALID_PARAMS: throw new Error(`Invalid Parameters: ${errorMsg}`); case E_ACTIVITY_DOES_NOT_EXIST: throw new Error('Activity Error: No valid Android activity found. Make sure you\'re calling this from a valid React Native screen.'); case SDK_IOS_INCOMPATIBLE: throw new Error('Platform Error: This SDK is only compatible with Android devices.'); default: throw new Error(`SDK Error: ${errorMsg}`); } } /** * Basic SDK integration - shows default Pngme dialog */ export async function go(params: GoParams): Promise<string> { // Validate parameters first const validationError = validateParams(params); if (validationError) { throw new Error(validationError.message); } if (Platform.OS !== ANDROID_OS_NAME) { throw new Error('Platform Error: This SDK is only compatible with Android devices.'); } return new Promise<string>((resolve, reject) => { try { const { SDKWrapper } = NativeModules; if (!SDKWrapper) { reject(new Error('SDK Error: SDKWrapper module not found. Make sure the native module is properly linked.')); return; } console.log('Calling Pngme SDK with params:', JSON.stringify(params, null, 2)); SDKWrapper.go(params, (status: string, errorMessage?: string) => { console.log('Pngme SDK Response:', { status, errorMessage }); try { const result = handleSDKResponse(status, errorMessage); resolve(result); } catch (error) { reject(error); } }); } catch (error) { console.error('Error calling Pngme SDK:', error); reject(new Error(`SDK Error: ${error instanceof Error ? error.message : 'Unknown error occurred'}`)); } }); } /** * Backward compatibility - maps to standard go() method * @deprecated Use go() or goWithStyle() instead */ export async function goWithCustomDialog(params: GoParams): Promise<string> { console.warn('goWithCustomDialog is deprecated. Use go() or goWithStyle() instead.'); return go(params); } /** * SDK integration with custom dialog styling */ export async function goWithStyle(params: GoParams, style: PngmeDialogStyle): Promise<string> { // Validate parameters first const validationError = validateParams(params); if (validationError) { throw new Error(validationError.message); } if (Platform.OS !== ANDROID_OS_NAME) { throw new Error('Platform Error: This SDK is only compatible with Android devices.'); } return new Promise<string>((resolve, reject) => { try { const { SDKWrapper } = NativeModules; if (!SDKWrapper) { reject(new Error('SDK Error: SDKWrapper module not found. Make sure the native module is properly linked.')); return; } console.log('Calling Pngme SDK with style:', JSON.stringify({ params, style }, null, 2)); SDKWrapper.goWithStyle(params, style, (status: string, errorMessage?: string) => { console.log('Pngme SDK with Style Response:', { status, errorMessage }); try { const result = handleSDKResponse(status, errorMessage); resolve(result); } catch (error) { reject(error); } }); } catch (error) { console.error('Error calling Pngme SDK with style:', error); reject(new Error(`SDK Error: ${error instanceof Error ? error.message : 'Unknown error occurred'}`)); } }); } /** * Set a default style for all SDK dialogs */ export function setDefaultStyle(style: PngmeDialogStyle): void { if (Platform.OS === ANDROID_OS_NAME) { try { const { SDKWrapper } = NativeModules; if (SDKWrapper) { SDKWrapper.setDefaultStyle(style); console.log('Default style set successfully'); } else { console.warn('SDKWrapper module not found'); } } catch (error) { console.warn('Error setting default style:', error); } } } /** * Clear the default style and revert to original Pngme styling */ export function clearDefaultStyle(): void { if (Platform.OS === ANDROID_OS_NAME) { try { const { SDKWrapper } = NativeModules; if (SDKWrapper) { SDKWrapper.clearDefaultStyle(); console.log('Default style cleared successfully'); } else { console.warn('SDKWrapper module not found'); } } catch (error) { console.warn('Error clearing default style:', error); } } } /** * Check if SMS permissions are granted */ export async function isPermissionGranted(): Promise<boolean> { if (Platform.OS !== ANDROID_OS_NAME) { return false; } try { const { SDKWrapper } = NativeModules; if (!SDKWrapper) { console.warn('SDKWrapper module not found'); return false; } return await SDKWrapper.isPermissionGranted(); } catch (error) { console.warn('Error on PngmeSDK - isPermissionGranted', error); return false; } } /** * Get the current user's UUID */ export async function getUserUuid(): Promise<string | null> { if (Platform.OS !== ANDROID_OS_NAME) { return null; } try { const { SDKWrapper } = NativeModules; if (!SDKWrapper) { console.warn('SDKWrapper module not found'); return null; } return await SDKWrapper.getUserUuid(); } catch (error) { console.warn('Error on PngmeSDK - getUserUuid', error); return null; } } /** * Enhanced SDK call with pre-flight checks */ export async function goWithPreflightChecks(params: GoParams, style?: PngmeDialogStyle): Promise<string> { console.log('Starting Pngme SDK with preflight checks...'); // 2. Check permissions const hasPermissions = await isPermissionGranted(); console.log(`SMS permissions granted: ${hasPermissions}`); // 3. Call appropriate SDK method if (style) { return goWithStyle(params, style); } else { return go(params); } } // Export response constants for client use export const PNGME_RESPONSES = { SUCCESS: SDK_SUCCESS, ERROR: SDK_FLOW_ERROR, IOS_INCOMPATIBLE: SDK_IOS_INCOMPATIBLE, INVALID_PARAMS: E_INVALID_PARAMS, ACTIVITY_DOES_NOT_EXIST: E_ACTIVITY_DOES_NOT_EXIST, } as const;