Hızlı Arama
Hızlı Arama, telefon numaralarını doğrulamak için SMS yerine cevapsız aramayı kullanan bir telefon doğrulama yöntemidir. Daha hızlı, daha güvenli ve uygun maliyetlidir.
Genel Bakış
Hızlı Arama doğrulaması şu şekilde çalışır:
- Kullanıcı doğrulama ister
- Sistem kullanıcının telefonuna bir çağrı başlatır
- Arama 1-2 kez çaldıktan sonra otomatik olarak sonlandırılır
- Kullanıcının uygulaması arayanın kimliğini yakalar
- Arayanın kimliği beklenen modele göre doğrulanır
- Kullanıcının kimliği doğrulandı
Faydaları
Uygun Maliyetli
- SMS'den 10 kata kadar daha ucuz
- Mesaj teslim ücreti yok
- Yüksek hacimli doğrulama için azaltılmış maliyetler
Daha hızlı
- Anında doğrulama (1-3 saniye)
- SMS teslimatını beklemek yok
- Daha iyi kullanıcı deneyimi
Daha Güvenli
- SMS'e müdahale etmekten daha zor
- Bildirimlerde OTP görünmüyor
- SIM değiştirme saldırılarına karşı dayanıklı
Küresel Erişim
- SMS kısıtlaması olan ülkelerde çalışır
- SMS filtrelemede sorun yok
- Evrensel telefon uyumluluğu
Temel Hızlı Arama
Talep
{
"from": "YourApp",
"to": "+380XXXXXXXXX",
"type": "flashcall",
"messageData": {
"callerId": "+380123456789"
}
}
Parametreler
| Parametre | Tür | Gerekli | Açıklama |
|---|---|---|---|
| 'dan' | dize | Evet | Gönderenin kimliğiniz |
| 'e' | dize | Evet | Alıcının telefon numarası (E.164) |
| 'tür' | dize | Evet | "Flashcall" olarak ayarla |
| 'arayanın kimliği' | dize | Evet | Kullanıcıyı arayacak telefon numarası |
| 'ttl' | tamsayı | Hayır | Saniye cinsinden yaşam süresi (varsayılan: 60) |
Nasıl Çalışır?
1. Kullanıcı Telefon Numarasını Girer
Kullanıcı uygulamanızda telefon numarasını sağlar:
2. Hızlı Arama İste
Sunucunuz hızlı arama doğrulaması istiyor:
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 Yanıtı
API, beklenen arayan kimliği modelini döndürür:
{
"messagelistId": 123456,
"messages": [
{
"messageId": "abc123def456",
"status": "accepted",
"callerId": "+380123456789",
"pattern": "***456789",
"to": "+380XXXXXXXXX"
}
]
}
4. Aramayı Başlat
Sistem kullanıcının telefonuna çağrı başlatır ve 1-2 çalıştan sonra sonlandırılır.
5. Arayan Kimliğini Yakala
Kullanıcının uygulaması, gelen aramanın arayan kimliğini yakalar:
// Android example
val cursor = contentResolver.query(
CallLog.Calls.CONTENT_URI,
arrayOf(CallLog.Calls.NUMBER),
null, null,
CallLog.Calls.DATE + " DESC"
)
6. Deseni Doğrulayın
Yakalanan arayan kimliğini beklenen modelle karşılaştırın:
// 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);
}
Uygulama Örnekleri
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 (Sunucu Tarafı)
// 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' });
}
});
Yanıt Formatı
Başarılı Yanıt
{
"messagelistId": 123456,
"messages": [
{
"messageId": "abc123def456",
"status": "accepted",
"callerId": "+380123456789",
"pattern": "***456789",
"to": "+380XXXXXXXXX",
"ttl": 60
}
]
}
Yanıt Alanları
| Alan | Tür | Açıklama |
|---|---|---|
| 'mesaj Kimliği' | dize | Benzersiz doğrulama kimliği |
| 'durum' | dize | Durum: 'kabul edildi', 'reddedildi' |
| 'arayanın kimliği' | dize | Arayanın tam kimlik numarası |
| 'desen' | dize | Eşleşecek desen (rakamlar + yıldız işaretleri) |
| 'e' | dize | Alıcının telefon numarası |
| 'ttl' | tamsayı | Saniye cinsinden geçerlilik süresi |
Desen Eşleştirme
API, bazı rakamları maskeleyen yıldız işaretlerine sahip bir model döndürür:
Uygulamanız:
- Gelen arayan kimliğini yakalayın
- Arayanın kimliğinden rakamları çıkarın
- Desene göre eşleştirme (yıldız işaretleri = herhangi bir rakam)
- TTL süresi içinde eşleşmeyi doğrulayın
SMS'e geri dönüş
Hızlı Arama başarısız olursa otomatik olarak SMS'e geri dönün:
{
"from": "YourApp",
"to": "+380XXXXXXXXX",
"type": "flashcall",
"messageData": {
"callerId": "+380123456789"
},
"fallback": {
"type": "sms",
"text": "Your verification code is: 123456"
},
"ttl": 60
}
Kullanım Durumları
Hesap Kaydı
Verify phone numbers during signup without SMS costs.
Giriş Doğrulaması
Hızlı çağrı kullanarak iki faktörlü kimlik doğrulama.
Telefon Numarası Güncellemesi
Kullanıcı profili güncellediğinde yeni telefon numarasını doğrulayın.
İşlem Onayı
Yüksek değerli işlemleri hızlı aramayla onaylayın.
En İyi Uygulamalar
TTL
- ✅ TTL'yi 60-90 saniyeye ayarlayın
- ✅ Kullanıcının süre dolduktan sonra yeniden denemesine izin ver
- ❌ TTL'yi 120 saniyeden uzun süre kullanmayın
Kullanıcı Deneyimi
- "Çağrı bekleniyor..." mesajını göster
- Geri sayım sayacını göster (60 saniye)
- "Bunun yerine SMS kullan" seçeneğini sunun
- Arayanın kimliğini otomatik olarak algıla ve doğrula
Hata İşleme
- Eksik telefon izinlerini yönetin
- TTL'nin süresi dolduktan sonra zaman aşımı
- SMS geri dönüş seçeneği sağlayın
- Net hata mesajlarını göster
İzinler
Hızlı aramadan önce telefon izinlerini isteyin:
Android:
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
<uses-permission android:name="android.permission.READ_CALL_LOG" />
iOS:
Test
- Farklı cihazlarda test edin
- Farklı operatörlerle test edin
- İzin reddi senaryolarını test edin
- Ağ zaman aşımı senaryolarını test edin
Sınırlamalar
Platform Desteği
- Tüm mobil cihazlarda çalışır
- Telefon görüşmesi özelliği gerektirir
- READ_PHONE_STATE izni gerekiyor
- Telefonsuz tabletlerde çalışmayabilir
Ağ
- Aktif telefon bağlantısı gerektirir
- Kötü ağ koşullarında başarısız olabilir
- Taşıyıcı kısıtlamaları geçerli olabilir
- Uluslararası fiyatlar değişiklik gösterebilir
Gizlilik
- Kullanıcılar bilinmeyen numaraları engelleyebilir
- Bazı cihazlarda çağrı engelleme özelliği vardır
- Açık izinler gerektirir
- Kullanıcı gizliliği endişelerini göz önünde bulundurun
Sorun Giderme
Çağrı Alınmadı
- Telefonun sinyali olup olmadığını kontrol edin
- Sayı biçimini doğrulayın (E.164)
- Operatör kısıtlamalarını kontrol edin
- SMS geri dönüşünü deneyin
Desen Eşleşmiyor
- Doğru arayan kimliğini yakaladığınızdan emin olun
- Rakam olmayan karakterleri soyun
- Desen formatını kontrol edin
- TTL süresi içinde doğrulayın
İzin Reddedildi
- İzinleri doğru şekilde isteyin
- İzinlerin neden gerekli olduğunu açıklayın
- Alternatif sağlayın (SMS)
- İncelikle kullanın
Sonraki Adımlar
- Viber OTP - Alternatif OTP dağıtımı
- SMS Mesajları - Yedek SMS
- Durumu Kontrol Et - Hızlı arama durumunu takip et