Supabase Edge Function मा WhatsApp वेबहुक प्राप्त गर्ने तरिका
Supabase Edge Function सिधै नम्बरको वेबहुक गन्तव्य बन्न सक्छ। यसले Meta को प्रमाणीकरण GET लाई hub.challenge को मानसहित प्रतिक्रिया दिन्छ, POST भएर आएका हरेक म्यासेज Postgres टेबलमा हाल्छ, र Cloud API मार्फत जवाफ पठाउँछ। यसलाई JWT प्रमाणीकरण बन्द गरेर डिप्लोय गर्नुहोस्, किनकि Supabase ले पूर्वनिर्धारित रूपमा मान्य JWT माग्छ र Meta ले पठाउन सक्दैन।
Edge Function का लागि Supabase को पूर्वनिर्धारित सेटिङ, जसले तपाईंको ह्यान्डलर चल्नुअघि नै मान्य JWT नभएको हरेक अनुरोध अस्वीकार गर्छ।
फङ्सनका लागि JWT प्रमाणीकरण बन्द गर्ने supabase functions deploy को फ्ल्याग।
Edge Function को अनुरोध निष्क्रिय रहन पाउने समयसीमा; त्यतिन्जेल प्रतिक्रिया नआए 504 फर्कन्छ।
Edge Function ले के के गर्नुपर्छ?
दुई काम, दुई मेथडमा।
GET मा यसले Meta को प्रमाणीकरणको प्रतिक्रिया दिन्छ। क्वेरी स्ट्रिङबाट hub.mode, hub.verify_token र hub.challenge पढ्नुहोस्, टोकनलाई गन्तव्यको प्रमाणीकरण टोकनका रूपमा तपाईंले राखेको टोकनसँग दाँज्नुहोस्, र challenge लाई सादा टेक्स्ट बडीका रूपमा स्ट्याटस 200 सहित फर्काउनुहोस्। टोकन नमिलेमा 403 फर्काउनुहोस्।
POST मा यसले इभेन्टहरू प्राप्त गर्छ। बडी पार्स गर्नुहोस्, entry, changes र value भित्रबाट म्यासेज निकाल्नुहोस्, टेबलमा हाल्नुहोस्, र 200 फर्काउनुहोस्। प्रतिक्रिया छिटो दिनुहोस्: ढिलो वा असफल प्रतिक्रियालाई Meta ले असफल डेलिभरी ठान्छ र फेरि पठाउँछ, जसको अर्थ उही म्यासेज दुई पटक आउँछ।
EasyCoexistence मा फङ्सनको यूआरएललाई नम्बरको वेबहुक गन्तव्यका रूपमा त्यही प्रमाणीकरण टोकनसहित राख्नुहोस्, अनि Meta ले डेलिभर गर्न थाल्छ।
import { createClient } from "npm:@supabase/supabase-js@2";
const db = createClient(Deno.env.get("SUPABASE_URL")!, Deno.env.get("SUPABASE_SERVICE_ROLE_KEY")!);
Deno.serve(async (req) => {
const url = new URL(req.url);
if (req.method === "GET") {
const ok = url.searchParams.get("hub.verify_token") === Deno.env.get("VERIFY_TOKEN");
return new Response(ok ? url.searchParams.get("hub.challenge") : "forbidden", { status: ok ? 200 : 403 });
}
if (url.searchParams.get("key") !== Deno.env.get("URL_SECRET")) return new Response("no", { status: 401 });
const body = await req.json();
const rows = (body.entry ?? []).flatMap((e: any) => e.changes ?? [])
.flatMap((c: any) => (c.value?.messages ?? []).map((m: any) => ({
wamid: m.id, sender: m.from, kind: m.type, text: m.text?.body ?? null,
phone_number_id: c.value.metadata?.phone_number_id, raw: m,
})));
if (rows.length) await db.from("whatsapp_messages").upsert(rows, { onConflict: "wamid" });
return new Response("ok");
});फङ्सनले Meta लाई किन 401 फर्काउँछ?
किनकि JWT प्रमाणीकरण खुला छ। Edge Function को ह्यान्डलर चल्नुअघि Supabase ले Authorization हेडरको JWT जाँच्छ, र यो हरेक फङ्सनको पूर्वनिर्धारित व्यवहार हो। Meta ले त्यस्तो हेडर पठाउँदैन, त्यसैले प्लेटफर्मले प्रमाणीकरण GET र हरेक डेलिभरी दुवै अस्वीकार गर्छ, र तपाईंको कोडले तिनलाई कहिल्यै देख्दैन।
यो फङ्सनका लागि मात्र बन्द गर्नुहोस्। या त supabase functions deploy whatsapp --no-verify-jwt चलाएर डिप्लोय गर्नुहोस्, या supabase/config.toml मा फङ्सनको खण्डमा verify_jwt = false राख्नुहोस्। Supabase को डकुमेन्टेसनले ठ्याक्कै यही अवस्था वर्णन गर्छ: बाहिरको वेबहुक प्रदायकले बोलाउने सार्वजनिक एन्डपोइन्ट।
प्लेटफर्मको जाँच बन्द भएपछि फङ्सनमा आफ्नै जाँच चाहिन्छ। सिग्नेचर हेडर तपाईंलाई उपलब्ध हुँदैन, किनकि सदस्यताको मालिक एपको एप सिक्रेटले Meta ले हस्ताक्षर गर्छ। गन्तव्य यूआरएलमा क्वेरी प्यारामिटरका रूपमा लामो अनियमित सिक्रेट राख्नुहोस् र त्यो नभएका अनुरोध अस्वीकार गर्नुहोस्, जस्तो उदाहरणले POST मा गर्छ।
फङ्सनले कसरी भण्डारण गर्ने र प्रतिक्रिया दिने?
पहिले भण्डारण, पछि प्रतिक्रिया। WhatsApp म्यासेज id मा unique constraint राखेर upsert गर्नुहोस्, ताकि Meta का पुनः प्रयास नयाँ दोहोरो रो बनाउनुको सट्टा उही रोमा पुगून्। एकभन्दा बढी नम्बरले यही फङ्सन देखाउँछन् भने हरेक रोमा प्राप्त गर्ने phone_number_id पनि राख्नुहोस्।
ढिलो हुने कामका लागि, जस्तै जवाफ दिनुअघि मोडेल वा अर्को एपीआई बोलाउने, काम EdgeRuntime.waitUntil लाई सुम्पनुहोस् र तुरुन्तै प्रतिक्रिया फर्काउनुहोस्। त्यो प्रोमिस पूरा नभएसम्म फङ्सन चलिरहन्छ, र Meta ले पहिले नै आफ्नो 200 पाइसकेको हुन्छ। Supabase ले 150 सेकेन्ड निष्क्रिय भएपछि कुर्न छोड्छ र 504 फर्काउँछ, त्यसैले प्रतिक्रिया दिनुअघि सबै काम गर्ने ह्यान्डलरले नै सबैभन्दा बढी पुनः प्रयास निम्त्याउँछ।
प्रतिक्रिया Cloud API को messages एन्डपोइन्टमा जान्छ, नम्बरको phone number id र टोकनसहित, जुन फङ्सन सिक्रेटमा राखिएका हुन्छन्। ग्राहकको पछिल्लो म्यासेजको 24 घण्टाभित्र स्वतन्त्र टेक्स्ट पुग्छ; त्यसपछि स्वीकृत टेम्प्लेट मात्र पुग्छ।
फोनबाट पठाएका म्यासेज फङ्सनमा आइपुग्छन् कि?
आइपुग्छन्। Coexistence नम्बरमा WhatsApp Business एप चलिरहन्छ, र त्यसबाट कसैले जवाफ दिँदा Meta ले त्यस बाहिर जाने म्यासेजको इको उही गन्तव्यमा पठाउँछ, messages होइन, smb_message_echoes फिल्ड र message_echoes एरे अन्तर्गत।
पार्सरलाई दुवै पढ्ने गरी बढाउनुहोस् र direction कोलम राख्नुहोस्। तब टेबलमा पूरा कुराकानी हुन्छ: ग्राहकका लाइन र व्यवसायका जवाफ, जुन पछि धेरैजसोले क्वेरी गर्न चाहन्छन्: प्रतिक्रिया समय, अनुत्तरित थ्रेड, हरेक सम्पर्कको पछिल्लो आगमन समय।
त्यो पछिल्लो मान हरेक पठाउने बाटोलाई चाहिने इनपुट पनि हो, किनकि जवाफ स्वतन्त्र टेक्स्ट हुन सक्छ कि टेम्प्लेट नै चाहिन्छ भनेर त्यसैले निर्धारण गर्छ। टेबलमाथिको भ्यूले त्यसलाई हरेक सम्पर्कका लागि तपाईंको बाँकी एपमा उपलब्ध गराउन सक्छ।
सामान्य गल्तीहरू
- JWT प्रमाणीकरण खुला राखेर डिप्लोय गर्नु। ह्यान्डलर चल्नुअघि नै Supabase ले Meta का अनुरोध 401 सहित अस्वीकार गर्छ, र कुनै म्यासेज आइपुग्दैन।
- challenge लाई JSON मा बेरेर फर्काउनु। Meta लाई बडीमा कच्चा मान चाहिन्छ, नत्र प्रमाणीकरण चुपचाप असफल हुन्छ।
- प्रतिक्रिया दिनुअघि ढिलो काम गर्नु। Meta ले असफल ठानेका कुरा फेरि पठाउँछ, र उही म्यासेज दुई पटक प्रशोधन हुन्छ।
- आफ्नै कुनै जाँच नराखी JWT प्रमाणीकरण बन्द गर्नु। यूआरएल भेट्ने जोकोहीले टेबलमा नक्कली म्यासेज पठाउन सक्छ।
easycoexistence.com मा नम्बर जडान गर्नुहोस्, यसको वेबहुक गन्तव्य Edge Function को यूआरएलमा तपाईंको प्रमाणीकरण टोकनसहित राख्नुहोस्, र phone number id तथा टोकन फङ्सन सिक्रेटमा राख्नुहोस्। प्रति नम्बर प्रति महिना US$ 9 बाट सुरु, नम्बर थपिँदै जाँदा US$ 1 सम्म घट्छ, पहिलो 3 दिन निःशुल्क।
बारम्बार सोधिने प्रश्नहरू
के यो Supabase को निःशुल्क योजनामा काम गर्छ?
Edge Function निःशुल्क योजनामा चल्छन्, जहाँ wall clock सीमा 150 सेकेन्ड हुन्छ भने सशुल्क योजनामा 400 सेकेन्ड। छिटो प्रतिक्रिया दिने वेबहुक ह्यान्डलर दुवैको धेरै भित्र रहन्छ।
के फङ्सनमा service role key प्रयोग गर्नुपर्छ?
सर्भर तर्फ मात्र, यहाँ जस्तै, फङ्सनको एनभाइरोनमेन्टबाट पढेर। यसले row level security लाई छल्छ, त्यसैले यो ब्राउजरमा कहिल्यै पुग्नु हुँदैन।
के एउटै फङ्सनले धेरै नम्बर सम्हाल्न सक्छ?
सक्छ। हरेक नम्बरको वेबहुक गन्तव्य यसैलाई देखाउनुहोस् र हरेक पेलोडको phone_number_id हेरेर बाटो छुट्याउनुहोस्।
के EasyCoexistence ले म्यासेज देख्छ?
देख्दैन। Meta ले हरेक वेबहुक सिधै तपाईंको फङ्सनमा डेलिभर गर्छ, र EasyCoexistence ले कुराकानीको सामग्री कहिल्यै भण्डारण गर्दैन।
पढ्दै जानुहोस्
सुरु गर्न तयार हुनुहुन्छ?
महिनौं होइन, केही मिनेटमै WhatsApp Coexistence सेट अप गर्नुहोस्। एप फोनमा चलिरहन्छ।
निःशुल्क ट्रायल सुरु गर्नुहोस्प्रमाणीकरण गरिएको