Flash Call
Flash Call je način preverjanja telefona, ki za preverjanje telefonskih številk uporablja neodgovorjen klic namesto sporočila SMS. Je hitrejši, varnejši in stroškovno učinkovit.
Pregled
Hitro preverjanje klicev deluje tako:
- Uporabnik zahteva preverjanje
- Sistem sproži klic na uporabnikov telefon
- Klic se samodejno prekine po 1-2 zvonjenjih
- Uporabnikova aplikacija zajame ID klicatelja
- ID klicatelja se preveri glede na pričakovani vzorec
- Uporabnik je overjen
Prednosti
Stroškovno učinkovito
- Do 10x ceneje kot SMS
- Brez stroškov dostave sporočil
- Zmanjšani stroški za preverjanje velikega obsega
Hitreje
- Takojšnje preverjanje (1-3 sekunde)
- Brez čakanja na dostavo SMS
- Boljša uporabniška izkušnja
Bolj varno
- Težje prestreči kot SMS
- V obvestilih ni vidnega OTP-ja
- Odporen na napade zamenjave kartice SIM
Globalni doseg
- Deluje v državah z omejitvami SMS
- Ni težav s filtriranjem SMS-ov
- Univerzalna združljivost telefona
Osnovni bliskovni klic
Zahteva
{
"from": "YourApp",
"to": "+380XXXXXXXXX",
"type": "flashcall",
"messageData": {
"callerId": "+380123456789"
}
}
Parametri
| Parameter | Vrsta | Zahtevano | Opis |
|---|---|---|---|
od |
niz | Da | Vaš identifikator pošiljatelja |
do |
niz | Da | Telefonska številka prejemnika (E.164) |
tip |
niz | Da | Nastavite na "flashcall" |
callerId |
niz | Da | Telefonska številka, ki bo poklicala uporabnika |
ttl |
celo število | Ne | Življenjska doba v sekundah (privzeto: 60) |
Kako deluje
1. Uporabnik vnese telefonsko številko
Uporabnik navede svojo telefonsko številko v vaši aplikaciji:
2. Zahtevajte hitri klic
Vaš strežnik zahteva hitro preverjanje klica:
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. Odziv API-ja
API vrne pričakovan vzorec ID klicatelja:
{
"messagelistId": 123456,
"messages": [
{
"messageId": "abc123def456",
"status": "accepted",
"callerId": "+380123456789",
"pattern": "***456789",
"to": "+380XXXXXXXXX"
}
]
}
4. Začni klic
Sistem sproži klic na uporabnikov telefon in prekine po 1-2 zvonjenjih.
5. Zajemite ID klicatelja
Uporabnikova aplikacija zajame ID klicatelja dohodnega klica:
// Android example
val cursor = contentResolver.query(
CallLog.Calls.CONTENT_URI,
arrayOf(CallLog.Calls.NUMBER),
null, null,
CallLog.Calls.DATE + " DESC"
)
6. Preverite vzorec
Primerjajte zajeti ID klicatelja s pričakovanim vzorcem:
// 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);
}
Primeri implementacije
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
}
}
Splet (strežniška stran)
// 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' });
}
});
Oblika odgovora
Uspešen odziv
{
"messagelistId": 123456,
"messages": [
{
"messageId": "abc123def456",
"status": "accepted",
"callerId": "+380123456789",
"pattern": "***456789",
"to": "+380XXXXXXXXX",
"ttl": 60
}
]
}
Polja odgovora
| Polje | Vrsta | Opis |
|---|---|---|
id sporočila |
niz | Enolični ID preverjanja |
stanje |
niz | Status: sprejeto, zavrnjeno |
callerId |
niz | Polna ID številka klicatelja |
vzorec |
niz | Vzorec za ujemanje (številke + zvezdice) |
do |
niz | Telefonska številka prejemnika |
ttl |
celo število | Obdobje veljavnosti v sekundah |
Ujemanje vzorcev
API vrne vzorec z zvezdicami, ki prikrije nekaj števk:
Vaša aplikacija bi morala:
- Zajemite ID dohodnega klicatelja
- Izvlecite številke iz ID-ja klicatelja
- Ujemanje z vzorcem (zvezdice = katera koli številka)
- Preverite ujemanje v obdobju TTL
Nazaj na SMS
Če Flash Call ne uspe, se samodejno vrnite na SMS:
{
"from": "YourApp",
"to": "+380XXXXXXXXX",
"type": "flashcall",
"messageData": {
"callerId": "+380123456789"
},
"fallback": {
"type": "sms",
"text": "Your verification code is: 123456"
},
"ttl": 60
}
Primeri uporabe
Registracija računa
Preverite telefonske številke med prijavo brez stroškov SMS-a.
Preverjanje prijave
Dvostopenjska avtentikacija z bliskovnim klicem.
Posodobitev telefonske številke
Preverite novo telefonsko številko, ko uporabnik posodobi profil.
Potrditev transakcije
Potrdite transakcije visoke vrednosti s hitrim klicem.
Najboljše prakse
TTL
- ✅ Nastavite TTL na 60-90 sekund
- ✅ Dovolite uporabniku, da po preteku poskusi znova
- ❌ TTL ne uporabljajte dlje kot 120 sekund
Uporabniška izkušnja
- Pokaži sporočilo "Čakanje na klic ...".
- Prikaz odštevalnika časa (60 sekund)
- Zagotovite možnost »Namesto tega uporabite SMS«
- Samodejno zaznavanje in preverjanje ID-ja klicatelja
Obravnava napak
- Obravnava manjkajoča dovoljenja za telefon
- Časovna omejitev po poteku TTL
- Zagotovite nadomestno možnost SMS
- Prikaži jasna sporočila o napakah
Dovoljenja
Zahtevaj telefonska dovoljenja pred hitrim klicem:
Android:
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
<uses-permission android:name="android.permission.READ_CALL_LOG" />
iOS:
Testiranje
- Test na različnih napravah
- Test z različnimi nosilci
- Preizkusite scenarije zavrnitve dovoljenja
- Preizkusite scenarije časovne omejitve omrežja
Omejitve
Podpora za platformo
- Deluje na vseh mobilnih napravah
- Zahteva možnost telefoniranja
- Potrebuje dovoljenje READ_PHONE_STATE
- Morda ne bo delovalo na tablicah brez telefona
Omrežje
- Zahteva aktivno telefonsko povezavo
- Lahko odpove v slabih omrežnih razmerah
- Morda veljajo omejitve operaterja
- Mednarodne cene se lahko razlikujejo
Zasebnost
- Uporabniki lahko blokirajo neznane številke
- Nekatere naprave imajo blokiranje klicev
- Zahteva izrecna dovoljenja
- Upoštevajte pomisleke glede zasebnosti uporabnikov
Odpravljanje težav
Klic ni prejet
- Preverite, ali ima telefon signal
- Preverite obliko številke (E.164)
- Preverite omejitve operaterja
- Poskusite nadomestni SMS
Vzorec se ne ujema
- Zagotovite zajem pravilne ID klicatelja
- Odstrani neštevilčne znake
- Preverite obliko vzorca
- Preverite v obdobju TTL
Dovoljenje zavrnjeno
- Pravilno zahtevajte dovoljenja
- Pojasnite, zakaj so potrebna dovoljenja
- Zagotovite alternativo (SMS)
- Ravnajte elegantno
Naslednji koraki
– Viber OTP – Nadomestna dostava OTP - Sporočila SMS - Nadomestni SMS - Preveri stanje - Sledite stanju hitrega klica