whatsapp-api-js
Advanced tools
Comparing version 2.1.3-beta.0 to 2.2.0
@@ -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);class WhatsAppAPI{token;appSecret;webhookVerifyToken;v;fetch;subtle;parsed;secure;on={};constructor({token,appSecret,webhookVerifyToken,v="v18.0",parsed=!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}async sendMessage(phoneID,to,message,context){const type=message._type,request={messaging_product:"whatsapp",type,to};request[type]=message._build(),context&&(request.context={message_id:context});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.offload(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(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};this.offload(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],args={phoneID,phone,status,id,conversation,pricing,error,raw:data};this.offload(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}offload(f,...a){f&&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);class WhatsAppAPI{token;appSecret;webhookVerifyToken;v;fetch;subtle;parsed;secure;on={};constructor({token,appSecret,webhookVerifyToken,v="v18.0",parsed=!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}async sendMessage(phoneID,to,message,context){const type=message._type,request={messaging_product:"whatsapp",type,to};request[type]=message._build(),context&&(request.context={message_id:context});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.offload(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(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)=>this.sendMessage(phoneID,from,response,context?message.id:void 0)};this.offload(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],args={phoneID,phone,status,id,conversation,pricing,error,raw:data};this.offload(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}offload(f,...a){f&&Promise.resolve().then(()=>f(...a))}} | ||
//# sourceMappingURL=index.js.map |
@@ -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 template_exports={};__export(template_exports,{BodyComponent:()=>BodyComponent,BodyParameter:()=>BodyParameter,ButtonComponent:()=>ButtonComponent,CarouselCard:()=>CarouselCard,CarouselComponent:()=>CarouselComponent,CatalogComponent:()=>CatalogComponent,CopyComponent:()=>CopyComponent,Currency:()=>Currency,DateTime:()=>DateTime,HeaderComponent:()=>HeaderComponent,HeaderParameter:()=>HeaderParameter,Language:()=>Language,MPMComponent:()=>MPMComponent,PayloadComponent:()=>PayloadComponent,SkipButtonComponent:()=>SkipButtonComponent,Template:()=>Template,URLComponent:()=>URLComponent});module.exports=__toCommonJS(template_exports);var import_types=require("../types.js");class Template extends import_types.ClientMessage{name;language;components;get _type(){return"template"}constructor(name,language,...components){if(super(),this.name=name,this.language=typeof language=="string"?new Language(language):language,components.length){const pointers={theres_only_body:components.length===1&&components[0]instanceof BodyComponent,button_counter:0};this.components=components.map(cmpt=>cmpt._build(pointers)).filter(e=>!!e)}}static OTP(name,language,code){return new Template(name,language,new BodyComponent(new BodyParameter(code)),new URLComponent(code))}}class Language{code;policy;constructor(code,policy="deterministic"){this.policy=policy,this.code=code}}class Currency{amount_1000;code;fallback_value;get _type(){return"currency"}constructor(amount_1000,code,fallback_value){if(amount_1000<=0)throw new Error("Currency must have an amount_1000 greater than 0");this.amount_1000=amount_1000,this.code=code,this.fallback_value=fallback_value}}class DateTime{fallback_value;get _type(){return"date_time"}constructor(fallback_value){this.fallback_value=fallback_value}}class ButtonComponent{type="button";sub_type;parameters;index=NaN;constructor(sub_type,parameter){this.sub_type=sub_type,this.parameters=[parameter]}_build(pointers){return this.index=pointers.button_counter++,this}}class URLComponent extends ButtonComponent{constructor(parameter){super("url",new URLComponent.Button(parameter))}static Button=class{type="text";text;constructor(text){if(!text.length)throw new Error("Button parameter can't be an empty string");this.text=text}}}class PayloadComponent extends ButtonComponent{constructor(parameter){super("quick_reply",new PayloadComponent.Button(parameter))}static Button=class{type="payload";payload;constructor(payload){if(!payload.length)throw new Error("Button parameter can't be an empty string");this.payload=payload}}}class CatalogComponent extends ButtonComponent{constructor(thumbnail){super("catalog",new CatalogComponent.Action(thumbnail))}static Action=class{type="action";action;constructor(thumbnail){this.action={thumbnail_product_retailer_id:thumbnail.product_retailer_id}}}}class MPMComponent extends ButtonComponent{constructor(thumbnail,...sections){super("mpm",new MPMComponent.Action(thumbnail,sections))}static Action=class extends import_types.ClientLimitedMessageComponent{type="action";action;constructor(thumbnail,sections){if(super("MPMComponent","sections",sections,10),sections.length>1&&!sections.every(s=>!!s.title))throw new Error("All sections must have a title if more than 1 section is provided");this.action={thumbnail_product_retailer_id:thumbnail.product_retailer_id,sections}}}}class CopyComponent extends ButtonComponent{constructor(parameter){super("copy_code",new CopyComponent.Action(parameter))}static Action=class{type="coupon_code";coupon_code;constructor(coupon_code){if(!coupon_code.length)throw new Error("Action coupon_code can't be an empty string");this.coupon_code=coupon_code}}}class SkipButtonComponent extends ButtonComponent{constructor(){super()}_build(pointers){return pointers.button_counter++,null}}class HeaderComponent{type;parameters;constructor(...parameters){this.type="header",this.parameters=parameters}_build(){return this}}class HeaderParameter{type;text;currency;date_time;image;document;video;location;constructor(parameter){if(typeof parameter=="string"){if(parameter.length>60)throw new Error("Header text must be 60 characters or less");this.type="text"}else{if(parameter._type==="location"&&!(parameter.name&¶meter.address))throw new Error("Header location must have a name and address");this.type=parameter._type}Object.defineProperty(this,this.type,{value:parameter,enumerable:!0})}}class BodyComponent{type;parameters;constructor(...parameters){this.type="body",this.parameters=parameters}_build({theres_only_body}){if(!theres_only_body){for(const param of this.parameters)if(param.text&¶m.text?.length>1024)throw new Error("Body text must be 1024 characters or less")}return this}}class BodyParameter{type;text;currency;date_time;constructor(parameter){if(typeof parameter=="string"){if(parameter.length>32768)throw new Error("Body text must be 32768 characters or less");this.type="text"}else this.type=parameter._type;Object.defineProperty(this,this.type,{value:parameter,enumerable:!0})}}class CarouselComponent extends import_types.ClientLimitedMessageComponent{type="carousel";cards;constructor(...cards){super("CarouselComponent","CarouselCard",cards,10);const pointers={counter:0};this.cards=cards.map(cmpt=>cmpt._build(pointers))}_build(){return this}}class CarouselCard{card_index=NaN;components;constructor(header,...components){const tmp=new Template("","",new HeaderComponent(new HeaderParameter(header)),...components);this.components=tmp.components}_build(ptr){return this.card_index=ptr.counter++,this}}0&&(module.exports={BodyComponent,BodyParameter,ButtonComponent,CarouselCard,CarouselComponent,CatalogComponent,CopyComponent,Currency,DateTime,HeaderComponent,HeaderParameter,Language,MPMComponent,PayloadComponent,SkipButtonComponent,Template,URLComponent}); | ||
"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 template_exports={};__export(template_exports,{BodyComponent:()=>BodyComponent,BodyParameter:()=>BodyParameter,ButtonComponent:()=>ButtonComponent,CarouselCard:()=>CarouselCard,CarouselComponent:()=>CarouselComponent,CatalogComponent:()=>CatalogComponent,CopyComponent:()=>CopyComponent,Currency:()=>Currency,DateTime:()=>DateTime,HeaderComponent:()=>HeaderComponent,HeaderParameter:()=>HeaderParameter,LTOComponent:()=>LTOComponent,Language:()=>Language,MPMComponent:()=>MPMComponent,PayloadComponent:()=>PayloadComponent,SkipButtonComponent:()=>SkipButtonComponent,Template:()=>Template,URLComponent:()=>URLComponent});module.exports=__toCommonJS(template_exports);var import_types=require("../types.js");class Template extends import_types.ClientMessage{name;language;components;get _type(){return"template"}constructor(name,language,...components){if(super(),this.name=name,this.language=typeof language=="string"?new Language(language):language,components.length){const pointers={theres_only_body:components.length===1&&components[0]instanceof BodyComponent,button_counter:0};this.components=components.map(cmpt=>cmpt._build(pointers)).filter(e=>!!e)}}static OTP(name,language,code){return new Template(name,language,new BodyComponent(new BodyParameter(code)),new URLComponent(code))}}class Language{code;policy;constructor(code,policy="deterministic"){this.policy=policy,this.code=code}}class Currency{amount_1000;code;fallback_value;get _type(){return"currency"}constructor(amount_1000,code,fallback_value){if(amount_1000<=0)throw new Error("Currency must have an amount_1000 greater than 0");this.amount_1000=amount_1000,this.code=code,this.fallback_value=fallback_value}}class DateTime{fallback_value;get _type(){return"date_time"}constructor(fallback_value){this.fallback_value=fallback_value}}class ButtonComponent{type="button";sub_type;parameters;index=NaN;constructor(sub_type,parameter){this.sub_type=sub_type,this.parameters=[parameter]}_build(pointers){return this.index=pointers.button_counter++,this}}class URLComponent extends ButtonComponent{constructor(parameter){super("url",new URLComponent.Button(parameter))}static Button=class{type="text";text;constructor(text){if(!text.length)throw new Error("Button parameter can't be an empty string");this.text=text}}}class PayloadComponent extends ButtonComponent{constructor(parameter){super("quick_reply",new PayloadComponent.Button(parameter))}static Button=class{type="payload";payload;constructor(payload){if(!payload.length)throw new Error("Button parameter can't be an empty string");this.payload=payload}}}class CatalogComponent extends ButtonComponent{constructor(thumbnail){super("catalog",new CatalogComponent.Action(thumbnail))}static Action=class{type="action";action;constructor(thumbnail){this.action={thumbnail_product_retailer_id:thumbnail.product_retailer_id}}}}class MPMComponent extends ButtonComponent{constructor(thumbnail,...sections){super("mpm",new MPMComponent.Action(thumbnail,sections))}static Action=class extends import_types.ClientLimitedMessageComponent{type="action";action;constructor(thumbnail,sections){if(super("MPMComponent","sections",sections,10),sections.length>1&&!sections.every(s=>!!s.title))throw new Error("All sections must have a title if more than 1 section is provided");this.action={thumbnail_product_retailer_id:thumbnail.product_retailer_id,sections}}}}class CopyComponent extends ButtonComponent{constructor(parameter){super("copy_code",new CopyComponent.Action(parameter))}static Action=class{type="coupon_code";coupon_code;constructor(coupon_code){if(!coupon_code.length)throw new Error("Action coupon_code can't be an empty string");this.coupon_code=coupon_code}}}class SkipButtonComponent extends ButtonComponent{constructor(){super()}_build(pointers){return pointers.button_counter++,null}}class HeaderComponent{type;parameters;constructor(...parameters){this.type="header",this.parameters=parameters}_build(){return this}}class HeaderParameter{type;text;currency;date_time;image;document;video;location;constructor(parameter){if(typeof parameter=="string"){if(parameter.length>60)throw new Error("Header text must be 60 characters or less");this.type="text"}else{if(parameter._type==="location"&&!(parameter.name&¶meter.address))throw new Error("Header location must have a name and address");this.type=parameter._type}Object.defineProperty(this,this.type,{value:parameter,enumerable:!0})}}class BodyComponent{type;parameters;constructor(...parameters){this.type="body",this.parameters=parameters}_build({theres_only_body}){if(!theres_only_body){for(const param of this.parameters)if(param.text&¶m.text?.length>1024)throw new Error("Body text must be 1024 characters or less")}return this}}class BodyParameter{type;text;currency;date_time;constructor(parameter){if(typeof parameter=="string"){if(parameter.length>32768)throw new Error("Body text must be 32768 characters or less");this.type="text"}else this.type=parameter._type;Object.defineProperty(this,this.type,{value:parameter,enumerable:!0})}}class CarouselComponent extends import_types.ClientLimitedMessageComponent{type="carousel";cards;constructor(...cards){super("CarouselComponent","CarouselCard",cards,10);const pointers={counter:0};this.cards=cards.map(cmpt=>cmpt._build(pointers))}_build(){return this}}class CarouselCard{card_index=NaN;components;constructor(header,...components){const tmp=new Template("","",new HeaderComponent(new HeaderParameter(header)),...components);this.components=tmp.components}_build(ptr){return this.card_index=ptr.counter++,this}}class LTOComponent{type="limited_time_offer";parameters;constructor(expiration){if(expiration<0)throw new Error("Expiration time must be a positive Unix timestamp");this.parameters=[{type:"limited_time_offer",limited_time_offer:{expiration_time_ms:expiration}}]}_build(){return this}}0&&(module.exports={BodyComponent,BodyParameter,ButtonComponent,CarouselCard,CarouselComponent,CatalogComponent,CopyComponent,Currency,DateTime,HeaderComponent,HeaderParameter,LTOComponent,Language,MPMComponent,PayloadComponent,SkipButtonComponent,Template,URLComponent}); | ||
//# sourceMappingURL=template.js.map |
@@ -1,2 +0,2 @@ | ||
class WhatsAppAPI{token;appSecret;webhookVerifyToken;v;fetch;subtle;parsed;secure;on={};constructor({token,appSecret,webhookVerifyToken,v="v18.0",parsed=!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}async sendMessage(phoneID,to,message,context){const type=message._type,request={messaging_product:"whatsapp",type,to};request[type]=message._build(),context&&(request.context={message_id:context});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.offload(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(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};this.offload(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],args={phoneID,phone,status,id,conversation,pricing,error,raw:data};this.offload(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}offload(f,...a){f&&Promise.resolve().then(()=>f(...a))}}export{WhatsAppAPI as default}; | ||
class WhatsAppAPI{token;appSecret;webhookVerifyToken;v;fetch;subtle;parsed;secure;on={};constructor({token,appSecret,webhookVerifyToken,v="v18.0",parsed=!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}async sendMessage(phoneID,to,message,context){const type=message._type,request={messaging_product:"whatsapp",type,to};request[type]=message._build(),context&&(request.context={message_id:context});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.offload(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(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)=>this.sendMessage(phoneID,from,response,context?message.id:void 0)};this.offload(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],args={phoneID,phone,status,id,conversation,pricing,error,raw:data};this.offload(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}offload(f,...a){f&&Promise.resolve().then(()=>f(...a))}}export{WhatsAppAPI as default}; | ||
//# sourceMappingURL=index.js.map |
@@ -1,2 +0,2 @@ | ||
import{ClientMessage,ClientLimitedMessageComponent}from"../types.js";class Template extends ClientMessage{name;language;components;get _type(){return"template"}constructor(name,language,...components){if(super(),this.name=name,this.language=typeof language=="string"?new Language(language):language,components.length){const pointers={theres_only_body:components.length===1&&components[0]instanceof BodyComponent,button_counter:0};this.components=components.map(cmpt=>cmpt._build(pointers)).filter(e=>!!e)}}static OTP(name,language,code){return new Template(name,language,new BodyComponent(new BodyParameter(code)),new URLComponent(code))}}class Language{code;policy;constructor(code,policy="deterministic"){this.policy=policy,this.code=code}}class Currency{amount_1000;code;fallback_value;get _type(){return"currency"}constructor(amount_1000,code,fallback_value){if(amount_1000<=0)throw new Error("Currency must have an amount_1000 greater than 0");this.amount_1000=amount_1000,this.code=code,this.fallback_value=fallback_value}}class DateTime{fallback_value;get _type(){return"date_time"}constructor(fallback_value){this.fallback_value=fallback_value}}class ButtonComponent{type="button";sub_type;parameters;index=NaN;constructor(sub_type,parameter){this.sub_type=sub_type,this.parameters=[parameter]}_build(pointers){return this.index=pointers.button_counter++,this}}class URLComponent extends ButtonComponent{constructor(parameter){super("url",new URLComponent.Button(parameter))}static Button=class{type="text";text;constructor(text){if(!text.length)throw new Error("Button parameter can't be an empty string");this.text=text}}}class PayloadComponent extends ButtonComponent{constructor(parameter){super("quick_reply",new PayloadComponent.Button(parameter))}static Button=class{type="payload";payload;constructor(payload){if(!payload.length)throw new Error("Button parameter can't be an empty string");this.payload=payload}}}class CatalogComponent extends ButtonComponent{constructor(thumbnail){super("catalog",new CatalogComponent.Action(thumbnail))}static Action=class{type="action";action;constructor(thumbnail){this.action={thumbnail_product_retailer_id:thumbnail.product_retailer_id}}}}class MPMComponent extends ButtonComponent{constructor(thumbnail,...sections){super("mpm",new MPMComponent.Action(thumbnail,sections))}static Action=class extends ClientLimitedMessageComponent{type="action";action;constructor(thumbnail,sections){if(super("MPMComponent","sections",sections,10),sections.length>1&&!sections.every(s=>!!s.title))throw new Error("All sections must have a title if more than 1 section is provided");this.action={thumbnail_product_retailer_id:thumbnail.product_retailer_id,sections}}}}class CopyComponent extends ButtonComponent{constructor(parameter){super("copy_code",new CopyComponent.Action(parameter))}static Action=class{type="coupon_code";coupon_code;constructor(coupon_code){if(!coupon_code.length)throw new Error("Action coupon_code can't be an empty string");this.coupon_code=coupon_code}}}class SkipButtonComponent extends ButtonComponent{constructor(){super()}_build(pointers){return pointers.button_counter++,null}}class HeaderComponent{type;parameters;constructor(...parameters){this.type="header",this.parameters=parameters}_build(){return this}}class HeaderParameter{type;text;currency;date_time;image;document;video;location;constructor(parameter){if(typeof parameter=="string"){if(parameter.length>60)throw new Error("Header text must be 60 characters or less");this.type="text"}else{if(parameter._type==="location"&&!(parameter.name&¶meter.address))throw new Error("Header location must have a name and address");this.type=parameter._type}Object.defineProperty(this,this.type,{value:parameter,enumerable:!0})}}class BodyComponent{type;parameters;constructor(...parameters){this.type="body",this.parameters=parameters}_build({theres_only_body}){if(!theres_only_body){for(const param of this.parameters)if(param.text&¶m.text?.length>1024)throw new Error("Body text must be 1024 characters or less")}return this}}class BodyParameter{type;text;currency;date_time;constructor(parameter){if(typeof parameter=="string"){if(parameter.length>32768)throw new Error("Body text must be 32768 characters or less");this.type="text"}else this.type=parameter._type;Object.defineProperty(this,this.type,{value:parameter,enumerable:!0})}}class CarouselComponent extends ClientLimitedMessageComponent{type="carousel";cards;constructor(...cards){super("CarouselComponent","CarouselCard",cards,10);const pointers={counter:0};this.cards=cards.map(cmpt=>cmpt._build(pointers))}_build(){return this}}class CarouselCard{card_index=NaN;components;constructor(header,...components){const tmp=new Template("","",new HeaderComponent(new HeaderParameter(header)),...components);this.components=tmp.components}_build(ptr){return this.card_index=ptr.counter++,this}}export{BodyComponent,BodyParameter,ButtonComponent,CarouselCard,CarouselComponent,CatalogComponent,CopyComponent,Currency,DateTime,HeaderComponent,HeaderParameter,Language,MPMComponent,PayloadComponent,SkipButtonComponent,Template,URLComponent}; | ||
import{ClientMessage,ClientLimitedMessageComponent}from"../types.js";class Template extends ClientMessage{name;language;components;get _type(){return"template"}constructor(name,language,...components){if(super(),this.name=name,this.language=typeof language=="string"?new Language(language):language,components.length){const pointers={theres_only_body:components.length===1&&components[0]instanceof BodyComponent,button_counter:0};this.components=components.map(cmpt=>cmpt._build(pointers)).filter(e=>!!e)}}static OTP(name,language,code){return new Template(name,language,new BodyComponent(new BodyParameter(code)),new URLComponent(code))}}class Language{code;policy;constructor(code,policy="deterministic"){this.policy=policy,this.code=code}}class Currency{amount_1000;code;fallback_value;get _type(){return"currency"}constructor(amount_1000,code,fallback_value){if(amount_1000<=0)throw new Error("Currency must have an amount_1000 greater than 0");this.amount_1000=amount_1000,this.code=code,this.fallback_value=fallback_value}}class DateTime{fallback_value;get _type(){return"date_time"}constructor(fallback_value){this.fallback_value=fallback_value}}class ButtonComponent{type="button";sub_type;parameters;index=NaN;constructor(sub_type,parameter){this.sub_type=sub_type,this.parameters=[parameter]}_build(pointers){return this.index=pointers.button_counter++,this}}class URLComponent extends ButtonComponent{constructor(parameter){super("url",new URLComponent.Button(parameter))}static Button=class{type="text";text;constructor(text){if(!text.length)throw new Error("Button parameter can't be an empty string");this.text=text}}}class PayloadComponent extends ButtonComponent{constructor(parameter){super("quick_reply",new PayloadComponent.Button(parameter))}static Button=class{type="payload";payload;constructor(payload){if(!payload.length)throw new Error("Button parameter can't be an empty string");this.payload=payload}}}class CatalogComponent extends ButtonComponent{constructor(thumbnail){super("catalog",new CatalogComponent.Action(thumbnail))}static Action=class{type="action";action;constructor(thumbnail){this.action={thumbnail_product_retailer_id:thumbnail.product_retailer_id}}}}class MPMComponent extends ButtonComponent{constructor(thumbnail,...sections){super("mpm",new MPMComponent.Action(thumbnail,sections))}static Action=class extends ClientLimitedMessageComponent{type="action";action;constructor(thumbnail,sections){if(super("MPMComponent","sections",sections,10),sections.length>1&&!sections.every(s=>!!s.title))throw new Error("All sections must have a title if more than 1 section is provided");this.action={thumbnail_product_retailer_id:thumbnail.product_retailer_id,sections}}}}class CopyComponent extends ButtonComponent{constructor(parameter){super("copy_code",new CopyComponent.Action(parameter))}static Action=class{type="coupon_code";coupon_code;constructor(coupon_code){if(!coupon_code.length)throw new Error("Action coupon_code can't be an empty string");this.coupon_code=coupon_code}}}class SkipButtonComponent extends ButtonComponent{constructor(){super()}_build(pointers){return pointers.button_counter++,null}}class HeaderComponent{type;parameters;constructor(...parameters){this.type="header",this.parameters=parameters}_build(){return this}}class HeaderParameter{type;text;currency;date_time;image;document;video;location;constructor(parameter){if(typeof parameter=="string"){if(parameter.length>60)throw new Error("Header text must be 60 characters or less");this.type="text"}else{if(parameter._type==="location"&&!(parameter.name&¶meter.address))throw new Error("Header location must have a name and address");this.type=parameter._type}Object.defineProperty(this,this.type,{value:parameter,enumerable:!0})}}class BodyComponent{type;parameters;constructor(...parameters){this.type="body",this.parameters=parameters}_build({theres_only_body}){if(!theres_only_body){for(const param of this.parameters)if(param.text&¶m.text?.length>1024)throw new Error("Body text must be 1024 characters or less")}return this}}class BodyParameter{type;text;currency;date_time;constructor(parameter){if(typeof parameter=="string"){if(parameter.length>32768)throw new Error("Body text must be 32768 characters or less");this.type="text"}else this.type=parameter._type;Object.defineProperty(this,this.type,{value:parameter,enumerable:!0})}}class CarouselComponent extends ClientLimitedMessageComponent{type="carousel";cards;constructor(...cards){super("CarouselComponent","CarouselCard",cards,10);const pointers={counter:0};this.cards=cards.map(cmpt=>cmpt._build(pointers))}_build(){return this}}class CarouselCard{card_index=NaN;components;constructor(header,...components){const tmp=new Template("","",new HeaderComponent(new HeaderParameter(header)),...components);this.components=tmp.components}_build(ptr){return this.card_index=ptr.counter++,this}}class LTOComponent{type="limited_time_offer";parameters;constructor(expiration){if(expiration<0)throw new Error("Expiration time must be a positive Unix timestamp");this.parameters=[{type:"limited_time_offer",limited_time_offer:{expiration_time_ms:expiration}}]}_build(){return this}}export{BodyComponent,BodyParameter,ButtonComponent,CarouselCard,CarouselComponent,CatalogComponent,CopyComponent,Currency,DateTime,HeaderComponent,HeaderParameter,LTOComponent,Language,MPMComponent,PayloadComponent,SkipButtonComponent,Template,URLComponent}; | ||
//# sourceMappingURL=template.js.map |
@@ -0,1 +1,2 @@ | ||
import { Response } from "undici"; | ||
import type { ClientMessage, ClientMessageRequest, ServerMessage, ServerMessageResponse, ServerConversation, ServerPricing, ServerError, PostData } from "./types"; | ||
@@ -73,2 +74,10 @@ /** | ||
raw: PostData; | ||
/** | ||
* A method to easily reply to the user who sent the message | ||
* | ||
* @param response - The message to send as a reply | ||
* @param context - Wether to mention the current message | ||
* @returns WhatsAppAPI.sendMessage return value | ||
*/ | ||
reply: (response: ClientMessage, context: boolean) => Promise<ServerMessageResponse | Response>; | ||
}; | ||
@@ -75,0 +84,0 @@ /** |
@@ -508,3 +508,37 @@ import { ClientMessage, ClientLimitedMessageComponent, type ClientBuildableMessageComponent, type ClientTypedMessageComponent } from "../types.js"; | ||
} | ||
/** | ||
* Components API object | ||
* | ||
* @group Template | ||
*/ | ||
export declare class LTOComponent implements ClientBuildableMessageComponent { | ||
/** | ||
* The type of the component | ||
*/ | ||
readonly type = "limited_time_offer"; | ||
/** | ||
* The parameters of the component | ||
*/ | ||
readonly parameters: [ | ||
{ | ||
type: "limited_time_offer"; | ||
limited_time_offer: { | ||
expiration_time_ms: number; | ||
}; | ||
} | ||
]; | ||
/** | ||
* Builds a limited-time offer component for a Template message | ||
* | ||
* @param expiration - Offer code expiration time as a UNIX timestamp in milliseconds | ||
* @throws If expiration is negative | ||
*/ | ||
constructor(expiration: number); | ||
/** | ||
* @override | ||
* @internal | ||
*/ | ||
_build(): this; | ||
} | ||
export {}; | ||
//# sourceMappingURL=template.d.ts.map |
{ | ||
"name": "whatsapp-api-js", | ||
"version": "2.1.3-beta.0", | ||
"version": "2.2.0", | ||
"author": "Secreto31126", | ||
@@ -8,2 +8,3 @@ "description": "A TypeScript server agnostic Whatsapp's Official API framework", | ||
"type": "module", | ||
"sideEffects": false, | ||
"engines": { | ||
@@ -138,5 +139,5 @@ "node": ">=18" | ||
"@types/express": "^4.17.17", | ||
"@types/node": "18.18.1", | ||
"@typescript-eslint/eslint-plugin": "6.7.3", | ||
"@typescript-eslint/parser": "6.7.3", | ||
"@types/node": "18.18.3", | ||
"@typescript-eslint/eslint-plugin": "6.7.4", | ||
"@typescript-eslint/parser": "6.7.4", | ||
"@vercel/node": "^3.0.4", | ||
@@ -153,7 +154,7 @@ "all-contributors-cli": "^6.26.1", | ||
"prettier": "3.0.3", | ||
"sinon": "16.0.0", | ||
"sinon": "16.1.0", | ||
"typedoc": "0.25.1", | ||
"typescript": "5.2.2", | ||
"undici": "5.25.2" | ||
"undici": "5.25.4" | ||
} | ||
} |
@@ -58,3 +58,3 @@ # whatsapp-api-js v2 | ||
Whatsapp.on.message = async ({ phoneID, from, message, name }) => { | ||
Whatsapp.on.message = async ({ phoneID, from, message, name, reply }) => { | ||
console.log( | ||
@@ -69,7 +69,5 @@ `User ${name} (${from}) sent to bot ${phoneID} ${JSON.stringify( | ||
if (message.type === "text") { | ||
promise = Whatsapp.sendMessage( | ||
phoneID, | ||
from, | ||
promise = reply( | ||
new Text(`*${name}* said:\n\n${message.text.body}`), | ||
message.id | ||
true | ||
); | ||
@@ -79,5 +77,3 @@ } | ||
if (message.type === "image") { | ||
promise = Whatsapp.sendMessage( | ||
phoneID, | ||
from, | ||
promise = reply( | ||
new Image(message.image.id, true, `Nice photo, ${name}`) | ||
@@ -88,5 +84,3 @@ ); | ||
if (message.type === "document") { | ||
promise = Whatsapp.sendMessage( | ||
phoneID, | ||
from, | ||
promise = reply( | ||
new Document(message.document.id, true, undefined, "Our document") | ||
@@ -97,5 +91,3 @@ ); | ||
if (message.type === "contacts") { | ||
promise = Whatsapp.sendMessage( | ||
phoneID, | ||
from, | ||
promise = reply( | ||
new Contacts.Contacts( | ||
@@ -102,0 +94,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
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
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
No v1
QualityPackage is not semver >=1. This means it is not stable and does not support ^ ranges.
Found 1 instance in 1 package
567979
3627
22
210