1import{serve}from"https://deno.land/std@0.224.0/http/server.ts";
2
3interfaceRelayConfig{
4targets:{url:string;headers?:Record<string,string>}[];
5transform?:(payload:unknown)=>unknown;
6}
7
8constMAX_RETRIES=3;
9constBASE_DELAY=1000;
10
11asyncfunctionretryFetch(
12url:string,
13options:RequestInit,
14attempt:number
15):Promise<Response>{
16constres=awaitfetch(url,options);
17if(res.ok||attempt>=MAX_RETRIES)returnres;
18awaitnewPromise((r)=>setTimeout(r,BASE_DELAY*2**attempt));
19returnretryFetch(url,options,attempt+1);
20}
21
22asyncfunctionrelay(req:Request):Promise<Response>{
23constconfig:RelayConfig={
24targets:[{url:Deno.env.get("RELAY_TARGET_1")!}],
25};
26
27constpayload=awaitreq.json();
28consttransformed=config.transform?.(payload)??payload;
29
30constresults=awaitPromise.allSettled(
31config.targets.map((t)=>
32retryFetch(
33t.url,
34{
35method:"POST",
36headers:{
37"Content-Type":"application/json",
38...t.headers,
39},
40body:JSON.stringify(transformed),
41},
420
43)
44)
45);
46
47constdelivered=results.filter(
48(r)=>r.status==="fulfilled"&&r.value.ok
49).length;
50
51returnnewResponse(
52JSON.stringify({delivered,total:config.targets.length}),
53{headers:{"content-type":"application/json"}}
54);
55}
56
57serve(relay,{port:8080});