132 lines
4.7 KiB
TypeScript
132 lines
4.7 KiB
TypeScript
import { createClient } from "npm:@supabase/supabase-js@2";
|
||
|
||
const ALLOWED_ORIGINS = [
|
||
"https://dost.supersamsev.ru",
|
||
"https://supa.supersamsev.ru",
|
||
"http://localhost:5173",
|
||
];
|
||
|
||
const SMS_STATUS_URL = "https://sms.ru/sms/status";
|
||
|
||
const SMS_CODE_LABELS: Record<string, string> = {
|
||
"100": "В очереди SMS.ru",
|
||
"101": "Передано оператору",
|
||
"102": "В пути",
|
||
"103": "Доставлено",
|
||
"104": "Истёкло время",
|
||
"105": "Удалено оператором",
|
||
"106": "Сбой телефона",
|
||
"107": "Неизвестная причина",
|
||
"108": "Отклонено",
|
||
"130": "Лимит на номер/день",
|
||
"131": "Лимит одинаковых/мин",
|
||
"132": "Лимит одинаковых/день",
|
||
"200": "Неправильный api_id",
|
||
"201": "Недостаточно средств",
|
||
"202": "Неправильный получатель",
|
||
"230": "Общий лимит/день",
|
||
"231": "Лимит одинаковых/мин",
|
||
"232": "Лимит одинаковых/день",
|
||
};
|
||
|
||
const cors = (origin: string) => ({
|
||
"Access-Control-Allow-Origin": ALLOWED_ORIGINS.includes(origin) ? origin : ALLOWED_ORIGINS[0],
|
||
"Access-Control-Allow-Methods": "POST,OPTIONS",
|
||
"Access-Control-Allow-Headers": "Content-Type,Authorization,apikey",
|
||
});
|
||
|
||
Deno.serve(async (req: Request) => {
|
||
const origin = req.headers.get("origin") || "";
|
||
const headers = { ...cors(origin), "Content-Type": "application/json" };
|
||
|
||
if (req.method === "OPTIONS") return new Response(null, { headers });
|
||
|
||
try {
|
||
const { log_id } = await req.json();
|
||
if (!log_id) return new Response(JSON.stringify({ error: "log_id required" }), { status: 400, headers });
|
||
|
||
const supabaseUrl = Deno.env.get("SUPABASE_URL") || "";
|
||
const serviceKey = Deno.env.get("SUPABASE_SERVICE_ROLE_KEY") || "";
|
||
const sb = createClient(supabaseUrl, serviceKey);
|
||
|
||
// Fetch log entry
|
||
const { data: logRow, error: logErr } = await sb
|
||
.from("sms_campaign_log")
|
||
.select("id, sms_id, campaign_type, order_group_id, attempts")
|
||
.eq("id", log_id)
|
||
.single();
|
||
if (logErr || !logRow) return new Response(JSON.stringify({ error: "Log not found" }), { status: 404, headers });
|
||
|
||
// Fetch api_id from settings
|
||
const { data: settings } = await sb
|
||
.from("sms_campaign_settings")
|
||
.select("sms_api_id")
|
||
.eq("campaign_type", logRow.campaign_type)
|
||
.single();
|
||
const apiId = settings?.sms_api_id || Deno.env.get("SMS_API_ID") || "";
|
||
|
||
if (!logRow.sms_id) return new Response(JSON.stringify({ error: "No sms_id in log" }), { status: 400, headers });
|
||
|
||
// Call SMS.ru status API
|
||
const formData = new URLSearchParams();
|
||
formData.append("api_id", apiId);
|
||
formData.append("sms_id", logRow.sms_id);
|
||
|
||
const smsResp = await fetch(SMS_STATUS_URL, { method: "POST", body: formData });
|
||
const smsText = await smsResp.text();
|
||
const lines = smsText.split("\n").map((l: string) => l.trim());
|
||
const code = lines[0] || "";
|
||
|
||
// Determine status
|
||
const status =
|
||
code === "103" ? "delivered" :
|
||
["100", "101", "102"].includes(code) ? "checking" :
|
||
["104", "105", "106", "107", "108", "130"].includes(code) ? "error" :
|
||
["131", "132", "230", "231", "232"].includes(code) ? "limit_exceeded" :
|
||
"checking";
|
||
|
||
// Update log entry
|
||
const now = new Date().toISOString();
|
||
await sb.from("sms_campaign_log").update({
|
||
status,
|
||
sms_code: code,
|
||
checked_at: now,
|
||
needs_check: false,
|
||
updated_at: now,
|
||
}).eq("id", log_id);
|
||
|
||
// Update order_groups if delivered
|
||
if (code === "103" && logRow.order_group_id) {
|
||
const nextCheck = new Date(Date.now() + 3 * 3600 * 1000).toISOString();
|
||
if (logRow.campaign_type === "first_sms") {
|
||
await sb.from("order_groups").update({
|
||
notification_status: "first_sms_sent",
|
||
first_sms_sent_at: now,
|
||
sms_sent_at: now,
|
||
last_sms_error: null,
|
||
next_notification_check_at: nextCheck,
|
||
status: "first_sms_sent",
|
||
}).eq("id", logRow.order_group_id);
|
||
} else if (logRow.campaign_type === "second_sms") {
|
||
await sb.from("order_groups").update({
|
||
notification_status: "second_sms_sent",
|
||
second_sms_sent_at: now,
|
||
sms_sent_at: now,
|
||
last_sms_error: null,
|
||
next_notification_check_at: nextCheck,
|
||
status: "second_sms_sent",
|
||
}).eq("id", logRow.order_group_id);
|
||
}
|
||
}
|
||
|
||
return new Response(JSON.stringify({
|
||
success: true,
|
||
sms_id: logRow.sms_id,
|
||
code,
|
||
status,
|
||
label: SMS_CODE_LABELS[code] || "Код " + code,
|
||
}), { headers });
|
||
} catch (e) {
|
||
return new Response(JSON.stringify({ error: String(e) }), { status: 500, headers });
|
||
}
|
||
}); |