supersam/volumes/functions/check-sms-status/index.ts

132 lines
4.7 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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 });
}
});