Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

whatsapp-api-js

Package Overview
Dependencies
Maintainers
1
Versions
95
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

whatsapp-api-js - npm Package Compare versions

Comparing version 2.5.1 to 2.6.0

2

lib/cjs/index.js

@@ -1,2 +0,2 @@

"use strict";var __defProp=Object.defineProperty;var __getOwnPropDesc=Object.getOwnPropertyDescriptor;var __getOwnPropNames=Object.getOwnPropertyNames;var __hasOwnProp=Object.prototype.hasOwnProperty;var __export=(target,all)=>{for(var name in all)__defProp(target,name,{get:all[name],enumerable:!0})},__copyProps=(to,from,except,desc)=>{if(from&&typeof from=="object"||typeof from=="function")for(let key of __getOwnPropNames(from))!__hasOwnProp.call(to,key)&&key!==except&&__defProp(to,key,{get:()=>from[key],enumerable:!(desc=__getOwnPropDesc(from,key))||desc.enumerable});return to};var __toCommonJS=mod=>__copyProps(__defProp({},"__esModule",{value:!0}),mod);var src_exports={};__export(src_exports,{default:()=>WhatsAppAPI});module.exports=__toCommonJS(src_exports);var import_utils=require("./utils.js");class WhatsAppAPI{token;appSecret;webhookVerifyToken;v;fetch;subtle;parsed;offload_functions;secure;on={};constructor({token,appSecret,webhookVerifyToken,v="v18.0",parsed=!0,offload_functions=!0,secure=!0,ponyfill={}}){if(this.token=token,this.secure=!!secure,this.secure){if(this.appSecret=appSecret,typeof ponyfill.subtle!="object"&&(typeof crypto!="object"||typeof crypto?.subtle!="object"))throw new Error("subtle is not defined in the enviroment. Consider using a setup helper, defined at 'whatsapp-api-js/setup', or provide a valid ponyfill object with the argument 'ponyfill.subtle'.");this.subtle=ponyfill.subtle||crypto.subtle}if(webhookVerifyToken&&(this.webhookVerifyToken=webhookVerifyToken),typeof ponyfill.fetch!="function"&&typeof fetch!="function")throw new Error("fetch is not defined in the enviroment. Consider using a setup helper, defined at 'whatsapp-api-js/setup', or provide a valid ponyfill object with the argument 'ponyfill.fetch'.");this.fetch=ponyfill.fetch||fetch,this.v=v,this.parsed=!!parsed,this.offload_functions=!!offload_functions}async sendMessage(phoneID,to,message,context,biz_opaque_callback_data){const type=message._type,request={messaging_product:"whatsapp",type,to};request[type]=message._build(),context&&(request.context={message_id:context}),biz_opaque_callback_data&&(request.biz_opaque_callback_data=biz_opaque_callback_data);const promise=this.fetch(`https://graph.facebook.com/${this.v}/${phoneID}/messages`,{method:"POST",headers:{Authorization:`Bearer ${this.token}`,"Content-Type":"application/json"},body:JSON.stringify(request)}),response=this.parsed?await(await promise).json():void 0,args={phoneID,to,type,message,request,id:response&&"messages"in response?response.messages[0].id:void 0,response};return this.user_function(this.on?.sent,args),response??promise}async broadcastMessage(phoneID,to,message,batch_size=50,delay=1e3){const responses=[];if(batch_size<1)throw new RangeError("batch_size must be greater than 0");if(delay<0)throw new RangeError("delay must be greater or equal to 0");for(let i=0;i<to.length;i+=batch_size){i!==0&&await new Promise(resolve=>setTimeout(resolve,delay));for(const u of to.slice(i,i+batch_size))responses.push(this.sendMessage(phoneID,u,message))}return responses}async markAsRead(phoneID,messageId){const promise=this.fetch(`https://graph.facebook.com/${this.v}/${phoneID}/messages`,{method:"POST",headers:{Authorization:`Bearer ${this.token}`,"Content-Type":"application/json"},body:JSON.stringify({messaging_product:"whatsapp",status:"read",message_id:messageId})});return this.getBody(promise)}async createQR(phoneID,message,format="png"){const promise=this.fetch(`https://graph.facebook.com/${this.v}/${phoneID}/message_qrdls?generate_qr_image=${format}&prefilled_message=${message}`,{method:"POST",headers:{Authorization:`Bearer ${this.token}`}});return this.getBody(promise)}async retrieveQR(phoneID,id){const promise=this.fetch(`https://graph.facebook.com/${this.v}/${phoneID}/message_qrdls/${id??""}`,{headers:{Authorization:`Bearer ${this.token}`}});return this.getBody(promise)}async updateQR(phoneID,id,message){const promise=this.fetch(`https://graph.facebook.com/${this.v}/${phoneID}/message_qrdls/${id}?prefilled_message=${message}`,{method:"POST",headers:{Authorization:`Bearer ${this.token}`}});return this.getBody(promise)}async deleteQR(phoneID,id){const promise=this.fetch(`https://graph.facebook.com/${this.v}/${phoneID}/message_qrdls/${id}`,{method:"DELETE",headers:{Authorization:`Bearer ${this.token}`}});return this.getBody(promise)}async retrieveMedia(id,phoneID){const params=phoneID?`phone_number_id=${phoneID}`:"",promise=this.fetch(`https://graph.facebook.com/${this.v}/${id}?${params}`,{headers:{Authorization:`Bearer ${this.token}`}});return this.getBody(promise)}async uploadMedia(phoneID,form,check=!0){if(check){if(!form||typeof form!="object"||!("get"in form)||typeof form.get!="function")throw new TypeError("File's Form must be an instance of FormData");const file=form.get("file");if(!file.type)throw new Error("File's Blob must have a type specified");if(!["audio/aac","audio/mp4","audio/mpeg","audio/amr","audio/ogg","text/plain","application/pdf","application/vnd.ms-powerpoint","application/msword","application/vnd.ms-excel","application/vnd.openxmlformats-officedocument.wordprocessingml.document","application/vnd.openxmlformats-officedocument.presentationml.presentation","application/vnd.openxmlformats-officedocument.spreadsheetml.sheet","image/jpeg","image/png","video/mp4","video/3gp","image/webp"].includes(file.type))throw new Error(`Invalid media type: ${file.type}`);const validMediaSizes={audio:16e6,text:1e8,application:1e8,image:5e6,video:16e6,sticker:5e5},mediaType=file.type==="image/webp"?"sticker":file.type.split("/")[0];if(file.size&&file.size>validMediaSizes[mediaType])throw new Error(`File is too big (${file.size} bytes) for a ${mediaType} (${validMediaSizes[mediaType]} bytes limit)`)}const promise=this.fetch(`https://graph.facebook.com/${this.v}/${phoneID}/media?messaging_product=whatsapp`,{method:"POST",body:form,headers:{Authorization:`Bearer ${this.token}`,"Content-Type":"multipart/form-data"}});return this.getBody(promise)}fetchMedia(url){return this._authenicatedRequest(new URL(url))}async deleteMedia(id,phoneID){const params=phoneID?`phone_number_id=${phoneID}`:"",promise=this.fetch(`https://graph.facebook.com/${this.v}/${id}?${params}`,{method:"DELETE",headers:{Authorization:`Bearer ${this.token}`}});return this.getBody(promise)}async post(data,raw_body,signature){if(this.secure){if(!this.appSecret)throw 500;if(!this.subtle)throw 501;if(!raw_body)throw 400;if(signature=signature?.split("sha256=")[1],!signature)throw 401;const encoder=new TextEncoder,keyBuffer=encoder.encode(this.appSecret),key=await this.subtle.importKey("raw",keyBuffer,{name:"HMAC",hash:"SHA-256"},!0,["sign","verify"]),data2=encoder.encode((0,import_utils.escapeUnicode)(raw_body)),result=await this.subtle.sign("HMAC",key,data2.buffer),check=Array.from(new Uint8Array(result)).map(b=>b.toString(16).padStart(2,"0")).join("");if(signature!==check)throw 401}if(!data.object)throw 400;const value=data.entry[0].changes[0].value,phoneID=value.metadata.phone_number_id;if("messages"in value){const message=value.messages[0],contact=value.contacts?.[0],from=contact?.wa_id??message.from,name=contact?.profile.name,args={phoneID,from,message,name,raw:data,reply:(response,context=!1,biz_opaque_callback_data)=>this.sendMessage(phoneID,from,response,context?message.id:void 0,biz_opaque_callback_data),Whatsapp:this};this.user_function(this.on?.message,args)}else if("statuses"in value){const statuses=value.statuses[0],phone=statuses.recipient_id,status=statuses.status,id=statuses.id,conversation=statuses.conversation,pricing=statuses.pricing,error=statuses.errors?.[0],biz_opaque_callback_data=statuses.biz_opaque_callback_data,args={phoneID,phone,status,id,conversation,pricing,error,biz_opaque_callback_data,raw:data};this.user_function(this.on?.status,args)}return 200}get(params){if(!this.webhookVerifyToken)throw 500;const{"hub.mode":mode,"hub.verify_token":token,"hub.challenge":challenge}=params;if(!mode||!token)throw 400;if(mode==="subscribe"&&token===this.webhookVerifyToken)return challenge;throw 403}_authenicatedRequest(url){if(!url)throw new Error("URL must be specified");return this.fetch(url,{headers:{Authorization:`Bearer ${this.token}`}})}async getBody(promise){return this.parsed?await(await promise).json():promise}user_function(f,...a){f&&(this.offload_functions?this.offload(f,...a):f(...a))}offload(f,...a){Promise.resolve().then(()=>f(...a))}}
"use strict";var __defProp=Object.defineProperty;var __getOwnPropDesc=Object.getOwnPropertyDescriptor;var __getOwnPropNames=Object.getOwnPropertyNames;var __hasOwnProp=Object.prototype.hasOwnProperty;var __export=(target,all)=>{for(var name in all)__defProp(target,name,{get:all[name],enumerable:!0})},__copyProps=(to,from,except,desc)=>{if(from&&typeof from=="object"||typeof from=="function")for(let key of __getOwnPropNames(from))!__hasOwnProp.call(to,key)&&key!==except&&__defProp(to,key,{get:()=>from[key],enumerable:!(desc=__getOwnPropDesc(from,key))||desc.enumerable});return to};var __toCommonJS=mod=>__copyProps(__defProp({},"__esModule",{value:!0}),mod);var src_exports={};__export(src_exports,{default:()=>WhatsAppAPI});module.exports=__toCommonJS(src_exports);var import_utils=require("./utils.js");class WhatsAppAPI{token;appSecret;webhookVerifyToken;v;fetch;subtle;parsed;offload_functions;secure;on={};constructor({token,appSecret,webhookVerifyToken,v="v19.0",parsed=!0,offload_functions=!0,secure=!0,ponyfill={}}){if(this.token=token,this.secure=!!secure,this.secure){if(this.appSecret=appSecret,typeof ponyfill.subtle!="object"&&(typeof crypto!="object"||typeof crypto?.subtle!="object"))throw new Error("subtle is not defined in the enviroment. Consider using a setup helper, defined at 'whatsapp-api-js/setup', or provide a valid ponyfill object with the argument 'ponyfill.subtle'.");this.subtle=ponyfill.subtle||crypto.subtle}if(webhookVerifyToken&&(this.webhookVerifyToken=webhookVerifyToken),typeof ponyfill.fetch!="function"&&typeof fetch!="function")throw new Error("fetch is not defined in the enviroment. Consider using a setup helper, defined at 'whatsapp-api-js/setup', or provide a valid ponyfill object with the argument 'ponyfill.fetch'.");this.fetch=ponyfill.fetch||fetch,this.v=v,this.parsed=!!parsed,this.offload_functions=!!offload_functions}async sendMessage(phoneID,to,message,context,biz_opaque_callback_data){const type=message._type,request={messaging_product:"whatsapp",type,to};request[type]=message._build(),context&&(request.context={message_id:context}),biz_opaque_callback_data&&(request.biz_opaque_callback_data=biz_opaque_callback_data);const promise=this.fetch(`https://graph.facebook.com/${this.v}/${phoneID}/messages`,{method:"POST",headers:{Authorization:`Bearer ${this.token}`,"Content-Type":"application/json"},body:JSON.stringify(request)}),response=this.parsed?await(await promise).json():void 0,args={phoneID,to,type,message,request,id:response&&"messages"in response?response.messages[0].id:void 0,response};return this.user_function(this.on?.sent,args),response??promise}async broadcastMessage(phoneID,to,message,batch_size=50,delay=1e3){const responses=[];if(batch_size<1)throw new RangeError("batch_size must be greater than 0");if(delay<0)throw new RangeError("delay must be greater or equal to 0");for(let i=0;i<to.length;i+=batch_size){i!==0&&await new Promise(resolve=>setTimeout(resolve,delay));for(const u of to.slice(i,i+batch_size))responses.push(this.sendMessage(phoneID,u,message))}return responses}async markAsRead(phoneID,messageId){const promise=this.fetch(`https://graph.facebook.com/${this.v}/${phoneID}/messages`,{method:"POST",headers:{Authorization:`Bearer ${this.token}`,"Content-Type":"application/json"},body:JSON.stringify({messaging_product:"whatsapp",status:"read",message_id:messageId})});return this.getBody(promise)}async createQR(phoneID,message,format="png"){const promise=this.fetch(`https://graph.facebook.com/${this.v}/${phoneID}/message_qrdls?generate_qr_image=${format}&prefilled_message=${message}`,{method:"POST",headers:{Authorization:`Bearer ${this.token}`}});return this.getBody(promise)}async retrieveQR(phoneID,id){const promise=this.fetch(`https://graph.facebook.com/${this.v}/${phoneID}/message_qrdls/${id??""}`,{headers:{Authorization:`Bearer ${this.token}`}});return this.getBody(promise)}async updateQR(phoneID,id,message){const promise=this.fetch(`https://graph.facebook.com/${this.v}/${phoneID}/message_qrdls/${id}?prefilled_message=${message}`,{method:"POST",headers:{Authorization:`Bearer ${this.token}`}});return this.getBody(promise)}async deleteQR(phoneID,id){const promise=this.fetch(`https://graph.facebook.com/${this.v}/${phoneID}/message_qrdls/${id}`,{method:"DELETE",headers:{Authorization:`Bearer ${this.token}`}});return this.getBody(promise)}async retrieveMedia(id,phoneID){const params=phoneID?`phone_number_id=${phoneID}`:"",promise=this.fetch(`https://graph.facebook.com/${this.v}/${id}?${params}`,{headers:{Authorization:`Bearer ${this.token}`}});return this.getBody(promise)}async uploadMedia(phoneID,form,check=!0){if(check){if(!form||typeof form!="object"||!("get"in form)||typeof form.get!="function")throw new TypeError("File's Form must be an instance of FormData");const file=form.get("file");if(!file.type)throw new Error("File's Blob must have a type specified");if(!["audio/aac","audio/mp4","audio/mpeg","audio/amr","audio/ogg","text/plain","application/pdf","application/vnd.ms-powerpoint","application/msword","application/vnd.ms-excel","application/vnd.openxmlformats-officedocument.wordprocessingml.document","application/vnd.openxmlformats-officedocument.presentationml.presentation","application/vnd.openxmlformats-officedocument.spreadsheetml.sheet","image/jpeg","image/png","video/mp4","video/3gp","image/webp"].includes(file.type))throw new Error(`Invalid media type: ${file.type}`);const validMediaSizes={audio:16e6,text:1e8,application:1e8,image:5e6,video:16e6,sticker:5e5},mediaType=file.type==="image/webp"?"sticker":file.type.split("/")[0];if(file.size&&file.size>validMediaSizes[mediaType])throw new Error(`File is too big (${file.size} bytes) for a ${mediaType} (${validMediaSizes[mediaType]} bytes limit)`)}const promise=this.fetch(`https://graph.facebook.com/${this.v}/${phoneID}/media?messaging_product=whatsapp`,{method:"POST",body:form,headers:{Authorization:`Bearer ${this.token}`,"Content-Type":"multipart/form-data"}});return this.getBody(promise)}fetchMedia(url){return this._authenicatedRequest(new URL(url))}async deleteMedia(id,phoneID){const params=phoneID?`phone_number_id=${phoneID}`:"",promise=this.fetch(`https://graph.facebook.com/${this.v}/${id}?${params}`,{method:"DELETE",headers:{Authorization:`Bearer ${this.token}`}});return this.getBody(promise)}async post(data,raw_body,signature){if(this.secure){if(!this.appSecret)throw 500;if(!this.subtle)throw 501;if(!raw_body)throw 400;if(signature=signature?.split("sha256=")[1],!signature)throw 401;const encoder=new TextEncoder,keyBuffer=encoder.encode(this.appSecret),key=await this.subtle.importKey("raw",keyBuffer,{name:"HMAC",hash:"SHA-256"},!0,["sign","verify"]),data2=encoder.encode((0,import_utils.escapeUnicode)(raw_body)),result=await this.subtle.sign("HMAC",key,data2.buffer),check=Array.from(new Uint8Array(result)).map(b=>b.toString(16).padStart(2,"0")).join("");if(signature!==check)throw 401}if(!data.object)throw 400;const value=data.entry[0].changes[0].value,phoneID=value.metadata.phone_number_id;if("messages"in value){const message=value.messages[0],contact=value.contacts?.[0],from=contact?.wa_id??message.from,name=contact?.profile.name,args={phoneID,from,message,name,raw:data,reply:(response,context=!1,biz_opaque_callback_data)=>this.sendMessage(phoneID,from,response,context?message.id:void 0,biz_opaque_callback_data),Whatsapp:this};this.user_function(this.on?.message,args)}else if("statuses"in value){const statuses=value.statuses[0],phone=statuses.recipient_id,status=statuses.status,id=statuses.id,conversation=statuses.conversation,pricing=statuses.pricing,error=statuses.errors?.[0],biz_opaque_callback_data=statuses.biz_opaque_callback_data,args={phoneID,phone,status,id,conversation,pricing,error,biz_opaque_callback_data,raw:data};this.user_function(this.on?.status,args)}return 200}get(params){if(!this.webhookVerifyToken)throw 500;const{"hub.mode":mode,"hub.verify_token":token,"hub.challenge":challenge}=params;if(!mode||!token)throw 400;if(mode==="subscribe"&&token===this.webhookVerifyToken)return challenge;throw 403}_authenicatedRequest(url){if(!url)throw new Error("URL must be specified");return this.fetch(url,{headers:{Authorization:`Bearer ${this.token}`}})}async getBody(promise){return this.parsed?await(await promise).json():promise}user_function(f,...a){f&&(this.offload_functions?this.offload(f,...a):f(...a))}offload(f,...a){Promise.resolve().then(()=>f(...a))}}
//# sourceMappingURL=index.js.map

