expo-otp-autofill
v1.0.7
Published
Expo OTP Autofill
Downloads
766
Maintainers
Readme
expo-otp-autofill
A native Expo wrapper for Android's official Google SMS Retriever API. This library allows your React Native / Expo application to automatically detect and auto-fill incoming OTP SMS messages with ZERO Android permissions requested from the user.
🚀 Features
| Feature | Description |
|---|---|
| Zero Permissions | No need to ask the user for dangerous RECEIVE_SMS or READ_SMS permissions. Google Play Store natively approves this exact implementation. |
| Silent Intercept | Google Play Services natively intercepts only the SMS meant for your app based on the unique 11-char App Hash. |
| useOtpAutoFill Hook | Simple plug-and-play React hook with auto-parsing logic. |
| Continuous Listening | Uniquely allows intercepting multiple consecutive OTP messages by instantly resetting the background listener after every read. |
| App Hash Generator | Instantly generate the exact 11-character app hash Google requires (getAppHashAsync()) programmatically. |
Note: Because this library uses the official Google SMS Retriever API, the server transmitting your OTP messages must append your 11-character App Hash at the very end of the SMS content. Example:
Your verification code is 123456.AB12cd3Efgh
📦 Installation
npx expo install expo-otp-autofillAfter installation, ensure you rebuild your Android codebase, as this includes native Google Play Services dependencies:
npx expo prebuild --clean
npx expo run:android📖 Hook Usage: useOtpAutoFill()
This is the main API you will use inside your components. It will trigger Android to listen for the OTP SMS targeting your app for up to 5 minutes.
import React, { useEffect } from 'react';
import { View, TextInput, Button, Text } from 'react-native';
import { useOtpAutoFill, getAppHashAsync } from 'expo-otp-autofill';
export default function MyLoginScreen() {
// 1. Hook begins listening automatically on mount and seamlessly resets after an OTP is intercepted
const { otp, message, clear } = useOtpAutoFill({
length: 6, // Optional: Number of digits to extract (default is [4, 8])
timeout: 30000, // Optional: How long to keep the `otp` state visible horizontally before clearing (default 30000ms. 0 disables)
});
useEffect(() => {
// Optional: Print your 11-character App Hash so you can configure it on your server!
getAppHashAsync().then((hash) => console.log('My App Hash is:', hash));
}, []);
return (
<View style={{ flex: 1, justifyContent: 'center', padding: 20 }}>
{message && <Text style={{ color: 'gray' }}>Captured exact SMS: {message}</Text>}
<TextInput
value={otp ?? ''}
placeholder="Waiting for OTP without permissions..."
style={{ borderWidth: 1, padding: 10, marginVertical: 10, fontSize: 20 }}
/>
<Button title="Manually Clear OTP" onPress={clear} />
</View>
);
}Options
| Option | Type | Default | Description |
|---|---|---|---|
| length | number or [min, max] | [4, 8] | Forces regex to only extract digits matching this length constraint. |
| timeout | number | 30000 | Once an OTP is parsed, automatically clear the state variable to null after this many milliseconds. Pass 0 to disable auto-clearing. |
Return Value
| Property | Type | Description |
|---|---|---|
| otp | string \| null | The purely extracted numeric code (e.g. "123456") |
| message | string \| null | The raw complete SMS message including your app hash. |
| clear | () => void | Removes the otp and message states from the screen, without killing the background listener. The API will immediately capture the next OTP sent. |
📖 Under-the-Hood APIs
If you prefer imperative control instead of Hooks, you can use the core functions explicitly:
startSmsRetrieverAsync()
Initiates 5-minute listening window inside Google Play Services. Returns boolean.
const started = await startSmsRetrieverAsync();stopSmsRetrieverAsync()
Stops listening and unregisters native Broadcast Receiver. (No-op if already stopped).
stopSmsRetrieverAsync();getAppHashAsync()
Computes the 11-char hash from your current Keystore. Returns String.
const hash = await getAppHashAsync();extractOtp(text, options?)
Pure JS function to extract OTP digits out of a larger SMS phrase.
const extracted = extractOtp('Your code is 6451. df3Wz2qP', { length: 4 });
// "6451"🤝 Need to read ALL messages without a hash?
If you are building an offline app, a budget tracker, or an app that does not control the server sending the SMS, the SMS Retriever API will not work for you.
Instead, use its sister library: expo-sms-listener. It requires the RECEIVE_SMS user permission, but allows you to capture any SMS from any sender, even when your app is completely closed.
License
MIT © MULERx
