Pokea webhook za WhatsApp kwenye Supabase Edge Function
Supabase Edge Function inaweza kuwa moja kwa moja mahali pa kupokelea webhook za nambari yako. Inajibu GET ya uthibitishaji ya Meta kwa thamani ya hub.challenge, inaingiza kila ujumbe unaotumwa kwa POST kwenye jedwali la Postgres, na inajibu kupitia Cloud API. Isambaze ikiwa na uthibitishaji wa JWT umezimwa, kwa sababu Supabase kwa chaguo-msingi inahitaji JWT halali, na Meta haiwezi kutuma.
Chaguo-msingi la Supabase kwa Edge Functions, linalokataa ombi lolote lisilo na JWT halali kabla msimbo wako haujaendeshwa.
Bendera ya supabase functions deploy inayozima uthibitishaji wa JWT kwa function.
Muda wa ombi kukaa bila shughuli kwa Edge Function; bila jibu kufikia wakati huo, inarudisha 504.
Edge Function inapaswa kufanya nini?
Mambo mawili, kwa njia mbili.
Kwenye GET, inajibu uthibitishaji wa Meta. Soma hub.mode, hub.verify_token na hub.challenge kutoka kwenye query string, linganisha token na ile uliyoweka kama verify token ya destination, kisha rudisha challenge kama maandishi matupu yenye hali 200. Rudisha 403 ikiwa token hailingani.
Kwenye POST, inapokea matukio. Changanua body, toa jumbe kutoka entry, changes na value, ziingize kwenye jedwali, kisha rudisha 200. Weka jibu liwe la haraka: Meta huchukulia jibu la polepole au lililoshindwa kama uwasilishaji ulioshindwa na hujaribu tena, jambo linalomaanisha ujumbe ule ule mara mbili.
Weka URL ya function kama webhook destination ya nambari yako kwenye EasyCoexistence, pamoja na verify token ile ile, nayo Meta itaanza kuwasilisha.
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");
});Kwa nini function inarudisha 401 kwa Meta?
Kwa sababu uthibitishaji wa JWT umewashwa. Supabase huthibitisha JWT kwenye header ya Authorization kabla msimbo wa Edge Function haujaendeshwa, na hilo ndilo chaguo-msingi kwa kila function. Meta haitumi header kama hiyo, kwa hiyo jukwaa linakataa GET ya uthibitishaji na kila uwasilishaji, na msimbo wako hauzioni kamwe.
Izime kwa function hii pekee. Ama isambaze kwa supabase functions deploy whatsapp --no-verify-jwt, au weka verify_jwt = false chini ya sehemu ya function kwenye supabase/config.toml. Nyaraka za Supabase zinaelezea kisa hiki hasa: endpoint ya umma inayoitwa na mtoa webhook wa nje.
Ukizima ukaguzi wa jukwaa, function inahitaji ukaguzi wake yenyewe. Header ya sahihi haipatikani kwako, kwa kuwa Meta husaini kwa app secret ya programu inayomiliki usajili. Weka siri ndefu ya nasibu kwenye URL ya destination kama parameter ya query na ukatae maombi yasiyo nayo, kama mfano unavyofanya kwenye POST.
Function ihifadhi na ijibu vipi?
Hifadhi kwanza, jibu baadaye. Fanya upsert kwa kitambulisho cha ujumbe cha WhatsApp ukiwa na unique constraint, ili majaribio ya kurudia ya Meta yaingie kwenye safu ile ile badala ya kuunda nakala. Weka phone_number_id inayopokea kwenye kila safu ikiwa nambari zaidi ya moja zinaelekeza kwenye function.
Kwa kazi yoyote ya polepole, kama kuita model au API nyingine kabla ya kujibu, mkabidhi EdgeRuntime.waitUntil kazi hiyo na urudishe jibu mara moja. Function inaendelea kufanya kazi hadi promise hiyo ikamilike, huku Meta tayari ikiwa na 200 yake. Supabase huacha kusubiri baada ya sekunde 150 za kukaa bila shughuli na hurudisha 504, kwa hiyo handler inayomaliza kazi yote kabla ya kujibu ndiyo inayoweza kusababisha majaribio ya kurudia zaidi.
Majibu huenda kwenye endpoint ya messages ya Cloud API, kwa kutumia phone number id na token ya nambari yako, zilizohifadhiwa kama function secrets. Ndani ya saa 24 tangu ujumbe wa mwisho wa mteja, maandishi huru yanawasilishwa; nje ya muda huo ni template iliyoidhinishwa pekee.
Je, jumbe zinazotumwa kutoka kwenye simu hufika kwenye function?
Ndiyo. Kwenye nambari ya Coexistence, programu ya WhatsApp Business inaendelea kufanya kazi, na mtu anapojibu kutoka humo, Meta huwasilisha echo ya ujumbe huo unaotoka kwenye destination ile ile, chini ya field ya smb_message_echoes na array ya message_echoes badala ya messages.
Panua parser isome zote mbili na uhifadhi safu ya direction. Jedwali kisha linashikilia mazungumzo kamili, maneno ya mteja na majibu ya biashara, ambayo ndiyo watu wengi wanataka kuyahoji baadaye: muda wa kujibu, mazungumzo yasiyojibiwa, na wakati wa mwisho wa ujumbe unaoingia kwa kila mwasiliani.
Thamani hiyo ya mwisho pia ndiyo pembejeo inayohitajika na kila njia ya kutuma, kwa kuwa huamua kama jibu linaweza kuwa maandishi huru au lazima liwe template. View juu ya jedwali inaweza kuitoa kwa kila mwasiliani kwa sehemu nyingine za programu yako.
Makosa ya kawaida
- Kusambaza function ukiwa umeacha uthibitishaji wa JWT umewashwa. Supabase hukataa maombi ya Meta kwa 401 kabla ya handler kuendeshwa, na hakuna ujumbe unaofika kamwe.
- Kurudisha challenge ikiwa imefungwa ndani ya JSON. Meta inahitaji thamani ghafi kama body, vinginevyo uthibitishaji unashindwa bila taarifa.
- Kufanya kazi ya polepole kabla ya kujibu. Meta hujaribu tena kile inachokiona kama kushindwa, na ujumbe ule ule unashughulikiwa mara mbili.
- Kuzima uthibitishaji wa JWT bila ukaguzi wako mwenyewe. Yeyote atakayepata URL anaweza kutuma jumbe bandia kwenye jedwali.
Unganisha nambari yako kwenye easycoexistence.com, weka webhook destination yake iwe URL ya Edge Function pamoja na verify token yako, kisha hifadhi phone number id na token kama function secrets. Kuanzia US$ 9 kwa kila nambari iliyounganishwa kwa mwezi, hadi US$ 1 kadiri unavyoongeza nambari, na siku 3 za kwanza ni kipindi cha majaribio bila malipo.
Maswali yanayoulizwa mara kwa mara
Je, hii inafanya kazi kwenye mpango wa bure wa Supabase?
Edge Functions zinaendeshwa kwenye mpango wa bure, zikiwa na kikomo cha sekunde 150 dhidi ya sekunde 400 kwenye mipango ya kulipia. Handler ya webhook inayojibu haraka hubaki mbali ndani ya kikomo chochote kati ya hivyo.
Je, nitumie service role key kwenye function?
Itumie upande wa server pekee, kama ilivyo hapa, ikisomwa kutoka kwenye environment ya function. Inapita row level security, kwa hiyo haipaswi kamwe kufika kwenye browser.
Je, function moja inaweza kuhudumia nambari kadhaa?
Ndiyo. Elekeza webhook destination ya kila nambari kwake na tenganisha kwa phone_number_id iliyo kwenye kila payload.
Je, EasyCoexistence huona jumbe?
Hapana. Meta huwasilisha kila webhook moja kwa moja kwa function yako, na EasyCoexistence haihifadhi maudhui ya mazungumzo kamwe.
Endelea kusoma
Uko tayari kuanza?
Sanidi WhatsApp Coexistence kwa dakika chache, si miezi. Programu inaendelea kufanya kazi kwenye simu.
Anza kipindi cha majaribio bila malipoImethibitishwa kwenye