Test ortamında OTPMOCK_URL=https://api.otpmock.com tanımlayın, Vonage istemcisini bu adrese yönlendirin ve Vonage kimlik bilgisi olarak otpmock API anahtarınızı kullanın. Uygulama kodunuz değişmez; canlı ortam Vonage ile göndermeye devam eder.
Kurulum
SDK'nın belgelenmiş restHost ve apiHost seçenekleri var.
import { Vonage } from "@vonage/server-sdk";
export const vonage = new Vonage(
{
apiKey: process.env.VONAGE_API_KEY,
apiSecret: process.env.VONAGE_API_SECRET, // testte: otpmock API anahtarı
applicationId: process.env.VONAGE_APPLICATION_ID, // testte: otpmock API anahtarı (Verify v2)
privateKey: process.env.VONAGE_PRIVATE_KEY,
},
process.env.OTPMOCK_URL ? { restHost: process.env.OTPMOCK_URL, apiHost: process.env.OTPMOCK_URL } : {},
);import os
from urllib.parse import urlparse
from vonage import Auth, HttpClientOptions, Vonage
otpmock = os.environ.get("OTPMOCK_URL") # e.g. https://api.otpmock.com
host = urlparse(otpmock).netloc if otpmock else None
vonage = Vonage(
Auth(api_key=os.environ["VONAGE_API_KEY"], api_secret=os.environ["VONAGE_API_SECRET"]), # secret = otpmock key in tests
HttpClientOptions(api_host=host, rest_host=host) if host else None,
)
# Verify v2 uses an application JWT (otpmock reads application_id, ignores the signature)
verify = Vonage(
Auth(application_id=os.environ["VONAGE_APPLICATION_ID"], # testte: otpmock API anahtarı
private_key=os.environ["VONAGE_PRIVATE_KEY"]),
HttpClientOptions(api_host=host) if host else None,
).verifyimport com.vonage.client.HttpConfig;
import com.vonage.client.VonageClient;
String otpmock = System.getenv("OTPMOCK_URL");
VonageClient.Builder builder = VonageClient.builder()
.apiKey(System.getenv("VONAGE_API_KEY"))
.apiSecret(System.getenv("VONAGE_API_SECRET")); // testte: otpmock API anahtarı
if (otpmock != null) builder.httpConfig(HttpConfig.builder().baseUri(otpmock).build());
VonageClient vonage = builder.build();// The Vonage .NET SDK reads its hosts from configuration (appsettings.json).
// In the test environment:
{
"vonage": {
"Url.Rest": "https://api.otpmock.com",
"Url.Api": "https://api.otpmock.com"
}
}
// Code stays the same:
var vonage = new VonageClient(Credentials.FromApiKeyAndSecret(apiKey, apiSecret)); // secret = otpmock key in tests
// Verify v2 over HTTPS (Basic auth with key and secret):
var vonageUrl = Environment.GetEnvironmentVariable("OTPMOCK_URL") ?? "https://api.nexmo.com";
var http = new HttpClient { BaseAddress = new Uri(vonageUrl) };
http.DefaultRequestHeaders.Authorization = new("Basic",
Convert.ToBase64String(Encoding.UTF8.GetBytes($"{apiKey}:{apiSecret}")));
// POST /v2/verify { brand, workflow = [{ channel = "sms", to }] } -> request_id
// POST /v2/verify/{request_id} { code } -> { status = "completed" }use Vonage\Client;
use Vonage\Client\Credentials\Basic;
$otpmock = getenv('OTPMOCK_URL');
$vonage = new Client(
new Basic(getenv('VONAGE_API_KEY'), getenv('VONAGE_API_SECRET')), // secret = otpmock key in tests
$otpmock ? ['base_rest_url' => $otpmock, 'base_api_url' => $otpmock] : [],
);
// Verify v2: application JWT (application_id = otpmock key in tests; signature not checked).
// verify2() hard-codes api.nexmo.com, so tests pass a host-rewriting Guzzle client.
$stack = \GuzzleHttp\HandlerStack::create();
if ($otpmock) {
$u = parse_url($otpmock);
$stack->push(\GuzzleHttp\Middleware::mapRequest(fn ($r) => $r->withUri(
$r->getUri()->withScheme($u['scheme'])->withHost($u['host'])->withPort($u['port'] ?? null))));
}
$verify = new Client(
new \Vonage\Client\Credentials\Keypair(file_get_contents(getenv('VONAGE_PRIVATE_KEY_PATH')), getenv('VONAGE_APPLICATION_ID')),
[], new \GuzzleHttp\Client(['handler' => $stack]),
);require "vonage"
require "uri"
otpmock = ENV["OTPMOCK_URL"] && URI(ENV["OTPMOCK_URL"])
host = otpmock && "#{otpmock.host}:#{otpmock.port}"
vonage = Vonage::Client.new(
api_key: ENV["VONAGE_API_KEY"],
api_secret: ENV["VONAGE_API_SECRET"], # testte: otpmock API anahtarı
**(host ? { api_host: host, rest_host: host } : {})
)
# Verify v2 (JWT): otpmock reads application_id as the key; signature not checked
verify = Vonage::Client.new(
application_id: ENV["VONAGE_APPLICATION_ID"], # testte: otpmock API anahtarı
private_key: File.read(ENV["VONAGE_PRIVATE_KEY_PATH"]),
**(host ? { api_host: host } : {})
).verify2auth := vonage.CreateAuthFromKeySecret(os.Getenv("VONAGE_API_KEY"), os.Getenv("VONAGE_API_SECRET")) // secret = otpmock key in tests
smsClient := vonage.NewSMSClient(auth)
if base := os.Getenv("OTPMOCK_URL"); base != "" {
smsClient.Config.BasePath = base + "/sms"
}
// Verify v2 (net/http): POST {base}/v2/verify, then POST {base}/v2/verify/{request_id} {"code": ...}
verifyBase := "https://api.nexmo.com"
if base := os.Getenv("OTPMOCK_URL"); base != "" {
verifyBase = base
}
req, _ := http.NewRequest("POST", verifyBase+"/v2/verify", bytes.NewReader(body))
req.SetBasicAuth(os.Getenv("VONAGE_API_KEY"), os.Getenv("VONAGE_API_SECRET")) // secret = otpmock key in testsHer dil, CI'da sağlayıcının resmi SDK'sıyla (ya da başka bir adrese yönlendirilemeyen SDK'larda düz HTTP API'siyle) otpmock'a karşı sınanır.
Kimlik bilgisi. Test ortamında VONAGE_API_SECRET değerini otpmock API anahtarınıza çevirin (SMS ve Messages API'leri Basic kimlik doğrulaması kullanır). SDK'nın JWT ile imzaladığı Verify v2 için VONAGE_APPLICATION_ID değerini de otpmock API anahtarınıza çevirin; otpmock JWT içindeki application_id alanını okur, imzayı denetlemez, bu yüzden alışık olduğunuz özel anahtar çalışmaya devam eder.
otpmock neyi taklit ediyor?
| Uç nokta | Ne yapar |
|---|---|
POST /sms/json | SMS API (rest.nexmo.com): SMS gönderir |
POST /v1/messages | Messages API; sms kanalı ve text mesaj türü |
POST /v2/verify | Verify v2: doğrulama başlatır (kodu otpmock üretir; code_length ve code dikkate alınır) |
POST /v2/verify/{request_id} | Verify v2: kodu kontrol eder (200 tamamlandı, 400 yanlış, 3 yanlış denemeden sonra 410) |
DELETE /v2/verify/{request_id} | Verify v2: iptal eder |
Yanıtlar ve hatalar Vonage API'sinin kendi biçimindedir, bu yüzden istemci kütüphanesi onları her zamanki gibi çözümler. Yanlış anahtar ve aylık hakkın dolması da aynı hata biçimiyle döner.
Telefon numaraları
Vonage numaraları başında + olmadan gönderir (15550142). otpmock bunları +15550142 olarak saklar; testte E.164 biçimiyle sorgulayabilirsiniz.
Testinizde kodu okuyun
const telefon = otp.randomPhone(); // her test için ayrı numara
const since = Date.now() - 5_000;
await page.getByRole("button", { name: "Kod gönder" }).click(); // uygulamanız Vonage API'sini çağırır
const { code } = await otp.waitForCode(telefon, { since });otp yardımcısı bağımlılığı olmayan tek bir dosyadır: dokümandan alın (İngilizce). Baştan sona örnekler: Playwright ve Cypress rehberleri (İngilizce).
Bilmeniz gerekenler
- Vonage'da olduğu gibi otpmock da aynı numaraya ikinci bir eşzamanlı Verify isteğini, ilki tamamlanana, iptal edilene ya da süresi dolana kadar 409 ile reddeder.
Sık sorulanlar
otpmock Vonage üzerinden gerçek SMS gönderiyor mu?
Hayır. Test ortamında uygulamanızın Vonage istekleri otpmock'a gider; mesaj 10 dakika saklanır ve Vonage ya da herhangi bir operatör ağına hiç ulaşmaz. Canlı ortamınız Vonage kullanmaya devam eder, çünkü otpmock yalnızca OTPMOCK_URL tanımlıyken devreye girer.
Resmi @vonage/server-sdk SDK'sı destekleniyor mu?
Evet. Vonage uç noktaları, resmi @vonage/server-sdk paketiyle Node.js'te uçtan uca sınanır. Adres değiştirmeye izin veren başka dillerdeki istemciler de çalışır.
otpmock hangi Vonage API'lerini destekliyor?
POST /sms/json (SMS API (rest.nexmo.com): SMS gönderir); POST /v1/messages (Messages API; sms kanalı ve text mesaj türü); POST /v2/verify (Verify v2: doğrulama başlatır (kodu otpmock üretir; code_length ve code dikkate alınır)); POST /v2/verify/{request_id} (Verify v2: kodu kontrol eder (200 tamamlandı, 400 yanlış, 3 yanlış denemeden sonra 410)); DELETE /v2/verify/{request_id} (Verify v2: iptal eder).
Ücretsiz plan ayda 300 mesaj içerir, kart gerekmez. Yapay zeka kodlama asistanı mı kullanıyorsunuz? otpmock.com/llms-full.txt adresini verin.
Ücretsiz API anahtarı al