113 lines
3.0 KiB
TypeScript
113 lines
3.0 KiB
TypeScript
import {
|
|
channelFromProvider,
|
|
createServiceClient,
|
|
json,
|
|
normalizeIncomingEvent,
|
|
orderUpdateByAction,
|
|
type ProviderName,
|
|
} from "../_shared/chatbot.ts";
|
|
|
|
const corsHeaders = {
|
|
"Access-Control-Allow-Origin": "*",
|
|
"Access-Control-Allow-Headers": "authorization, x-client-info, apikey, content-type",
|
|
};
|
|
|
|
Deno.serve(async (request) => {
|
|
if (request.method === "OPTIONS") {
|
|
return new Response("ok", { headers: corsHeaders });
|
|
}
|
|
|
|
try {
|
|
const url = new URL(request.url);
|
|
const provider = url.searchParams.get("provider") as ProviderName | null;
|
|
if (!provider) {
|
|
return json({ error: "provider is required" }, 400);
|
|
}
|
|
|
|
const body = (await request.json()) as Record<string, unknown>;
|
|
const event = normalizeIncomingEvent(provider, body);
|
|
if (!event.orderId) {
|
|
return json({ error: "order_id is required" }, 400);
|
|
}
|
|
|
|
const supabase = createServiceClient();
|
|
const orderUpdate = orderUpdateByAction(event.action);
|
|
|
|
const messagePayload = {
|
|
order_id: event.orderId,
|
|
sender_name: "chatbot-webhook",
|
|
sender_type: event.senderType,
|
|
channel: channelFromProvider(event.provider),
|
|
text: event.text || `Inbound ${event.provider} event`,
|
|
external_message_id: event.externalMessageId,
|
|
payload: event.payload,
|
|
};
|
|
|
|
const { error: messageError } = await supabase.from("chat_messages").insert(messagePayload);
|
|
if (messageError) {
|
|
throw messageError;
|
|
}
|
|
|
|
if (orderUpdate) {
|
|
const { data: currentOrder, error: orderError } = await supabase
|
|
.from("orders")
|
|
.select("id, status, delivery_agreement_status")
|
|
.eq("id", event.orderId)
|
|
.single();
|
|
|
|
if (orderError) {
|
|
throw orderError;
|
|
}
|
|
|
|
const { error: updateError } = await supabase
|
|
.from("orders")
|
|
.update({
|
|
status: orderUpdate.status,
|
|
delivery_agreement_status: orderUpdate.deliveryAgreementStatus,
|
|
})
|
|
.eq("id", event.orderId);
|
|
|
|
if (updateError) {
|
|
throw updateError;
|
|
}
|
|
|
|
const { error: historyError } = await supabase.from("order_history").insert({
|
|
order_id: event.orderId,
|
|
action: `Webhook ${provider}: ${event.action}`,
|
|
old_status: currentOrder.status,
|
|
new_status: orderUpdate.status,
|
|
metadata: {
|
|
...event.payload,
|
|
old_delivery_agreement_status: currentOrder.delivery_agreement_status,
|
|
new_delivery_agreement_status: orderUpdate.deliveryAgreementStatus,
|
|
},
|
|
});
|
|
|
|
if (historyError) {
|
|
throw historyError;
|
|
}
|
|
}
|
|
|
|
return new Response(JSON.stringify({ ok: true }), {
|
|
headers: {
|
|
...corsHeaders,
|
|
"Content-Type": "application/json",
|
|
},
|
|
});
|
|
} catch (error) {
|
|
return new Response(
|
|
JSON.stringify({
|
|
ok: false,
|
|
error: error instanceof Error ? error.message : "Unexpected error",
|
|
}),
|
|
{
|
|
status: 500,
|
|
headers: {
|
|
...corsHeaders,
|
|
"Content-Type": "application/json",
|
|
},
|
|
},
|
|
);
|
|
}
|
|
});
|