Flash Call
Flash Call ir tālruņa verifikācijas metode, kas izmanto neatbildētu zvanu, nevis īsziņu, lai pārbaudītu tālruņa numurus. Tas ir ātrāk, drošāk un izmaksu ziņā izdevīgāk.
Pārskats
Flash Call verifikācija darbojas, izmantojot:
1. Lietotājs pieprasa verifikāciju 2. Sistēma uzsāk zvanu uz lietotāja tālruni 3. Saruna tiek automātiski pārtraukta pēc 1-2 zvaniem 4. Lietotāja lietotne fiksē zvanītāja ID 5. Zvanītāja ID tiek pārbaudīts, salīdzinot ar paredzamo modeli 6. Lietotājs ir autentificēts
Ieguvumi
Rentabli
- Līdz 10x lētāk nekā SMS
- Nav ziņojumu piegādes maksas
- Samazinātas liela apjoma verifikācijas izmaksas
Ātrāk
- Tūlītēja pārbaude (1–3 sekundes)
- Nav jāgaida SMS piegāde
- Labāka lietotāja pieredze
Drošāka
- Grūtāk pārtvert nekā SMS
- Paziņojumos nav redzama OTP
- Izturīgs pret SIM maiņas uzbrukumiem
Globālā sasniedzamība
- Darbojas valstīs ar SMS ierobežojumiem
- Nav problēmu ar SMS filtrēšanu
- Universāla tālruņa saderība
Pamata zibatmiņas zvans
Pieprasījums
{
"from": "YourApp",
"to": "+380XXXXXXXXX",
"type": "flashcall",
"messageData": {
"callerId": "+380123456789"
}
}
Parametri
| Parametrs | Tips | Nepieciešams | Apraksts |
|---|---|---|---|
no |
stīga | Jā | Jūsu sūtītāja identifikators |
uz |
stīga | Jā | Saņēmēja tālruņa numurs (E.164) |
| "tips" | stīga | Jā | Iestatīt uz "flashcall" |
zvanītāja ID |
stīga | Jā | Tālruņa numurs, kas zvanīs lietotājam |
ttl |
vesels skaitlis | Nē | Dzīves laiks sekundēs (noklusējums: 60) |
Kā tas darbojas
1. Lietotājs ievada tālruņa numuru
Lietotājs jūsu lietotnē norāda savu tālruņa numuru:
2. Pieprasiet zibzvanu
Jūsu serveris pieprasa zibzvana verifikāciju:
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. API atbilde
API atgriež paredzamo zvanītāja ID modeli:
{
"messagelistId": 123456,
"messages": [
{
"messageId": "abc123def456",
"status": "accepted",
"callerId": "+380123456789",
"pattern": "***456789",
"to": "+380XXXXXXXXX"
}
]
}
4. Sāciet zvanu
Sistēma uzsāk zvanu uz lietotāja tālruni un beidz pēc 1-2 zvaniem.
5. Uzņemiet zvanītāja ID
Lietotāja lietotne fiksē ienākošā zvana zvanītāja ID:
// Android example
val cursor = contentResolver.query(
CallLog.Calls.CONTENT_URI,
arrayOf(CallLog.Calls.NUMBER),
null, null,
CallLog.Calls.DATE + " DESC"
)
6. Verify Pattern
Salīdziniet uzņemto zvanītāja ID ar paredzamo modeli:
// 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);
}
Īstenošanas piemēri
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
}
}
Tīmeklis (servera pusē)
// 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' });
}
});
Atbildes formāts
Veiksmīga atbilde
{
"messagelistId": 123456,
"messages": [
{
"messageId": "abc123def456",
"status": "accepted",
"callerId": "+380123456789",
"pattern": "***456789",
"to": "+380XXXXXXXXX",
"ttl": 60
}
]
}
Atbildes lauki
| Lauks | Tips | Apraksts |
|---|---|---|
messageId |
stīga | Unikāls verifikācijas ID |
statuss |
stīga | Statuss: "pieņemts", "noraidīts" |
zvanītāja ID |
stīga | Pilns zvanītāja ID numurs |
raksts |
stīga | Atbilstošais raksts (cipari + zvaigznītes) |
uz |
stīga | Saņēmēja tālruņa numurs |
ttl |
vesels skaitlis | Derīguma termiņš sekundēs |
Rakstu saskaņošana
API atgriež modeli ar zvaigznītēm, kas maskē dažus ciparus:
Jūsu lietotnei vajadzētu:
- Uzņemiet ienākošā zvanītāja ID
- Izņemiet ciparus no zvanītāja ID 3. Saskaņot paraugu (zvaigznītes = jebkurš cipars)
- Pārbaudiet atbilstību TTL periodā
Atkāpšanās uz SMS
Ja Flash Call neizdodas, automātiski atgriezieties pie SMS:
{
"from": "YourApp",
"to": "+380XXXXXXXXX",
"type": "flashcall",
"messageData": {
"callerId": "+380123456789"
},
"fallback": {
"type": "sms",
"text": "Your verification code is: 123456"
},
"ttl": 60
}
Lietošanas gadījumi
Konta reģistrācija
Reģistrācijas laikā pārbaudiet tālruņu numurus bez maksas par SMS.
Pieteikšanās verifikācija
Divu faktoru autentifikācija, izmantojot zibatmiņas zvanu.
Tālruņa numura atjaunināšana
Apstipriniet jauno tālruņa numuru, kad lietotājs atjaunina profilu.
Darījuma apstiprinājums
Apstipriniet lielas vērtības darījumus, izmantojot zibatmiņas zvanu.
Labākā prakse
TTL
- ✅ Iestatiet TTL uz 60-90 sekundēm
- ✅ Ļaujiet lietotājam mēģināt vēlreiz pēc derīguma termiņa beigām
- ❌ Neizmantojiet TTL ilgāk par 120 sekundēm
Lietotāja pieredze
- Parādiet ziņojumu "Gaida zvanu...".
- Displeja atpakaļskaitīšanas taimeris (60 sekundes)
- Nodrošiniet iespēju "Tā vietā izmantot SMS"
- Automātiski noteikt un pārbaudīt zvanītāja ID
Kļūdu apstrāde
- Apstrādājiet trūkstošās tālruņa atļaujas
- Taimauts pēc TTL termiņa beigām
- Nodrošiniet SMS atkāpšanās iespēju
- Rādīt skaidrus kļūdu ziņojumus
Atļaujas
Pieprasiet tālruņa atļaujas pirms zibatmiņas:
Android:
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
<uses-permission android:name="android.permission.READ_CALL_LOG" />
iOS:
Testēšana
- Testēšana dažādās ierīcēs
- Pārbaude ar dažādiem nesējiem - Pārbaudiet atļauju atteikuma scenārijus
- Pārbaudiet tīkla noildzes scenārijus
Ierobežojumi
Platformas atbalsts
- Darbojas visās mobilajās ierīcēs
- Nepieciešama tālruņa zvanu iespēja
- Nepieciešama READ_PHONE_STATE atļauja
- Var nedarboties planšetdatoros bez tālruņa
Tīkls
- Nepieciešams aktīvs tālruņa savienojums
- Sliktos tīkla apstākļos var neizdoties
- Var tikt piemēroti mobilo sakaru operatoru ierobežojumi
- Starptautiskie tarifi var atšķirties
Privātums
- Lietotāji var bloķēt nezināmus numurus
- Dažām ierīcēm ir zvanu bloķēšana
- Nepieciešamas skaidras atļaujas
- Apsveriet lietotāju konfidencialitātes problēmas
Traucējummeklēšana
Zvans nav saņemts
- Pārbaudiet, vai tālrunim ir signāls - Pārbaudiet skaitļa formātu (E.164)
- Pārbaudiet operatora ierobežojumus
- Izmēģiniet atkāpšanos no SMS
Raksts neatbilst
- Nodrošiniet pareizu zvanītāja ID uztveršanu - Noņemiet rakstzīmes, kas nav cipari
- Pārbaudiet modeļa formātu
- Pārbaudiet TTL periodā
Atļauja liegta
- Pieprasiet atļaujas pareizi - Paskaidrojiet, kāpēc nepieciešamas atļaujas
- Sniegt alternatīvu (SMS)
- Rīkojieties graciozi
Nākamie soļi
- Viber OTP - alternatīva OTP piegāde
- SMS Messages - SMS rezerves
- Pārbaudīt statusu - izsekojiet zibatmiņas zvanu statusu