@@ -1,2 +0,2 @@

import{escapeUnicode}from"./utils.js";class WhatsAppAPI{token;appSecret;webhookVerifyToken;v;fetch;subtle;parsed;offload_functions;secure;on={};constructor({token,appSecret,webhookVerifyToken,v="v18.0",parsed=!0,offload_functions=!0,secure=!0,ponyfill={}}){if(this.token=token,this.secure=!!secure,this.secure){if(this.appSecret=appSecret,typeof ponyfill.subtle!="object"&&(typeof crypto!="object"||typeof crypto?.subtle!="object"))throw new Error("subtle is not defined in the enviroment. Consider using a setup helper, defined at 'whatsapp-api-js/setup', or provide a valid ponyfill object with the argument 'ponyfill.subtle'.");this.subtle=ponyfill.subtle||crypto.subtle}if(webhookVerifyToken&&(this.webhookVerifyToken=webhookVerifyToken),typeof ponyfill.fetch!="function"&&typeof fetch!="function")throw new Error("fetch is not defined in the enviroment. Consider using a setup helper, defined at 'whatsapp-api-js/setup', or provide a valid ponyfill object with the argument 'ponyfill.fetch'.");this.fetch=ponyfill.fetch||fetch,this.v=v,this.parsed=!!parsed,this.offload_functions=!!offload_functions}async sendMessage(phoneID,to,message,context,biz_opaque_callback_data){const type=message._type,request={messaging_product:"whatsapp",type,to};request[type]=message._build(),context&&(request.context={message_id:context}),biz_opaque_callback_data&&(request.biz_opaque_callback_data=biz_opaque_callback_data);const promise=this.fetch(`https://graph.facebook.com/${this.v}/${phoneID}/messages`,{method:"POST",headers:{Authorization:`Bearer ${this.token}`,"Content-Type":"application/json"},body:JSON.stringify(request)}),response=this.parsed?await(await promise).json():void 0,args={phoneID,to,type,message,request,id:response&&"messages"in response?response.messages[0].id:void 0,response};return this.user_function(this.on?.sent,args),response??promise}async broadcastMessage(phoneID,to,message,batch_size=50,delay=1e3){const responses=[];if(batch_size<1)throw new RangeError("batch_size must be greater than 0");if(delay<0)throw new RangeError("delay must be greater or equal to 0");for(let i=0;i<to.length;i+=batch_size){i!==0&&await new Promise(resolve=>setTimeout(resolve,delay));for(const u of to.slice(i,i+batch_size))responses.push(this.sendMessage(phoneID,u,message))}return responses}async markAsRead(phoneID,messageId){const promise=this.fetch(`https://graph.facebook.com/${this.v}/${phoneID}/messages`,{method:"POST",headers:{Authorization:`Bearer ${this.token}`,"Content-Type":"application/json"},body:JSON.stringify({messaging_product:"whatsapp",status:"read",message_id:messageId})});return this.getBody(promise)}async createQR(phoneID,message,format="png"){const promise=this.fetch(`https://graph.facebook.com/${this.v}/${phoneID}/message_qrdls?generate_qr_image=${format}&prefilled_message=${message}`,{method:"POST",headers:{Authorization:`Bearer ${this.token}`}});return this.getBody(promise)}async retrieveQR(phoneID,id){const promise=this.fetch(`https://graph.facebook.com/${this.v}/${phoneID}/message_qrdls/${id??""}`,{headers:{Authorization:`Bearer ${this.token}`}});return this.getBody(promise)}async updateQR(phoneID,id,message){const promise=this.fetch(`https://graph.facebook.com/${this.v}/${phoneID}/message_qrdls/${id}?prefilled_message=${message}`,{method:"POST",headers:{Authorization:`Bearer ${this.token}`}});return this.getBody(promise)}async deleteQR(phoneID,id){const promise=this.fetch(`https://graph.facebook.com/${this.v}/${phoneID}/message_qrdls/${id}`,{method:"DELETE",headers:{Authorization:`Bearer ${this.token}`}});return this.getBody(promise)}async retrieveMedia(id,phoneID){const params=phoneID?`phone_number_id=${phoneID}`:"",promise=this.fetch(`https://graph.facebook.com/${this.v}/${id}?${params}`,{headers:{Authorization:`Bearer ${this.token}`}});return this.getBody(promise)}async uploadMedia(phoneID,form,check=!0){if(check){if(!form||typeof form!="object"||!("get"in form)||typeof form.get!="function")throw new TypeError("File's Form must be an instance of FormData");const file=form.get("file");if(!file.type)throw new Error("File's Blob must have a type specified");if(!["audio/aac","audio/mp4","audio/mpeg","audio/amr","audio/ogg","text/plain","application/pdf","application/vnd.ms-powerpoint","application/msword","application/vnd.ms-excel","application/vnd.openxmlformats-officedocument.wordprocessingml.document","application/vnd.openxmlformats-officedocument.presentationml.presentation","application/vnd.openxmlformats-officedocument.spreadsheetml.sheet","image/jpeg","image/png","video/mp4","video/3gp","image/webp"].includes(file.type))throw new Error(`Invalid media type: ${file.type}`);const validMediaSizes={audio:16e6,text:1e8,application:1e8,image:5e6,video:16e6,sticker:5e5},mediaType=file.type==="image/webp"?"sticker":file.type.split("/")[0];if(file.size&&file.size>validMediaSizes[mediaType])throw new Error(`File is too big (${file.size} bytes) for a ${mediaType} (${validMediaSizes[mediaType]} bytes limit)`)}const promise=this.fetch(`https://graph.facebook.com/${this.v}/${phoneID}/media?messaging_product=whatsapp`,{method:"POST",body:form,headers:{Authorization:`Bearer ${this.token}`,"Content-Type":"multipart/form-data"}});return this.getBody(promise)}fetchMedia(url){return this._authenicatedRequest(new URL(url))}async deleteMedia(id,phoneID){const params=phoneID?`phone_number_id=${phoneID}`:"",promise=this.fetch(`https://graph.facebook.com/${this.v}/${id}?${params}`,{method:"DELETE",headers:{Authorization:`Bearer ${this.token}`}});return this.getBody(promise)}async post(data,raw_body,signature){if(this.secure){if(!this.appSecret)throw 500;if(!this.subtle)throw 501;if(!raw_body)throw 400;if(signature=signature?.split("sha256=")[1],!signature)throw 401;const encoder=new TextEncoder,keyBuffer=encoder.encode(this.appSecret),key=await this.subtle.importKey("raw",keyBuffer,{name:"HMAC",hash:"SHA-256"},!0,["sign","verify"]),data2=encoder.encode(escapeUnicode(raw_body)),result=await this.subtle.sign("HMAC",key,data2.buffer),check=Array.from(new Uint8Array(result)).map(b=>b.toString(16).padStart(2,"0")).join("");if(signature!==check)throw 401}if(!data.object)throw 400;const value=data.entry[0].changes[0].value,phoneID=value.metadata.phone_number_id;if("messages"in value){const message=value.messages[0],contact=value.contacts?.[0],from=contact?.wa_id??message.from,name=contact?.profile.name,args={phoneID,from,message,name,raw:data,reply:(response,context=!1,biz_opaque_callback_data)=>this.sendMessage(phoneID,from,response,context?message.id:void 0,biz_opaque_callback_data),Whatsapp:this};this.user_function(this.on?.message,args)}else if("statuses"in value){const statuses=value.statuses[0],phone=statuses.recipient_id,status=statuses.status,id=statuses.id,conversation=statuses.conversation,pricing=statuses.pricing,error=statuses.errors?.[0],biz_opaque_callback_data=statuses.biz_opaque_callback_data,args={phoneID,phone,status,id,conversation,pricing,error,biz_opaque_callback_data,raw:data};this.user_function(this.on?.status,args)}return 200}get(params){if(!this.webhookVerifyToken)throw 500;const{"hub.mode":mode,"hub.verify_token":token,"hub.challenge":challenge}=params;if(!mode||!token)throw 400;if(mode==="subscribe"&&token===this.webhookVerifyToken)return challenge;throw 403}_authenicatedRequest(url){if(!url)throw new Error("URL must be specified");return this.fetch(url,{headers:{Authorization:`Bearer ${this.token}`}})}async getBody(promise){return this.parsed?await(await promise).json():promise}user_function(f,...a){f&&(this.offload_functions?this.offload(f,...a):f(...a))}offload(f,...a){Promise.resolve().then(()=>f(...a))}}export{WhatsAppAPI as default};
import{escapeUnicode}from"./utils.js";class WhatsAppAPI{token;appSecret;webhookVerifyToken;v;fetch;subtle;parsed;offload_functions;secure;on={};constructor({token,appSecret,webhookVerifyToken,v="v19.0",parsed=!0,offload_functions=!0,secure=!0,ponyfill={}}){if(this.token=token,this.secure=!!secure,this.secure){if(this.appSecret=appSecret,typeof ponyfill.subtle!="object"&&(typeof crypto!="object"||typeof crypto?.subtle!="object"))throw new Error("subtle is not defined in the enviroment. Consider using a setup helper, defined at 'whatsapp-api-js/setup', or provide a valid ponyfill object with the argument 'ponyfill.subtle'.");this.subtle=ponyfill.subtle||crypto.subtle}if(webhookVerifyToken&&(this.webhookVerifyToken=webhookVerifyToken),typeof ponyfill.fetch!="function"&&typeof fetch!="function")throw new Error("fetch is not defined in the enviroment. Consider using a setup helper, defined at 'whatsapp-api-js/setup', or provide a valid ponyfill object with the argument 'ponyfill.fetch'.");this.fetch=ponyfill.fetch||fetch,this.v=v,this.parsed=!!parsed,this.offload_functions=!!offload_functions}async sendMessage(phoneID,to,message,context,biz_opaque_callback_data){const type=message._type,request={messaging_product:"whatsapp",type,to};request[type]=message._build(),context&&(request.context={message_id:context}),biz_opaque_callback_data&&(request.biz_opaque_callback_data=biz_opaque_callback_data);const promise=this.fetch(`https://graph.facebook.com/${this.v}/${phoneID}/messages`,{method:"POST",headers:{Authorization:`Bearer ${this.token}`,"Content-Type":"application/json"},body:JSON.stringify(request)}),response=this.parsed?await(await promise).json():void 0,args={phoneID,to,type,message,request,id:response&&"messages"in response?response.messages[0].id:void 0,response};return this.user_function(this.on?.sent,args),response??promise}async broadcastMessage(phoneID,to,message,batch_size=50,delay=1e3){const responses=[];if(batch_size<1)throw new RangeError("batch_size must be greater than 0");if(delay<0)throw new RangeError("delay must be greater or equal to 0");for(let i=0;i<to.length;i+=batch_size){i!==0&&await new Promise(resolve=>setTimeout(resolve,delay));for(const u of to.slice(i,i+batch_size))responses.push(this.sendMessage(phoneID,u,message))}return responses}async markAsRead(phoneID,messageId){const promise=this.fetch(`https://graph.facebook.com/${this.v}/${phoneID}/messages`,{method:"POST",headers:{Authorization:`Bearer ${this.token}`,"Content-Type":"application/json"},body:JSON.stringify({messaging_product:"whatsapp",status:"read",message_id:messageId})});return this.getBody(promise)}async createQR(phoneID,message,format="png"){const promise=this.fetch(`https://graph.facebook.com/${this.v}/${phoneID}/message_qrdls?generate_qr_image=${format}&prefilled_message=${message}`,{method:"POST",headers:{Authorization:`Bearer ${this.token}`}});return this.getBody(promise)}async retrieveQR(phoneID,id){const promise=this.fetch(`https://graph.facebook.com/${this.v}/${phoneID}/message_qrdls/${id??""}`,{headers:{Authorization:`Bearer ${this.token}`}});return this.getBody(promise)}async updateQR(phoneID,id,message){const promise=this.fetch(`https://graph.facebook.com/${this.v}/${phoneID}/message_qrdls/${id}?prefilled_message=${message}`,{method:"POST",headers:{Authorization:`Bearer ${this.token}`}});return this.getBody(promise)}async deleteQR(phoneID,id){const promise=this.fetch(`https://graph.facebook.com/${this.v}/${phoneID}/message_qrdls/${id}`,{method:"DELETE",headers:{Authorization:`Bearer ${this.token}`}});return this.getBody(promise)}async retrieveMedia(id,phoneID){const params=phoneID?`phone_number_id=${phoneID}`:"",promise=this.fetch(`https://graph.facebook.com/${this.v}/${id}?${params}`,{headers:{Authorization:`Bearer ${this.token}`}});return this.getBody(promise)}async uploadMedia(phoneID,form,check=!0){if(check){if(!form||typeof form!="object"||!("get"in form)||typeof form.get!="function")throw new TypeError("File's Form must be an instance of FormData");const file=form.get("file");if(!file.type)throw new Error("File's Blob must have a type specified");if(!["audio/aac","audio/mp4","audio/mpeg","audio/amr","audio/ogg","text/plain","application/pdf","application/vnd.ms-powerpoint","application/msword","application/vnd.ms-excel","application/vnd.openxmlformats-officedocument.wordprocessingml.document","application/vnd.openxmlformats-officedocument.presentationml.presentation","application/vnd.openxmlformats-officedocument.spreadsheetml.sheet","image/jpeg","image/png","video/mp4","video/3gp","image/webp"].includes(file.type))throw new Error(`Invalid media type: ${file.type}`);const validMediaSizes={audio:16e6,text:1e8,application:1e8,image:5e6,video:16e6,sticker:5e5},mediaType=file.type==="image/webp"?"sticker":file.type.split("/")[0];if(file.size&&file.size>validMediaSizes[mediaType])throw new Error(`File is too big (${file.size} bytes) for a ${mediaType} (${validMediaSizes[mediaType]} bytes limit)`)}const promise=this.fetch(`https://graph.facebook.com/${this.v}/${phoneID}/media?messaging_product=whatsapp`,{method:"POST",body:form,headers:{Authorization:`Bearer ${this.token}`,"Content-Type":"multipart/form-data"}});return this.getBody(promise)}fetchMedia(url){return this._authenicatedRequest(new URL(url))}async deleteMedia(id,phoneID){const params=phoneID?`phone_number_id=${phoneID}`:"",promise=this.fetch(`https://graph.facebook.com/${this.v}/${id}?${params}`,{method:"DELETE",headers:{Authorization:`Bearer ${this.token}`}});return this.getBody(promise)}async post(data,raw_body,signature){if(this.secure){if(!this.appSecret)throw 500;if(!this.subtle)throw 501;if(!raw_body)throw 400;if(signature=signature?.split("sha256=")[1],!signature)throw 401;const encoder=new TextEncoder,keyBuffer=encoder.encode(this.appSecret),key=await this.subtle.importKey("raw",keyBuffer,{name:"HMAC",hash:"SHA-256"},!0,["sign","verify"]),data2=encoder.encode(escapeUnicode(raw_body)),result=await this.subtle.sign("HMAC",key,data2.buffer),check=Array.from(new Uint8Array(result)).map(b=>b.toString(16).padStart(2,"0")).join("");if(signature!==check)throw 401}if(!data.object)throw 400;const value=data.entry[0].changes[0].value,phoneID=value.metadata.phone_number_id;if("messages"in value){const message=value.messages[0],contact=value.contacts?.[0],from=contact?.wa_id??message.from,name=contact?.profile.name,args={phoneID,from,message,name,raw:data,reply:(response,context=!1,biz_opaque_callback_data)=>this.sendMessage(phoneID,from,response,context?message.id:void 0,biz_opaque_callback_data),Whatsapp:this};this.user_function(this.on?.message,args)}else if("statuses"in value){const statuses=value.statuses[0],phone=statuses.recipient_id,status=statuses.status,id=statuses.id,conversation=statuses.conversation,pricing=statuses.pricing,error=statuses.errors?.[0],biz_opaque_callback_data=statuses.biz_opaque_callback_data,args={phoneID,phone,status,id,conversation,pricing,error,biz_opaque_callback_data,raw:data};this.user_function(this.on?.status,args)}return 200}get(params){if(!this.webhookVerifyToken)throw 500;const{"hub.mode":mode,"hub.verify_token":token,"hub.challenge":challenge}=params;if(!mode||!token)throw 400;if(mode==="subscribe"&&token===this.webhookVerifyToken)return challenge;throw 403}_authenicatedRequest(url){if(!url)throw new Error("URL must be specified");return this.fetch(url,{headers:{Authorization:`Bearer ${this.token}`}})}async getBody(promise){return this.parsed?await(await promise).json():promise}user_function(f,...a){f&&(this.offload_functions?this.offload(f,...a):f(...a))}offload(f,...a){Promise.resolve().then(()=>f(...a))}}export{WhatsAppAPI as default};
//# sourceMappingURL=index.js.map

