שיחת הבזק
Flash Call היא שיטת אימות טלפונית המשתמשת בשיחה שלא נענתה במקום ב-SMS כדי לאמת מספרי טלפון. זה מהיר יותר, בטוח יותר וחסכוני יותר.
סקירה כללית
אימות שיחת פלאש פועל על ידי:
- משתמש מבקש אימות
- המערכת יוזמת שיחה לטלפון של המשתמש
- השיחה מופסקת אוטומטית לאחר 1-2 צלצולים
- האפליקציה של המשתמש לוכדת את זיהוי המתקשר
- זיהוי המתקשר מאומת כנגד הדפוס הצפוי
- המשתמש מאומת
הטבות
חסכוני
- זול עד פי 10 מ-SMS
- ללא דמי משלוח הודעות
- עלויות מופחתות עבור אימות בנפח גבוה
מהיר יותר
- אימות מיידי (1-3 שניות)
- אין המתנה למשלוח SMS
- חווית משתמש טובה יותר
מאובטח יותר
- קשה יותר ליירט מאשר SMS
- אין OTP גלוי בהודעות
- עמיד בפני התקפות החלפת SIM
טווח עולמי
- עובד במדינות עם הגבלות SMS
- אין בעיות עם סינון SMS
- תאימות טלפון אוניברסלית
שיחת פלאש בסיסית
בקשה
{
"from": "YourApp",
"to": "+380XXXXXXXXX",
"type": "flashcall",
"messageData": {
"callerId": "+380123456789"
}
}
פרמטרים
| פרמטר | הקלד | חובה | תיאור |
|---|---|---|---|
מ |
מחרוזת | כן | מזהה השולח שלך |
אל |
מחרוזת | כן | מספר הטלפון של הנמען (E.164) |
סוג |
מחרוזת | כן | הגדר ל-"שיחת הבזק" |
CallerId |
מחרוזת | כן | מספר טלפון שיתקשר למשתמש |
ttl |
מספר שלם | לא | זמן חיים בשניות (ברירת מחדל: 60) |
איך זה עובד
1. משתמש מזין מספר טלפון
המשתמש מספק את מספר הטלפון שלו באפליקציה שלך:
2. בקש שיחת הבזק
השרת שלך מבקש אימות שיחת הבזק:
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
API מחזיר את דפוס זיהוי המתקשר הצפוי:
{
"messagelistId": 123456,
"messages": [
{
"messageId": "abc123def456",
"status": "accepted",
"callerId": "+380123456789",
"pattern": "***456789",
"to": "+380XXXXXXXXX"
}
]
}
4. התחל שיחה
המערכת יוזמת שיחה לטלפון של המשתמש ומסתיימת לאחר 1-2 צלצולים.
5. לכידת זיהוי מתקשר
האפליקציה של המשתמש לוכדת את זיהוי המתקשר של השיחה הנכנסת:
// Android example
val cursor = contentResolver.query(
CallLog.Calls.CONTENT_URI,
arrayOf(CallLog.Calls.NUMBER),
null, null,
CallLog.Calls.DATE + " DESC"
)
6. אמת את התבנית
השווה את זיהוי המתקשר שנקלט לדפוס הצפוי:
// 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);
}
דוגמאות ליישום
אנדרואיד
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
}
}
אינטרנט (צד השרת)
// 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' });
}
});
פורמט תגובה
תגובת הצלחה
{
"messagelistId": 123456,
"messages": [
{
"messageId": "abc123def456",
"status": "accepted",
"callerId": "+380123456789",
"pattern": "***456789",
"to": "+380XXXXXXXXX",
"ttl": 60
}
]
}
שדות תגובה
| שדה | הקלד | תיאור |
|---|---|---|
messageId |
מחרוזת | מזהה אימות ייחודי |
סטטוס |
מחרוזת | סטטוס: מקובל, נדחה |
CallerId |
מחרוזת | מספר זיהוי מתקשר מלא |
דפוס |
מחרוזת | דפוס להתאמה (ספרות + כוכביות) |
אל |
מחרוזת | מספר טלפון של הנמען |
ttl |
מספר שלם | תקופת תוקף בשניות |
התאמת דפוסים
ה-API מחזיר דפוס עם כוכביות המסתרות מספר ספרות:
האפליקציה שלך צריכה:
- לכידת זיהוי מתקשר נכנס
- חלץ ספרות מזיהוי המתקשר
- התאמה לדפוס (כוכביות = כל ספרה)
- אמת התאמה בתוך תקופת TTL
חזרה ל-SMS
אם שיחת הבזק נכשלת, חזור אוטומטית ל-SMS:
{
"from": "YourApp",
"to": "+380XXXXXXXXX",
"type": "flashcall",
"messageData": {
"callerId": "+380123456789"
},
"fallback": {
"type": "sms",
"text": "Your verification code is: 123456"
},
"ttl": 60
}
מקרי שימוש
רישום חשבון
אמת מספרי טלפון במהלך ההרשמה ללא עלויות SMS.
אימות התחברות
אימות דו-גורמי באמצעות שיחת הבזק.
עדכון מספר טלפון
אמת מספר טלפון חדש כאשר המשתמש מעדכן את הפרופיל.
אישור עסקה
אשר עסקאות בעלות ערך גבוה באמצעות שיחת הבזק.
שיטות עבודה מומלצות
TTL
- ✅ הגדר את TTL ל-60-90 שניות
- ✅ אפשר למשתמש לנסות שוב לאחר התפוגה
- ❌ אל תשתמש ב-TTL יותר מ-120 שניות
חווית משתמש
- הצג את הודעת "ממתין לשיחה...".
- הצג טיימר ספירה לאחור (60 שניות)
- ספק אפשרות "השתמש ב-SMS במקום"
- זיהוי אוטומטי ואימות של זיהוי מתקשר
טיפול בשגיאות
- טיפול בהרשאות טלפון חסרות
- פסק זמן לאחר תום ה-TTL
- ספק אפשרות חילופי SMS
- הצג הודעות שגיאה ברורות
הרשאות
בקש הרשאות טלפון לפני שיחת הבזק:
אנדרואיד:
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
<uses-permission android:name="android.permission.READ_CALL_LOG" />
iOS:
בדיקה
- בדוק במכשירים שונים
- בדיקה עם מנשאים שונים
- בדיקת תרחישי שלילת הרשאה
- בדוק את תרחישי הזמן הקצוב של הרשת
מגבלות
תמיכה בפלטפורמה
- עובד על כל המכשירים הניידים
- דורש יכולת שיחת טלפון
- צריך הרשאת READ_PHONE_STATE
- ייתכן שלא יפעל בטאבלטים ללא טלפון
רשת
- דורש חיבור טלפון פעיל
- עלול להיכשל בתנאי רשת גרועים
- עשויות לחול הגבלות על הספק
- תעריפים בינלאומיים עשויים להשתנות
פרטיות
- משתמשים עשויים לחסום מספרים לא ידועים
- בחלק מהמכשירים יש חסימת שיחות
- דורש הרשאות מפורשות
- שקול את חששות פרטיות המשתמש
פתרון בעיות
שיחה לא התקבלה
- בדוק שיש אות לטלפון
- אימות פורמט מספר (E.164)
- בדוק את הגבלות הספק
- נסה חזרה של SMS
תבנית לא תואמת
- ודא לכידת זיהוי מתקשר נכון
- הסר תווים שאינם ספרות
- בדוק את פורמט הדפוס
- אמת בתוך תקופת TTL
ההרשאה נדחתה
- בקש הרשאות כראוי
- הסבר מדוע יש צורך בהרשאות
- ספק חלופה (SMS)
- טפל בחן
השלבים הבאים
- Viber OTP - משלוח OTP חלופי
- הודעות SMS - חזרה של SMS
- בדוק סטטוס - עקוב אחר מצב שיחת הבזק