Bleskový hovor
Flash Call je metóda telefonického overenia, ktorá na overenie telefónnych čísel používa namiesto SMS zmeškaný hovor. Je to rýchlejšie, bezpečnejšie a nákladovo efektívne.
Prehľad
Overenie Flash Call funguje takto:
- Používateľ požaduje overenie
- Systém inicializuje hovor na telefón užívateľa
- Hovor sa automaticky ukončí po 1-2 zvoneniach
- Aplikácia používateľa zachytáva ID volajúceho
- Identifikácia volajúceho je overená podľa očakávaného vzoru
- Používateľ je overený
Výhody
Nákladovo efektívne
- Až 10x lacnejšie ako SMS
- Žiadne poplatky za doručenie správ
- Znížené náklady na overovanie veľkého objemu
Rýchlejšie
- Okamžité overenie (1-3 sekundy)
- Žiadne čakanie na doručenie SMS
- Lepší používateľský zážitok
Bezpečnejšie
- Ťažšie zachytiť ako SMS
- Žiadne OTP viditeľné v upozorneniach
- Odolné voči útokom na výmenu SIM karty
Globálny dosah
- Funguje v krajinách s obmedzeniami SMS
- Žiadne problémy s filtrovaním SMS
- Univerzálna kompatibilita s telefónmi
Základný bleskový hovor
Žiadosť
{
"from": "YourApp",
"to": "+380XXXXXXXXX",
"type": "flashcall",
"messageData": {
"callerId": "+380123456789"
}
}
Parametre
| Parameter | Typ | povinné | Popis |
|---|---|---|---|
| "od" | reťazec | áno | Váš identifikátor odosielateľa |
| "do" | reťazec | áno | Telefónne číslo príjemcu (E.164) |
| "typ" | reťazec | áno | Nastaviť na "flashcall" |
ID volajúceho |
reťazec | áno | Telefónne číslo, ktoré zavolá používateľovi |
ttl |
celé číslo | Nie | Čas do žitia v sekundách (predvolené: 60) |
Ako to funguje
1. Používateľ zadá telefónne číslo
Používateľ poskytne svoje telefónne číslo vo vašej aplikácii:
2. Požiadajte o bleskový hovor
Váš server požaduje overenie bleskovým hovorom:
curl -X POST https://restapi.smsbat.com/bat/messagelist \
-H "X-Authorization-Key: your-api-key" \
-H "Content-Type: application/json" \
-d '{
"messages": [{
"from": "YourApp",
"to": "+380XXXXXXXXX",
"type": "flashcall",
"messageData": {
"callerId": "+380123456789"
},
"ttl": 60
}]
}'
3. Odozva API
API vracia očakávaný vzor ID volajúceho:
{
"messagelistId": 123456,
"messages": [
{
"messageId": "abc123def456",
"status": "accepted",
"callerId": "+380123456789",
"pattern": "***456789",
"to": "+380XXXXXXXXX"
}
]
}
4. Začnite hovor
Systém zaháji hovor na telefón užívateľa a ukončí ho po 1-2 zvoneniach.
5. Zaznamenajte ID volajúceho
Aplikácia používateľa zachytáva ID volajúceho prichádzajúceho hovoru:
// Android example
val cursor = contentResolver.query(
CallLog.Calls.CONTENT_URI,
arrayOf(CallLog.Calls.NUMBER),
null, null,
CallLog.Calls.DATE + " DESC"
)
6. Overte vzor
Porovnajte zachytené ID volajúceho s očakávaným vzorom:
// JavaScript example
function verifyFlashCall(callerId, pattern) {
// Remove non-digits
const callerDigits = callerId.replace(/\D/g, '');
const patternDigits = pattern.replace(/\*/g, '.');
// Check if matches pattern
const regex = new RegExp(patternDigits);
return regex.test(callerDigits);
}
Príklady implementácie
Android
class FlashCallVerification {
fun requestFlashCall(phoneNumber: String) {
// 1. Request flash call from API
val response = api.requestFlashCall(phoneNumber)
val pattern = response.pattern
// 2. Wait for incoming call
val callReceiver = object : BroadcastReceiver() {
override fun onReceive(context: Context, intent: Intent) {
if (intent.action == TelephonyManager.ACTION_PHONE_STATE_CHANGED) {
val state = intent.getStringExtra(TelephonyManager.EXTRA_STATE)
if (state == TelephonyManager.EXTRA_STATE_RINGING) {
val callerId = intent.getStringExtra(
TelephonyManager.EXTRA_INCOMING_NUMBER
)
// 3. Verify caller ID against pattern
if (verifyPattern(callerId, pattern)) {
onVerificationSuccess()
}
}
}
}
}
// Register receiver
context.registerReceiver(
callReceiver,
IntentFilter(TelephonyManager.ACTION_PHONE_STATE_CHANGED)
)
}
private fun verifyPattern(callerId: String?, pattern: String): Boolean {
if (callerId == null) return false
val regex = pattern.replace("*", "\\d").toRegex()
return regex.matches(callerId)
}
}
iOS
class FlashCallVerification {
func requestFlashCall(phoneNumber: String) {
// 1. Request flash call from API
api.requestFlashCall(phoneNumber) { response in
let pattern = response.pattern
// 2. Use CallKit to detect incoming call
let provider = CXProvider(configuration: providerConfiguration)
provider.setDelegate(self, queue: nil)
// Store pattern for verification
self.expectedPattern = pattern
}
}
// CallKit delegate
func provider(_ provider: CXProvider, perform action: CXAnswerCallAction) {
// Capture caller ID
let callerId = action.callUUID.uuidString
// Verify against pattern
if verifyPattern(callerId: callerId, pattern: expectedPattern) {
onVerificationSuccess()
}
action.fulfill()
}
private func verifyPattern(callerId: String, pattern: String) -> Bool {
let regex = try! NSRegularExpression(
pattern: pattern.replacingOccurrences(of: "*", with: "\\d")
)
let range = NSRange(location: 0, length: callerId.count)
return regex.firstMatch(in: callerId, range: range) != nil
}
}
Web (na strane servera)
// Node.js example
const express = require('express');
const app = express();
app.post('/request-verification', async (req, res) => {
const { phoneNumber } = req.body;
// 1. Request flash call
const response = await fetch('https://restapi.smsbat.com/bat/messagelist', {
method: 'POST',
headers: {
'X-Authorization-Key': process.env.SMSBAT_API_KEY,
'Content-Type': 'application/json'
},
body: JSON.stringify({
messages: [{
from: 'YourApp',
to: phoneNumber,
type: 'flashcall',
messageData: {
callerId: process.env.FLASH_CALL_NUMBER
},
ttl: 60
}]
})
});
const data = await response.json();
const { messageId, pattern } = data.messages[0];
// 2. Store pattern for verification
await redis.setex(`flashcall:${messageId}`, 60, pattern);
// 3. Return pattern to client
res.json({ messageId, pattern });
});
app.post('/verify-flashcall', async (req, res) => {
const { messageId, callerId } = req.body;
// 1. Get expected pattern
const pattern = await redis.get(`flashcall:${messageId}`);
if (!pattern) {
return res.status(400).json({ error: 'Verification expired' });
}
// 2. Verify caller ID
const regex = new RegExp(pattern.replace(/\*/g, '\\d'));
const isValid = regex.test(callerId);
if (isValid) {
// Mark phone as verified
await markPhoneVerified(callerId);
res.json({ verified: true });
} else {
res.status(400).json({ error: 'Invalid caller ID' });
}
});
Formát odpovede
Úspešná odpoveď
{
"messagelistId": 123456,
"messages": [
{
"messageId": "abc123def456",
"status": "accepted",
"callerId": "+380123456789",
"pattern": "***456789",
"to": "+380XXXXXXXXX",
"ttl": 60
}
]
}
Polia odpovedí
| Pole | Typ | Popis |
|---|---|---|
messageId |
reťazec | Jedinečné overovacie ID |
| "stav" | reťazec | Stav: prijatý, odmietnutý |
ID volajúceho |
reťazec | Úplné identifikačné číslo volajúceho |
| "vzor" | reťazec | Vzor na zhodu (číslice + hviezdičky) |
| "do" | reťazec | Telefónne číslo príjemcu |
ttl |
celé číslo | Doba platnosti v sekundách |
Zhoda vzorov
Rozhranie API vracia vzor s hviezdičkami, ktoré maskujú niektoré číslice:
Vaša aplikácia by mala:
- Zaznamenajte ID prichádzajúceho volajúceho
- Extrahujte číslice z ID volajúceho
- Porovnajte so vzorom (hviezdičky = ľubovoľná číslica)
- Overte zhodu v rámci obdobia TTL
Náhrada na SMS
Ak Flash Call zlyhá, automaticky sa vráťte k SMS:
{
"from": "YourApp",
"to": "+380XXXXXXXXX",
"type": "flashcall",
"messageData": {
"callerId": "+380123456789"
},
"fallback": {
"type": "sms",
"text": "Your verification code is: 123456"
},
"ttl": 60
}
Prípady použitia
Registrácia účtu
Overte telefónne čísla počas registrácie bez poplatkov za SMS.
Overenie prihlásenia
Dvojfaktorová autentifikácia pomocou bleskového hovoru.
Aktualizácia telefónneho čísla
Overte nové telefónne číslo, keď používateľ aktualizuje profil.
Potvrdenie transakcie
Potvrďte transakcie s vysokou hodnotou pomocou bleskového hovoru.
Osvedčené postupy
TTL
- ✅ Nastavte TTL na 60-90 sekúnd
- ✅ Umožnite používateľovi opakovať pokus po uplynutí platnosti
- ❌ Nepoužívajte TTL dlhšie ako 120 sekúnd
Používateľská skúsenosť
- Zobraziť správu „Čaká sa na hovor...“.
- Zobrazte časovač odpočítavania (60 sekúnd)
- Poskytnite možnosť „Použiť namiesto toho SMS“
- Automatická detekcia a overenie ID volajúceho
Spracovanie chýb
- Vyriešte chýbajúce povolenia telefónu
- Časový limit po vypršaní TTL
- Poskytnite možnosť núdzovej správy SMS
- Zobraziť jasné chybové hlásenia
Povolenia
Požiadajte o povolenia telefónu pred bleskovým hovorom:
Android:
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
<uses-permission android:name="android.permission.READ_CALL_LOG" />
iOS:
Testovanie
- Test na rôznych zariadeniach
- Testujte s rôznymi dopravcami
- Testujte scenáre odmietnutia povolenia
- Otestujte scenáre časového limitu siete
Obmedzenia
Podpora platformy
- Funguje na všetkých mobilných zariadeniach
- Vyžaduje možnosť telefonického hovoru – Vyžaduje sa povolenie READ_PHONE_STATE
- Nemusí fungovať na tabletoch bez telefónu
Sieť
- Vyžaduje aktívne telefónne pripojenie
- Môže zlyhať v zlých podmienkach siete
- Môžu platiť obmedzenia operátora
- Medzinárodné sadzby sa môžu líšiť
Súkromie
- Používatelia môžu blokovať neznáme čísla
- Niektoré zariadenia majú blokovanie hovorov
- Vyžaduje explicitné povolenia
- Zvážte obavy o súkromie používateľov
Riešenie problémov
Hovor neprijatý
- Skontrolujte, či má telefón signál – Overte formát čísla (E.164)
- Skontrolujte obmedzenia operátora
- Vyskúšajte záložnú SMS
Vzor sa nezhoduje
- Zaistite správne zachytenie ID volajúceho
- Odstráňte znaky, ktoré nie sú číslice
- Skontrolujte formát vzoru
- Overte v rámci obdobia TTL
Povolenie odmietnuté
- Požiadajte správne o povolenia
- Vysvetlite, prečo sú potrebné povolenia
- Poskytnite alternatívu (SMS)
- Zaobchádzajte s gráciou
Ďalšie kroky
- Viber OTP - Alternatívne doručenie OTP
- SMS správy - Záložná SMS
- Skontrolovať stav - Sledujte stav bleskového hovoru