@@ -79,3 +79,3 @@ import type { ClientMessage, ClientMessageRequest, ServerMessage, ServerMessageResponse, ServerConversation, ServerPricing, ServerError, PostData } from "./types";

* @param context - Wether to mention the current message, defaults to false
* @param biz_opaque_callback_data - An arbitrary 256B string, useful for tracking
* @param biz_opaque_callback_data - An arbitrary 512B string, useful for tracking
* @returns WhatsAppAPI.sendMessage return value

@@ -82,0 +82,0 @@ */

@@ -107,3 +107,3 @@ /** @module WhatsAppAPI */

* @param context - The message ID of the message to reply to
* @param biz_opaque_callback_data - An arbitrary 256B string, useful for tracking (length not checked by the framework)
* @param biz_opaque_callback_data - An arbitrary 512B string, useful for tracking (length not checked by the framework)
* @returns The server response

@@ -110,0 +110,0 @@ */

@@ -61,3 +61,3 @@ /**

/**
* The version of the API, defaults to v18.0
* The version of the API, defaults to v19.0
*/

@@ -266,3 +266,3 @@ v?: string;

/**
* An arbitrary 256B string, useful for tracking.
* An arbitrary 512B string, useful for tracking.
*

@@ -269,0 +269,0 @@ * Any app subscribed to the messages webhook field on the WhatsApp Business Account can get this string,

{
"name": "whatsapp-api-js",
"version": "2.5.1",
"version": "2.6.0",
"author": "Secreto31126",

@@ -136,11 +136,11 @@ "description": "A TypeScript server agnostic Whatsapp's Official API framework",

"devDependencies": {
"@adonisjs/http-server": "7.0.0",
"@adonisjs/http-server": "7.0.2",
"@types/express": "4.17.21",
"@types/node": "18.19.8",
"@typescript-eslint/eslint-plugin": "6.19.0",
"@typescript-eslint/parser": "6.19.0",
"@vercel/node": "3.0.16",
"@types/node": "18.19.10",
"@typescript-eslint/eslint-plugin": "6.19.1",
"@typescript-eslint/parser": "6.19.1",
"@vercel/node": "3.0.17",
"all-contributors-cli": "6.26.1",
"c8": "9.1.0",
"dotenv": "16.3.2",
"dotenv": "16.4.1",
"esbuild": "0.19.0",

@@ -156,4 +156,4 @@ "eslint": "8.56.0",

"typescript": "5.3.3",
"undici": "6.4.0"
"undici": "6.5.0"
}
}

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc