import { Platform } from 'react-native'; type SmsRetrieverModule = { requestPhoneNumber: () => Promise; startSmsRetriever: () => Promise; addSmsListener: (callback: (event: { message?: string }) => void) => Promise; removeSmsListener: () => void; }; function getModule(): SmsRetrieverModule | null { if (Platform.OS !== 'android') return null; return require('react-native-sms-retriever').default as SmsRetrieverModule; } export function extractOtpFromMessage(message: string, length: number): string | null { const exact = new RegExp(`(?:^|[^\\d])(\\d{${length}})(?:[^\\d]|$)`); const m = message.match(exact); if (m) return m[1]; const any = message.match(/(\d{4,8})/); if (!any) return null; const digits = any[1]; if (digits.length >= length) return digits.slice(0, length); if (digits.length === length) return digits; return null; } /** SMS Retriever:无需 READ_SMS,短信需含 app hash(见 Google 文档) */ export async function startOtpSmsListener( otpLength: number, onOtp: (otp: string) => void, ): Promise<() => void> { const mod = getModule(); if (!mod) return () => {}; const stop = () => { try { mod.removeSmsListener(); } catch { /* ignore */ } }; try { const registered = await mod.startSmsRetriever(); if (!registered) return stop; await mod.addSmsListener((event) => { const msg = event.message ?? ''; const otp = extractOtpFromMessage(msg, otpLength); if (otp) { onOtp(otp); stop(); } }); } catch { stop(); } return stop; } /** 系统号码选择器,一次性授权,无需 READ_SMS */ export async function requestPhoneNumberHint(): Promise { const mod = getModule(); if (!mod) throw new Error('仅支持 Android'); return mod.requestPhoneNumber(); } export function normalizeHintPhone(raw: string, mobileLength = 10): string { return raw.replace(/\D/g, '').slice(-mobileLength); }