@apostlejs/whatsapp 0.0.0 → 0.0.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.cjs +1 -1
- package/dist/index.d.cts +0 -8
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
@@ -1 +1 @@
|
|
1
|
-
"use strict";var e=require("zod");function t(e){return e&&e.__esModule?e:{default:e}}var a=t(require("node:crypto")),r=Object.defineProperty,n=(e,t)=>{for(var a in t)r(e,a,{get:t[a],enumerable:!0})},o={create:{url:"/{waba_id}/flows",method:"post",headers:{"Content-Type":"application/json"},request:{body:null},response:null},updateMetadata:{url:"/{flow_id}",method:"post",headers:{"Content-Type":"application/json"},request:{body:null},response:null},readMany:{url:"/{waba_id}/flows",method:"get",response:null},delete:{url:"/{flow_id}",method:"delete",response:null},read:{url:"/{flow_id}",method:"get",request:{query:null},response:null},updateJson:{url:"/{flow_id}/assets",method:"post",request:{body:null},response:null},getPreview:{url:"/{flow_id}?fields=preview.invalidate(false)",method:"get",response:null},publish:{url:"/{flow_id}/publish",method:"post",response:null}},s={send:{url:"/{number_id}/messages",method:"post",headers:{"Content-Type":"application/json"},request:{body:null},response:null}},i={updateEncryption:{url:"/{number_id}/whatsapp_business_encryption",method:"post",headers:{"Content-Type":"application/x-www-form-urlencoded"},request:{body:null}},registerNumber:{url:"/{number_id}/register",method:"post",headers:{"Content-Type":"application/json"},request:{body:null}}},c={flows:o,messages:s,waba:i},l=e.z.enum(["INIT","BACK","data_exchange","navigate","ping"]),p=e.z.enum(["SIGN_UP","SIGN_IN","APPOINTMENT_BOOKING","LEAD_GENERATION","CONTACT_US","CUSTOMER_SUPPORT","SURVEY","OTHER"]),u=e.z.object({media_id:e.z.string(),cdn_url:e.z.string(),file_name:e.z.string(),encryption_metadata:e.z.object({encrypted_hash:e.z.string(),iv:e.z.string(),encryption_key:e.z.string(),hmac_key:e.z.string(),plaintext_hash:e.z.string()})}),d=e.z.object({name:e.z.string(),categories:e.z.array(p),application_id:e.z.string().optional(),endpoint_uri:e.z.string().optional()}),f=e.z.union([e.z.literal("SUCCESS"),e.z.string()]),m=e.z.enum(["DRAFT","PUBLISHED","DEPRECATED","BLOCKED","THROTTLED"]),y=e.z.enum(["AVAILABLE","LIMITED","BLOCKED"]),_=e.z.object({error:e.z.string(),error_type:e.z.string(),message:e.z.string(),line_start:e.z.number(),line_end:e.z.number(),column_start:e.z.number(),column_end:e.z.number()}),h={},w={setup:e=>{Object.assign(h,e)},get:e=>{const t=h[e]??process.env[e];if(!t)throw new Error(`Missing environment variable: ${e}`);return t}},g={};n(g,{actions:()=>H,flows:()=>U,parsers:()=>q,security:()=>K,utils:()=>j});var b={};async function v(e,t,a){const r=`https://graph.facebook.com/v${w.get("GRAPH_API_VERSION")}`,n={Authorization:`Bearer ${w.get("META_APP_ACCESS_TOKEN")}`};let o=e.url;const s={...n,...e.headers,...t.headers},i=new URLSearchParams(t.query).toString();"/"===o[0]&&(o=o.slice(1)),o=`${r}/${o}`,i&&(o=`${o}?${i}`);const c={waba_id:w.get("WHATSAPP_ACCOUNT_ID"),number_id:w.get("WHATSAPP_NUMBER_ID"),...t.params};for(const e in c)o=o.replace(`{${e}}`,c[e]);const l=t.body;let p;if(l&&a?.asFormData){const e=new FormData;for(const t in l)e.append(t,l[t]);p=e}else l&&a?.asUrlEncoded?p=new URLSearchParams(l).toString():l&&(p=JSON.stringify(l));return await fetch(o,{method:e.method,headers:s,body:p}).then((e=>e.json())).then((e=>{if("error"in e)throw{response:{data:e.error}};return e})).catch((async e=>{throw e.response.data}))}async function E(e){return v(c.flows.create,{body:e})}async function S(e,t){const a=c.flows.updateMetadata;return await v(a,{body:t,params:{flow_id:e}})}async function A(e,t){return v(c.flows.updateJson,{params:{flow_id:e},body:{name:"flow.json",asset_type:"FLOW_JSON",file:new Blob([JSON.stringify(t,null,2)],{type:"application/json"})}},{asFormData:!0})}async function I(e,t){const a=c.flows.getPreview,{preview:r}=await v(a,{params:{flow_id:e}}),n=r.preview_url.replaceAll("\\",""),o=Object.entries(t??{}).reduce(((e,[t,a])=>(e[t]="flow_action_payload"===t?encodeURIComponent(JSON.stringify(a)):a.toString(),e)),{});return`${n}&${new URLSearchParams(o).toString()}`}async function P(e){return v(c.flows.delete,{params:{flow_id:e}})}async function N(e,t){return v(c.flows.read,{params:{flow_id:e},query:{fields:t?.fields.join(",")??""}})}async function T(){return v(c.flows.readMany,{})}async function x(e){return v(c.flows.publish,{params:{flow_id:e}})}n(b,{create:()=>E,delete:()=>P,get:()=>N,getMany:()=>T,getPreview:()=>I,publish:()=>x,updateJson:()=>A,updateMetadata:()=>S});var C={};async function O(e){const t=w.get("WHATSAPP_UNNOFICIAL_AUTHENTICATION_STRING"),a=await async function(e){const t=w.get("WHATSAPP_UNNOFICIAL_AUTHENTICATION_STRING");return await fetch("https://business.facebook.com/latest/whatsapp_manager/flows?flow_id="+e,{headers:{accept:"text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8","accept-language":"en-US,en;q=0.5","cache-control":"no-cache",pragma:"no-cache",priority:"u=0, i","sec-ch-ua":'"Brave";v="131", "Chromium";v="131", "Not_A Brand";v="24"',"sec-ch-ua-full-version-list":'"Brave";v="131.0.0.0", "Chromium";v="131.0.0.0", "Not_A Brand";v="24.0.0.0"',"sec-ch-ua-mobile":"?0","sec-ch-ua-model":'""',"sec-ch-ua-platform":'"Linux"',"sec-ch-ua-platform-version":'"6.11.9"',"sec-fetch-dest":"document","sec-fetch-mode":"navigate","sec-fetch-site":"same-origin","sec-fetch-user":"?1","sec-gpc":"1","upgrade-insecure-requests":"1",cookie:t},referrerPolicy:"strict-origin-when-cross-origin",body:null,method:"GET"}).then((e=>e.text())).then((e=>{const t=/<script\b[^>]*\bid=["']__eqmc["'][^>]*>(.*?)<\/script>/is.exec(e);if(!t)throw new Error("No matching <script> tag found.");const{f:a}=JSON.parse(t[1]);return a}))}(e),r={__aaid:"0",__bid:"250887754468924",__user:"100072333227027",__a:"1",__req:"m",dpr:"1",__ccg:"EXCELLENT",__rev:"1019090278",__comet_req:"11",fb_dtsg:a,__spin_b:"trunk",__jssesw:"1",fb_api_caller_class:"RelayModern",fb_api_req_friendly_name:"WAMFlowsBuilderDynamicSetupHealthCheckQuery",variables:JSON.stringify({flowID:e}),server_timestamps:"true",doc_id:" 7983200618385332"},n=new URLSearchParams(r).toString();return await fetch("https://business.facebook.com/api/graphql",{headers:{accept:"*/*","accept-language":"en-US,en;q=0.5","cache-control":"no-cache","content-type":"application/x-www-form-urlencoded",pragma:"no-cache",priority:"u=1, i","sec-ch-ua":'"Brave";v="131", "Chromium";v="131", "Not_A Brand";v="24"',"sec-ch-ua-full-version-list":'"Brave";v="131.0.0.0", "Chromium";v="131.0.0.0", "Not_A Brand";v="24.0.0.0"',"sec-ch-ua-mobile":"?0","sec-ch-ua-model":'""',"sec-ch-ua-platform":'"Linux"',"sec-ch-ua-platform-version":'"6.11.9"',"sec-fetch-dest":"empty","sec-fetch-mode":"cors","sec-fetch-site":"same-origin","sec-gpc":"1","x-fb-friendly-name":"WAMFlowsBuilderDynamicSetupHealthCheckQuery",cookie:t,Referer:"https://business.facebook.com/latest/whatsapp_manager/flows?flow_id=1137578314629992","Referrer-Policy":"strict-origin-when-cross-origin"},body:n,method:"POST"}).then((e=>e.text())).then((e=>e)).catch((e=>{console.error(e)}))}n(C,{verifyFlowIntegrity:()=>O});var B=e=>e.split("?")[0],U={createToken:({flow_name:e,flow_parameters:t,chatId:a})=>{const r=new URLSearchParams({chat_id:a});if(r.set("flow_identifier",crypto.randomUUID()),t)for(const[e,a]of Object.entries(t))r.set(e,a.toString());return`${e}?${decodeURIComponent(r.toString())}`},getName:B,destructureFlowToken:e=>{const t=B(e);let a=e.split("?")?.[1];"&"===a?.[0]&&(a=a.slice(1));const r=new URLSearchParams(a),n=r.get("chat_id")||r.get("chatId"),o=r.get("flow_identifier")||r.get("flowIdentifier"),s={};for(const[e,t]of r.entries())"chat_id"!==e&&"chatId"!==e&&"flow_identifier"!==e&&"flowIdentifier"!==e&&(s[e]=t);return{paramsString:a,flowName:t,chatId:n,flowIdentifier:o,flowParameters:s}}},R=e=>{const t={to:e.to,messaging_product:"whatsapp",recipient_type:"individual"};return e.reply&&(t.context=e.reply),e.showUrlPreviewImage&&(t.preview_url=e.showUrlPreviewImage),t},k={flow:e=>{if("flow"!==e.message.type)throw new Error("Invalid type");const{message:t,...a}=e,{flow:r,...n}=t,o=R(a);r.mode||(r.mode=w.get("WHATSAPP_FLOWS_MODE"));const s=U.createToken({chatId:o.to,flow_name:r.name,flow_parameters:r.parameters});return{type:"interactive",...o,interactive:{...n,type:"flow",action:{name:"flow",parameters:{flow_name:r.name,flow_token:s,flow_message_version:"3",flow_cta:r.buttonText,flow_action:r.action??"navigate",mode:r.mode,...r.payload&&{flow_action_payload:{...r.payload,screen:r.payload.screen.toUpperCase()}}}}}}},text:e=>{if("text"!==e.message.type)throw new Error("Invalid type");const{message:t,...a}=e,r=R(a),n={type:"text",text:{body:t.text},...r};return e.message.previewUrl&&n.text&&(n.text.preview_url=e.message.previewUrl),n},list:e=>{if("list"!==e.message.type)throw new Error("Invalid type");const{message:t,...a}=e,{list:r,type:n,...o}=t;return{...R(a),type:"interactive",interactive:{...o,type:n,action:{button:r.buttonText,sections:r.sections}}}},button:e=>{if("button"!==e.message.type)throw new Error("Invalid type");const{message:t,...a}=e,{buttons:r,type:n,...o}=t;return{...R(a),type:"interactive",interactive:{...o,type:n,action:{buttons:r.map((e=>({id:e.id,title:e.text,type:"reply"})))}}}},template:e=>{if("template"!==e.message.type)throw new Error("Invalid type");const{message:{type:t,...a},...r}=e,n={...R(r),type:t,template:{...a,language:{code:a.language}}};return n.template&&(n.template.namespace=process.env.WHATSAPP_MESSAGE_NAMESPACE),n},media:e=>{if("media"!==e.message.type)throw new Error("Invalid type");const{message:{type:t,...a},...r}=e,n=Object.entries(a)[0],[o,{ref:s,...i}]=n,c=i,l=R(r);return Number.isNaN(Number(s))?c.link=s:c.id=s,{type:o,[o]:c,...l}}};function z(e){const{encrypted_aes_key:t,encrypted_flow_data:r,initial_vector:n}=e,o=a.default.createPrivateKey({key:w.get("WHATSAPP_ACCOUNT_ENCRYPTION_PRIVATE_KEY"),passphrase:w.get("WHATSAPP_ACCOUNT_ENCRYPTION_PASSPHRASE")}),s=a.default.privateDecrypt({key:o,padding:a.default.constants.RSA_PKCS1_OAEP_PADDING,oaepHash:"sha256"},Buffer.from(t,"base64")),i=Buffer.from(r,"base64"),c=Buffer.from(n,"base64"),l=i.subarray(0,-16),p=i.subarray(-16),u=a.default.createDecipheriv("aes-128-gcm",s,c);u.setAuthTag(p);const d=Buffer.concat([u.update(l),u.final()]).toString("utf-8");return{payload:JSON.parse(d),encryptionMetadata:{aesKeyBuffer:s,initialVectorBuffer:c}}}function M(e){const t=new URL(e.url).searchParams,a=t.get("hub.verify_token"),r=t.get("hub.challenge");return!(!a||!r)&&a===w.get("WHATSAPP_WEBHOOK_KEY")&&r}async function D(e,t){const r=e.headers.get("x-hub-signature-256");if(!r)return!1;const n=r.replace("sha256=",""),o=a.default.createHmac("sha256",w.get("WHATSAPP_WEBHOOK_KEY")).update(t,"utf-8").digest("hex");return!!a.default.timingSafeEqual(Buffer.from(n),Buffer.from(o))}var q={toGraph:{sendMessage:e=>k[e.message.type](e),flowResponse:(e,t)=>{if(!t.data)throw new Error("Missing data in flow response");if(!t.screen)throw new Error("Missing screen in flow response");if(t.screen=t.screen.toUpperCase(),"SUCCESS"===t.screen){const a=t.data??{};t.data={extension_message_response:{params:{flow_token:e,...a}}}}return t}},toSDK:{webhook:async function(e){if("GET"===e.method){const t=M(e);if(!t)throw new Error("Invalid request");return{type:"healthCheck",payload:t}}const t=await e.text(),a=JSON.parse(t);if("entry"in a){if(!D(e,t))throw new Error("Invalid request");const n=a.entry.flatMap((e=>e.changes)).filter((e=>"messages"===e.field)).flatMap((e=>e.value.messages)).filter(Boolean).map((e=>function(e){const t=e.from,a={id:e.id,type:e.type,timestamp:e.timestamp,metadata:{forwarded:e.context?.forwarded,frequentlyForwarded:e.context?.frequently_forwarded}},r=function(e){if(!(e.audio||e.document||e.video||e.image))return null;const t=e.audio?.id??e.document?.id??e.image?.id??e.video?.id,a=e.audio?.mime_type??e.document?.mime_type??e.image?.mime_type??e.video?.mime_type,r=["audio","document","image","video"].find((t=>e[t])),n=e.image?.sha256??e.document?.sha256??e.video?.sha256;return{id:t,type:r,caption:e.document?.caption??e.image?.caption??e.video?.caption??null,mime_type:a,sha256:n,filename:e.document?.filename??e.video?.filename}}(e),n=function(e){return e.text?.body??e.button?.text??e.interactive?.button_reply?.title??e.interactive?.list_reply?.title??e.document?.caption??null}(e),o=function(e){return e.interactive?{...e.interactive?.button_reply||e.button?{button:{id:e.interactive?.button_reply?.id??null,title:e.button?.text??e.interactive.button_reply?.title,payload:e.button?.payload??null}}:{},...e.interactive.list_reply?{selectedOption:{id:e.interactive.list_reply.id,title:e.interactive.list_reply.title,description:e.interactive.list_reply.description}}:{},...e.interactive.nfm_reply?{flowResponse:JSON.parse(e.interactive.nfm_reply.response_json)}:{}}:null}(e);return{...a,...o&&{interaction:o},...r&&{media:r},text:n,chatId:t}}(e)));return{type:"application",payload:{messageReceived:(r=n,r.length?r:void 0)}}}var r;if("encrypted_flow_data"in a)return{type:"flowExchange",payload:{...z(a),pingResponse:{data:{status:"active"}}}};throw new Error("Invalid request")}}},H={messages:{send:async function(e){const t=q.toGraph.sendMessage(e),a=c.messages.send;return await v(a,{body:t})}},flows:{...b,unnoficial:C},waba:{registerNumber:async function({dataRegion:e,pin:t}){const a=c.waba.registerNumber,r={messaging_product:"whatsapp",pin:t};return e&&(r.data_localization_region=e),await v(a,{body:r},{asUrlEncoded:!0})},encryption:{upload:async function(e){const t=c.waba.updateEncryption,a={business_public_key:e};return await v(t,{body:a},{asUrlEncoded:!0})}}}};async function L(e){return await fetch(e).then((async e=>{const t=await e.arrayBuffer();return Buffer.from(t)}))}var K={verifyHub:M,verifySignature:D,generateWabaEncryption:async function(){const e=a.default.randomUUID(),{publicKey:t,privateKey:r}=a.default.generateKeyPairSync("rsa",{modulusLength:2048,publicKeyEncoding:{type:"spki",format:"pem"},privateKeyEncoding:{type:"pkcs8",format:"pem",cipher:"aes-256-cbc",passphrase:e}});return{passphrase:e,publicKey:t,privateKey:r}},decryptFlowBody:z,encryptFlowResponse:function(e,t){const r=[];for(const e of Buffer.from(t.initialVectorBuffer).entries())r.push(~e[1]);const n=a.default.createCipheriv("aes-128-gcm",Buffer.from(t.aesKeyBuffer),Buffer.from(r));return Buffer.concat([n.update(JSON.stringify(e),"utf-8"),n.final(),n.getAuthTag()]).toString("base64")},decryptFlowMedia:async function(e){const t=[];for(const r of e){let{cdn_url:e,encryption_metadata:n}=r;if("EXAMPLE_DATA__CDN_URL_WILL_COME_IN_THIS_FIELD"===e){e="https://picsum.photos/seed/picsum/200";const a=await L(e);t.push(a);continue}const o=await L(e),{iv:s,encryption_key:i,hmac_key:c,encrypted_hash:l,plaintext_hash:p}=n,u={iv:Buffer.from(s,"base64"),encryption_key:Buffer.from(i,"base64"),hmac_key:Buffer.from(c,"base64")};if(a.default.createHash("sha256").update(o).digest("base64")!==l)throw new Error("Encrypted hash validation failed");const d=o.subarray(0,o.length-10),f=o.subarray(-10);if(!a.default.createHmac("sha256",u.hmac_key).update(Buffer.concat([u.iv,d])).digest().subarray(0,10).equals(f))throw new Error("HMAC validation failed");const m=a.default.createDecipheriv("aes-256-cbc",u.encryption_key,u.iv),y=m.update(d),_=Buffer.concat([y,m.final()]);if(a.default.createHash("sha256").update(_).digest("base64")!==p)throw new Error("Decrypted media hash validation failed");t.push(_)}return t}},j={flows:U},W={graph:{endpoints:c},settings:w,sdk:g};exports.actions=H,exports.endpoints=c,exports.flowAction=l,exports.flowCanSendMessageStatus=y,exports.flowCategory=p,exports.flowMediaData=u,exports.flowMetadata=d,exports.flowScreen=f,exports.flowStatus=m,exports.flowValidationError=_,exports.flows=U,exports.flowsEndpoints=o,exports.messagesEndpoints=s,exports.parsers=q,exports.security=K,exports.utils=j,exports.wabaEndpoints=i,exports.whatsapp=W;
|
1
|
+
"use strict";var e=require("zod");function t(e){return e&&e.__esModule?e:{default:e}}var r=t(require("node:crypto")),a=Object.defineProperty,n=(e,t)=>{for(var r in t)a(e,r,{get:t[r],enumerable:!0})},o={create:{url:"/{waba_id}/flows",method:"post",headers:{"Content-Type":"application/json"},request:{body:null},response:null},updateMetadata:{url:"/{flow_id}",method:"post",headers:{"Content-Type":"application/json"},request:{body:null},response:null},readMany:{url:"/{waba_id}/flows",method:"get",response:null},delete:{url:"/{flow_id}",method:"delete",response:null},read:{url:"/{flow_id}",method:"get",request:{query:null},response:null},updateJson:{url:"/{flow_id}/assets",method:"post",request:{body:null},response:null},getPreview:{url:"/{flow_id}?fields=preview.invalidate(false)",method:"get",response:null},publish:{url:"/{flow_id}/publish",method:"post",response:null}},s={send:{url:"/{number_id}/messages",method:"post",headers:{"Content-Type":"application/json"},request:{body:null},response:null}},i={updateEncryption:{url:"/{number_id}/whatsapp_business_encryption",method:"post",headers:{"Content-Type":"application/x-www-form-urlencoded"},request:{body:null}},registerNumber:{url:"/{number_id}/register",method:"post",headers:{"Content-Type":"application/json"},request:{body:null}}},l={flows:o,messages:s,waba:i},p=e.z.enum(["INIT","BACK","data_exchange","navigate","ping"]),c=e.z.enum(["SIGN_UP","SIGN_IN","APPOINTMENT_BOOKING","LEAD_GENERATION","CONTACT_US","CUSTOMER_SUPPORT","SURVEY","OTHER"]),d=e.z.object({media_id:e.z.string(),cdn_url:e.z.string(),file_name:e.z.string(),encryption_metadata:e.z.object({encrypted_hash:e.z.string(),iv:e.z.string(),encryption_key:e.z.string(),hmac_key:e.z.string(),plaintext_hash:e.z.string()})}),u=e.z.object({name:e.z.string(),categories:e.z.array(c),application_id:e.z.string().optional(),endpoint_uri:e.z.string().optional()}),f=e.z.union([e.z.literal("SUCCESS"),e.z.string()]),m=e.z.enum(["DRAFT","PUBLISHED","DEPRECATED","BLOCKED","THROTTLED"]),y=e.z.enum(["AVAILABLE","LIMITED","BLOCKED"]),w=e.z.object({error:e.z.string(),error_type:e.z.string(),message:e.z.string(),line_start:e.z.number(),line_end:e.z.number(),column_start:e.z.number(),column_end:e.z.number()}),_={},g={setup:e=>{Object.assign(_,e)},get:e=>{const t=_[e]??process.env[e];if(!t)throw new Error(`Missing environment variable: ${e}`);return t}},h={};n(h,{actions:()=>k,flows:()=>C,parsers:()=>D,security:()=>K,utils:()=>L});var b={};async function v(e,t,r){const a=`https://graph.facebook.com/v${g.get("GRAPH_API_VERSION")}`,n={Authorization:`Bearer ${g.get("META_APP_ACCESS_TOKEN")}`};let o=e.url;const s={...n,...e.headers,...t.headers},i=new URLSearchParams(t.query).toString();"/"===o[0]&&(o=o.slice(1)),o=`${a}/${o}`,i&&(o=`${o}?${i}`);const l={waba_id:g.get("WHATSAPP_ACCOUNT_ID"),number_id:g.get("WHATSAPP_NUMBER_ID"),...t.params};for(const e in l)o=o.replace(`{${e}}`,l[e]);const p=t.body;let c;if(p&&r?.asFormData){const e=new FormData;for(const t in p)e.append(t,p[t]);c=e}else p&&r?.asUrlEncoded?c=new URLSearchParams(p).toString():p&&(c=JSON.stringify(p));return await fetch(o,{method:e.method,headers:s,body:c}).then((e=>e.json())).then((e=>{if("error"in e)throw{response:{data:e.error}};return e})).catch((async e=>{throw e.response.data}))}async function E(e){return v(l.flows.create,{body:e})}async function S(e,t){const r=l.flows.updateMetadata;return await v(r,{body:t,params:{flow_id:e}})}async function A(e,t){return v(l.flows.updateJson,{params:{flow_id:e},body:{name:"flow.json",asset_type:"FLOW_JSON",file:new Blob([JSON.stringify(t,null,2)],{type:"application/json"})}},{asFormData:!0})}async function P(e,t){const r=l.flows.getPreview,{preview:a}=await v(r,{params:{flow_id:e}}),n=a.preview_url.replaceAll("\\",""),o=Object.entries(t??{}).reduce(((e,[t,r])=>(e[t]="flow_action_payload"===t?encodeURIComponent(JSON.stringify(r)):r.toString(),e)),{});return`${n}&${new URLSearchParams(o).toString()}`}async function I(e){return v(l.flows.delete,{params:{flow_id:e}})}async function T(e,t){return v(l.flows.read,{params:{flow_id:e},query:{fields:t?.fields.join(",")??""}})}async function x(){return v(l.flows.readMany,{})}async function N(e){return v(l.flows.publish,{params:{flow_id:e}})}n(b,{create:()=>E,delete:()=>I,get:()=>T,getMany:()=>x,getPreview:()=>P,publish:()=>N,updateJson:()=>A,updateMetadata:()=>S});var O=e=>e.split("?")[0],C={createToken:({flow_name:e,flow_parameters:t,chatId:r})=>{const a=new URLSearchParams({chat_id:r});if(a.set("flow_identifier",crypto.randomUUID()),t)for(const[e,r]of Object.entries(t))a.set(e,r.toString());return`${e}?${decodeURIComponent(a.toString())}`},getName:O,destructureFlowToken:e=>{const t=O(e);let r=e.split("?")?.[1];"&"===r?.[0]&&(r=r.slice(1));const a=new URLSearchParams(r),n=a.get("chat_id")||a.get("chatId"),o=a.get("flow_identifier")||a.get("flowIdentifier"),s={};for(const[e,t]of a.entries())"chat_id"!==e&&"chatId"!==e&&"flow_identifier"!==e&&"flowIdentifier"!==e&&(s[e]=t);return{paramsString:r,flowName:t,chatId:n,flowIdentifier:o,flowParameters:s}}},B=e=>{const t={to:e.to,messaging_product:"whatsapp",recipient_type:"individual"};return e.reply&&(t.context=e.reply),e.showUrlPreviewImage&&(t.preview_url=e.showUrlPreviewImage),t},U={flow:e=>{if("flow"!==e.message.type)throw new Error("Invalid type");const{message:t,...r}=e,{flow:a,...n}=t,o=B(r);a.mode||(a.mode=g.get("WHATSAPP_FLOWS_MODE"));const s=C.createToken({chatId:o.to,flow_name:a.name,flow_parameters:a.parameters});return{type:"interactive",...o,interactive:{...n,type:"flow",action:{name:"flow",parameters:{flow_name:a.name,flow_token:s,flow_message_version:"3",flow_cta:a.buttonText,flow_action:a.action??"navigate",mode:a.mode,...a.payload&&{flow_action_payload:{...a.payload,screen:a.payload.screen.toUpperCase()}}}}}}},text:e=>{if("text"!==e.message.type)throw new Error("Invalid type");const{message:t,...r}=e,a=B(r),n={type:"text",text:{body:t.text},...a};return e.message.previewUrl&&n.text&&(n.text.preview_url=e.message.previewUrl),n},list:e=>{if("list"!==e.message.type)throw new Error("Invalid type");const{message:t,...r}=e,{list:a,type:n,...o}=t;return{...B(r),type:"interactive",interactive:{...o,type:n,action:{button:a.buttonText,sections:a.sections}}}},button:e=>{if("button"!==e.message.type)throw new Error("Invalid type");const{message:t,...r}=e,{buttons:a,type:n,...o}=t;return{...B(r),type:"interactive",interactive:{...o,type:n,action:{buttons:a.map((e=>({id:e.id,title:e.text,type:"reply"})))}}}},template:e=>{if("template"!==e.message.type)throw new Error("Invalid type");const{message:{type:t,...r},...a}=e,n={...B(a),type:t,template:{...r,language:{code:r.language}}};return n.template&&(n.template.namespace=process.env.WHATSAPP_MESSAGE_NAMESPACE),n},media:e=>{if("media"!==e.message.type)throw new Error("Invalid type");const{message:{type:t,...r},...a}=e,n=Object.entries(r)[0],[o,{ref:s,...i}]=n,l=i,p=B(a);return Number.isNaN(Number(s))?l.link=s:l.id=s,{type:o,[o]:l,...p}}};function z(e){const{encrypted_aes_key:t,encrypted_flow_data:a,initial_vector:n}=e,o=r.default.createPrivateKey({key:g.get("WHATSAPP_ACCOUNT_ENCRYPTION_PRIVATE_KEY"),passphrase:g.get("WHATSAPP_ACCOUNT_ENCRYPTION_PASSPHRASE")}),s=r.default.privateDecrypt({key:o,padding:r.default.constants.RSA_PKCS1_OAEP_PADDING,oaepHash:"sha256"},Buffer.from(t,"base64")),i=Buffer.from(a,"base64"),l=Buffer.from(n,"base64"),p=i.subarray(0,-16),c=i.subarray(-16),d=r.default.createDecipheriv("aes-128-gcm",s,l);d.setAuthTag(c);const u=Buffer.concat([d.update(p),d.final()]).toString("utf-8");return{payload:JSON.parse(u),encryptionMetadata:{aesKeyBuffer:s,initialVectorBuffer:l}}}function R(e){const t=new URL(e.url).searchParams,r=t.get("hub.verify_token"),a=t.get("hub.challenge");return!(!r||!a)&&r===g.get("WHATSAPP_WEBHOOK_KEY")&&a}async function M(e,t){const a=e.headers.get("x-hub-signature-256");if(!a)return!1;const n=a.replace("sha256=",""),o=r.default.createHmac("sha256",g.get("WHATSAPP_WEBHOOK_KEY")).update(t,"utf-8").digest("hex");return!!r.default.timingSafeEqual(Buffer.from(n),Buffer.from(o))}var D={toGraph:{sendMessage:e=>U[e.message.type](e),flowResponse:(e,t)=>{if(!t.data)throw new Error("Missing data in flow response");if(!t.screen)throw new Error("Missing screen in flow response");if(t.screen=t.screen.toUpperCase(),"SUCCESS"===t.screen){const r=t.data??{};t.data={extension_message_response:{params:{flow_token:e,...r}}}}return t}},toSDK:{webhook:async function(e){if("GET"===e.method){const t=R(e);if(!t)throw new Error("Invalid request");return{type:"healthCheck",payload:t}}const t=await e.text(),r=JSON.parse(t);if("entry"in r){if(!M(e,t))throw new Error("Invalid request");const n=r.entry.flatMap((e=>e.changes)).filter((e=>"messages"===e.field)).flatMap((e=>e.value.messages)).filter(Boolean).map((e=>function(e){const t=e.from,r={id:e.id,type:e.type,timestamp:e.timestamp,metadata:{forwarded:e.context?.forwarded,frequentlyForwarded:e.context?.frequently_forwarded}},a=function(e){if(!(e.audio||e.document||e.video||e.image))return null;const t=e.audio?.id??e.document?.id??e.image?.id??e.video?.id,r=e.audio?.mime_type??e.document?.mime_type??e.image?.mime_type??e.video?.mime_type,a=["audio","document","image","video"].find((t=>e[t])),n=e.image?.sha256??e.document?.sha256??e.video?.sha256;return{id:t,type:a,caption:e.document?.caption??e.image?.caption??e.video?.caption??null,mime_type:r,sha256:n,filename:e.document?.filename??e.video?.filename}}(e),n=function(e){return e.text?.body??e.button?.text??e.interactive?.button_reply?.title??e.interactive?.list_reply?.title??e.document?.caption??null}(e),o=function(e){return e.interactive?{...e.interactive?.button_reply||e.button?{button:{id:e.interactive?.button_reply?.id??null,title:e.button?.text??e.interactive.button_reply?.title,payload:e.button?.payload??null}}:{},...e.interactive.list_reply?{selectedOption:{id:e.interactive.list_reply.id,title:e.interactive.list_reply.title,description:e.interactive.list_reply.description}}:{},...e.interactive.nfm_reply?{flowResponse:JSON.parse(e.interactive.nfm_reply.response_json)}:{}}:null}(e);return{...r,...o&&{interaction:o},...a&&{media:a},text:n,chatId:t}}(e)));return{type:"application",payload:{messageReceived:(a=n,a.length?a:void 0)}}}var a;if("encrypted_flow_data"in r)return{type:"flowExchange",payload:{...z(r),pingResponse:{data:{status:"active"}}}};throw new Error("Invalid request")}}},k={messages:{send:async function(e){const t=D.toGraph.sendMessage(e),r=l.messages.send;return await v(r,{body:t})}},flows:{...b},waba:{registerNumber:async function({dataRegion:e,pin:t}){const r=l.waba.registerNumber,a={messaging_product:"whatsapp",pin:t};return e&&(a.data_localization_region=e),await v(r,{body:a},{asUrlEncoded:!0})},encryption:{upload:async function(e){const t=l.waba.updateEncryption,r={business_public_key:e};return await v(t,{body:r},{asUrlEncoded:!0})}}}};async function H(e){return await fetch(e).then((async e=>{const t=await e.arrayBuffer();return Buffer.from(t)}))}var K={verifyHub:R,verifySignature:M,generateWabaEncryption:async function(){const e=r.default.randomUUID(),{publicKey:t,privateKey:a}=r.default.generateKeyPairSync("rsa",{modulusLength:2048,publicKeyEncoding:{type:"spki",format:"pem"},privateKeyEncoding:{type:"pkcs8",format:"pem",cipher:"aes-256-cbc",passphrase:e}});return{passphrase:e,publicKey:t,privateKey:a}},decryptFlowBody:z,encryptFlowResponse:function(e,t){const a=[];for(const e of Buffer.from(t.initialVectorBuffer).entries())a.push(~e[1]);const n=r.default.createCipheriv("aes-128-gcm",Buffer.from(t.aesKeyBuffer),Buffer.from(a));return Buffer.concat([n.update(JSON.stringify(e),"utf-8"),n.final(),n.getAuthTag()]).toString("base64")},decryptFlowMedia:async function(e){const t=[];for(const a of e){let{cdn_url:e,encryption_metadata:n}=a;if("EXAMPLE_DATA__CDN_URL_WILL_COME_IN_THIS_FIELD"===e){e="https://picsum.photos/seed/picsum/200";const r=await H(e);t.push(r);continue}const o=await H(e),{iv:s,encryption_key:i,hmac_key:l,encrypted_hash:p,plaintext_hash:c}=n,d={iv:Buffer.from(s,"base64"),encryption_key:Buffer.from(i,"base64"),hmac_key:Buffer.from(l,"base64")};if(r.default.createHash("sha256").update(o).digest("base64")!==p)throw new Error("Encrypted hash validation failed");const u=o.subarray(0,o.length-10),f=o.subarray(-10);if(!r.default.createHmac("sha256",d.hmac_key).update(Buffer.concat([d.iv,u])).digest().subarray(0,10).equals(f))throw new Error("HMAC validation failed");const m=r.default.createDecipheriv("aes-256-cbc",d.encryption_key,d.iv),y=m.update(u),w=Buffer.concat([y,m.final()]);if(r.default.createHash("sha256").update(w).digest("base64")!==c)throw new Error("Decrypted media hash validation failed");t.push(w)}return t}},L={flows:C},q={graph:{endpoints:l},settings:g,sdk:h};exports.actions=k,exports.endpoints=l,exports.flowAction=p,exports.flowCanSendMessageStatus=y,exports.flowCategory=c,exports.flowMediaData=d,exports.flowMetadata=u,exports.flowScreen=f,exports.flowStatus=m,exports.flowValidationError=w,exports.flows=C,exports.flowsEndpoints=o,exports.messagesEndpoints=s,exports.parsers=D,exports.security=K,exports.utils=L,exports.wabaEndpoints=i,exports.whatsapp=q;
|
package/dist/index.d.cts
CHANGED
@@ -783,13 +783,6 @@ interface WhatsappFlowInfo {
|
|
783
783
|
|
784
784
|
declare function _delete(flow_id: string): Promise<WhatsappDeleteFlowResponse>;
|
785
785
|
|
786
|
-
declare function verifyFlowIntegrity(flowID: string): Promise<string | void>;
|
787
|
-
|
788
|
-
declare const unnoficial_verifyFlowIntegrity: typeof verifyFlowIntegrity;
|
789
|
-
declare namespace unnoficial {
|
790
|
-
export { unnoficial_verifyFlowIntegrity as verifyFlowIntegrity };
|
791
|
-
}
|
792
|
-
|
793
786
|
type WaSDKButtonMessage = Omit<WaInteractiveBase, "type"> & {
|
794
787
|
type: "button";
|
795
788
|
buttons: Array<{
|
@@ -907,7 +900,6 @@ declare const actions: {
|
|
907
900
|
send: typeof send;
|
908
901
|
};
|
909
902
|
flows: {
|
910
|
-
unnoficial: typeof unnoficial;
|
911
903
|
create(body: WhatsappCreateFlowRequestBody): Promise<WhatsappCreateFlowResponse>;
|
912
904
|
updateMetadata(flow_id: string, body: WhatsappFlowUpdateMetadataRequestBody): Promise<WhatsappFlowUpdateMetadataResponse>;
|
913
905
|
updateJson(flow_id: string, json: Record<string, AnyType>): Promise<WhatsappUpdateFlowJsonResponse>;
|