Test ortamında OTPMOCK_URL=https://api.otpmock.com tanımlayın, Twilio istemcisini bu adrese yönlendirin ve Twilio kimlik bilgisi olarak otpmock API anahtarınızı kullanın. Uygulama kodunuz değişmez; canlı ortam Twilio ile göndermeye devam eder.
Kurulum
Resmi SDK özel bir HTTP istemcisi kabul ediyor. Buradaki istemci yolların hepsini koruyup yalnızca adresi değiştirir; böylece hem api.twilio.com hem verify.twilio.com trafiği otpmock'a gider. https://otpmock.com/sdk/twilio-node-client.mjs adresinden indirin.
import twilio from "twilio";
import { OtpMockHttpClient } from "./twilio-node-client.mjs";
export const sms = twilio(process.env.TWILIO_ACCOUNT_SID, process.env.TWILIO_AUTH_TOKEN, {
httpClient: process.env.OTPMOCK_URL ? new OtpMockHttpClient(process.env.OTPMOCK_URL) : undefined,
});import os
from urllib.parse import urlparse
from twilio.http.http_client import TwilioHttpClient
from twilio.rest import Client
class OtpMockHttpClient(TwilioHttpClient):
"""Sends Twilio SDK requests to otpmock, keeping path, params and auth."""
def __init__(self, base):
super().__init__()
self.base = base.rstrip("/")
def request(self, method, url, *args, **kwargs):
u = urlparse(url)
return super().request(method, self.base + u.path + ("?" + u.query if u.query else ""), *args, **kwargs)
otpmock = os.environ.get("OTPMOCK_URL")
client = Client(
os.environ["TWILIO_ACCOUNT_SID"],
os.environ["TWILIO_AUTH_TOKEN"], # testte: otpmock API anahtarı
http_client=OtpMockHttpClient(otpmock) if otpmock else None,
)import com.twilio.http.*;
import java.net.URI;
// Sends Twilio SDK requests to otpmock, keeping path, params and auth.
public class OtpMockTwilioHttpClient extends NetworkHttpClient {
private final String base;
public OtpMockTwilioHttpClient(String base) { this.base = base.replaceAll("/+$", ""); }
@Override
public Response makeRequest(Request request) {
Request routed = new Request(request.getMethod(), base + URI.create(request.getUrl()).getRawPath());
request.getQueryParams().forEach((k, vs) -> vs.forEach(v -> routed.addQueryParam(k, v)));
request.getPostParams().forEach((k, vs) -> vs.forEach(v -> routed.addPostParam(k, v)));
request.getHeaderParams().forEach((k, vs) -> vs.forEach(v -> routed.addHeaderParam(k, v)));
routed.setAuth(request.getUsername(), request.getPassword());
return super.makeRequest(routed);
}
}
// Where you build the client:
String otpmock = System.getenv("OTPMOCK_URL");
TwilioRestClient.Builder builder = new TwilioRestClient.Builder(accountSid, authToken); // testte: otpmock API anahtarı
if (otpmock != null) builder.httpClient(new OtpMockTwilioHttpClient(otpmock));
TwilioRestClient client = builder.build();
// Message.creator(...).create(client);using Twilio.Clients;
using Twilio.Http;
// Sends requests to otpmock, keeping path, query and auth headers.
class OtpMockHandler : DelegatingHandler
{
private readonly Uri _base;
public OtpMockHandler(string baseUrl) : base(new HttpClientHandler()) => _base = new Uri(baseUrl);
protected override Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken ct)
{
request.RequestUri = new Uri(_base, request.RequestUri!.PathAndQuery);
return base.SendAsync(request, ct);
}
}
var otpmock = Environment.GetEnvironmentVariable("OTPMOCK_URL");
var client = new TwilioRestClient(
accountSid,
authToken, // testte: otpmock API anahtarı
httpClient: otpmock is null ? null : new SystemNetHttpClient(new HttpClient(new OtpMockHandler(otpmock))));
// await MessageResource.CreateAsync(..., client: client);use Twilio\Http\CurlClient;
use Twilio\Rest\Client;
// Sends Twilio SDK requests to otpmock, keeping path, params and auth.
class OtpMockTwilioClient extends CurlClient {
public function __construct(private string $base) { parent::__construct(); }
public function request(string $method, string $url, array $params = [], array $data = [], array $headers = [],
?string $user = null, ?string $password = null, ?int $timeout = null, ?\Twilio\AuthStrategy\AuthStrategy $authStrategy = null): \Twilio\Http\Response {
return parent::request($method, rtrim($this->base, '/') . parse_url($url, PHP_URL_PATH), $params, $data, $headers, $user, $password, $timeout, $authStrategy);
}
}
$otpmock = getenv('OTPMOCK_URL');
$client = new Client(
getenv('TWILIO_ACCOUNT_SID'),
getenv('TWILIO_AUTH_TOKEN'), // testte: otpmock API anahtarı
null, null,
$otpmock ? new OtpMockTwilioClient($otpmock) : null,
);require "twilio-ruby"
require "uri"
# Sends Twilio SDK requests to otpmock, keeping path, params and auth.
class OtpMockHttpClient < Twilio::HTTP::Client
def initialize(base)
super()
@base = URI(base)
end
def request(_host, _port, method, url, *rest)
u = URI(url)
path = u.path + (u.query ? "?#{u.query}" : "")
super("#{@base.scheme}://#{@base.host}", @base.port, method, "#{@base.scheme}://#{@base.host}:#{@base.port}#{path}", *rest)
end
end
otpmock = ENV["OTPMOCK_URL"]
client = Twilio::REST::Client.new(
ENV["TWILIO_ACCOUNT_SID"],
ENV["TWILIO_AUTH_TOKEN"], # testte: otpmock API anahtarı
nil, nil,
otpmock ? OtpMockHttpClient.new(otpmock) : nil
)// otpmockTransport sends SDK requests to otpmock, keeping path, query and auth.
type otpmockTransport struct{ base *url.URL }
func (t otpmockTransport) RoundTrip(r *http.Request) (*http.Response, error) {
r = r.Clone(r.Context())
r.URL.Scheme, r.URL.Host, r.Host = t.base.Scheme, t.base.Host, t.base.Host
return http.DefaultTransport.RoundTrip(r)
}
func newTwilio() *twilio.RestClient {
// token = testte: otpmock API anahtarı. twilio-go only accepts letters and digits here,
// so use the key without underscores (om_live_abc… -> omliveabc…); otpmock accepts both forms.
sid, token := os.Getenv("TWILIO_ACCOUNT_SID"), os.Getenv("TWILIO_AUTH_TOKEN")
params := twilio.ClientParams{Username: sid, Password: token}
if base, err := url.Parse(os.Getenv("OTPMOCK_URL")); err == nil && base.Host != "" {
c := &client.Client{Credentials: client.NewCredentials(sid, token), HTTPClient: &http.Client{Transport: otpmockTransport{base}}}
c.SetAccountSid(sid)
params.Client = c
}
return twilio.NewRestClientWithParams(params)
}Her 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 TWILIO_AUTH_TOKEN değerini otpmock API anahtarınıza çevirin. Account SID olduğu gibi kalabilir; otpmock onu yanıtta aynen geri verir.
otpmock neyi taklit ediyor?
| Uç nokta | Ne yapar |
|---|---|
POST /2010-04-01/Accounts/{AccountSid}/Messages.json | Programmable Messaging: SMS gönderir |
POST /v2/Services/{ServiceSid}/Verifications | Verify v2: doğrulama başlatır (otpmock 6 haneli kod üretir) |
POST /v2/Services/{ServiceSid}/VerificationCheck | Verify v2: kodu kontrol eder (approved / pending, 5 deneme) |
Yanıtlar ve hatalar Twilio 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ı
E.164 biçiminde (+15550142) gönderin, Twilio da böyle bekler.
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 Twilio 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
- Twilio'nun kendi test kimlik bilgileri yalnızca birkaç kaynağı kapsar, Verify'ı kapsamaz. otpmock hem Messaging'i hem Verify'ı karşılar.
- Go SDK'sı (twilio-go) yetki belirtecinde harf ve rakam dışında karakter kabul etmez. otpmock anahtarınızı alt çizgisiz kullanın (
om_live_abc…yerineomliveabc…); otpmock iki biçimi de aynı anahtar sayar.
Sık sorulanlar
otpmock Twilio üzerinden gerçek SMS gönderiyor mu?
Hayır. Test ortamında uygulamanızın Twilio istekleri otpmock'a gider; mesaj 10 dakika saklanır ve Twilio ya da herhangi bir operatör ağına hiç ulaşmaz. Canlı ortamınız Twilio kullanmaya devam eder, çünkü otpmock yalnızca OTPMOCK_URL tanımlıyken devreye girer.
Resmi twilio SDK'sı destekleniyor mu?
Evet. Twilio uç noktaları, resmi twilio 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 Twilio API'lerini destekliyor?
POST /2010-04-01/Accounts/{AccountSid}/Messages.json (Programmable Messaging: SMS gönderir); POST /v2/Services/{ServiceSid}/Verifications (Verify v2: doğrulama başlatır (otpmock 6 haneli kod üretir)); POST /v2/Services/{ServiceSid}/VerificationCheck (Verify v2: kodu kontrol eder (approved / pending, 5 deneme)).
Ü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