export class ReOTPClient {
private apiKey: string;
private baseUrl: string;
constructor(apiKey: string, baseUrl: string = "https://your-domain.com") {
this.apiKey = apiKey;
this.baseUrl = baseUrl;
}
async verify(phoneNumber: string, method: "WHATSAPP" | "TELEGRAM" = "WHATSAPP") {
const res = await fetch(`${this.baseUrl}/api/verify/init`, {
method: "POST",
headers: {
"Content-Type": "application/json",
"Authorization": `Bearer ${this.apiKey}`
},
body: JSON.stringify({ phoneNumber, method })
});
if (!res.ok) throw new Error(await res.text());
return await res.json(); // { requestId, waLink, tgLink, expectedText }
}
async waitForVerification(requestId: string, timeoutMs: number = 120000): Promise<boolean> {
return new Promise((resolve, reject) => {
const EventSource = require('eventsource');
const evtSource = new EventSource(`${this.baseUrl}/api/verify/stream?id=${requestId}`);
const timeout = setTimeout(() => {
evtSource.close();
resolve(false);
}, timeoutMs);
evtSource.onmessage = (event: any) => {
const data = JSON.parse(event.data);
if (data.status === "VERIFIED") {
clearTimeout(timeout);
evtSource.close();
resolve(true);
} else if (data.status === "EXPIRED") {
clearTimeout(timeout);
evtSource.close();
reject(new Error("Session expired"));
} else if (data.status === "REJECTED") {
clearTimeout(timeout);
evtSource.close();
reject(new Error(data.failureReason || "Session rejected"));
}
};
evtSource.onerror = () => {
// Fallback or retry logic can be added here
};
});
}
}