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 = { "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 }); } });