UNPKG

meta-cloud-api

Version:
1 lines 511 kB
{"version":3,"file":"index.mjs","names":["LOGGER","LOGGER","LOGGER","LOGGER","LOGGER","MessageApi","SDKEnums","LOGGER","handlerCache","getCacheKey","handlerCache","getCacheKey","crypto"],"sources":["../src/config/defaults.ts","../src/types/base.ts","../src/types/enums.ts","../src/utils/objectToQueryString.ts","../src/utils/isMetaError.ts","../src/utils/validate.ts","../src/api/blockUsers/BlockUsersApi.ts","../src/api/business/BusinessApi.ts","../src/api/calling/CallingApi.ts","../src/api/commerce/CommerceApi.ts","../src/api/encryption/EncryptionApi.ts","../src/api/flow/FlowApi.ts","../src/api/flow/types/common.ts","../src/api/groups/GroupsApi.ts","../src/api/marketingMessages/MarketingMessagesApi.ts","../src/api/media/MediaApi.ts","../src/api/messageHistory/MessageHistoryApi.ts","../src/api/messages/MessageApi.ts","../src/api/payments/PaymentsApi.ts","../src/api/phone/PhoneNumberApi.ts","../src/utils/buildFieldsQueryString.ts","../src/api/profile/BusinessProfileApi.ts","../src/api/qrCode/QrCodeApi.ts","../src/api/registration/RegistrationApi.ts","../src/api/solutions/SolutionsApi.ts","../src/api/template/factories/index.ts","../src/api/template/TemplateApi.ts","../src/api/twoStepVerification/TwoStepVerificationApi.ts","../src/api/waba/WabaApi.ts","../src/api/waba/types/common.ts","../src/utils/logger.ts","../src/config/importConfig.ts","../src/utils/configTable.ts","../src/utils/flowEncryptionUtils.ts","../src/utils/http/httpsClient.ts","../src/utils/http/request.ts","../src/utils/logoConsole.ts","../src/utils/version.ts","../src/core/whatsapp/WhatsApp.ts","../src/utils/flowTypeGuards.ts","../src/core/webhook/utils/webhookUtils.ts","../src/core/webhook/WebhookProcessor.ts","../src/core/webhook/frameworks/handler.ts","../src/core/webhook/frameworks/express/express.ts","../src/core/webhook/frameworks/nextjs-app/nextjs-app.ts","../src/core/webhook/frameworks/nextjs-page/nextjs-page.ts","../src/core/webhook/utils/extractMessageText.ts","../src/core/webhook/utils/generateXHub256Sig.ts","../src/core/webhook/utils/messageHelpers.ts","../src/types/constants.ts"],"sourcesContent":["export const DEFAULT_CLOUD_API_VERSION = 'v23.0';\nexport const DEFAULT_LISTENER_PORT = 3000;\nexport const DEFAULT_MAX_RETRIES_AFTER_WAIT = 30;\nexport const DEFAULT_REQUEST_TIMEOUT = 20000;\n\nexport const DEFAULT_RETRY_MAX_ATTEMPTS = 3;\nexport const DEFAULT_RETRY_INITIAL_DELAY_MS = 1000;\nexport const DEFAULT_RETRY_BACKOFF = 'exponential';\n\nexport const GRAPH_API_HOST = 'graph.facebook.com';\nexport const GRAPH_API_PROTOCOL = 'https:';\n\nexport const WHATSAPP_MESSAGING_PRODUCT = 'whatsapp';\n","import type { WabaConfigType } from './config';\n\nexport declare class BaseClass {\n constructor(config: WabaConfigType);\n}\n\nimport type { HttpMethodsEnum } from './enums';\nimport type { RequesterClass, UrlEncodedFormBody } from './request';\n\nexport class BaseAPI implements BaseClass {\n protected config: WabaConfigType;\n protected client: RequesterClass;\n\n constructor(config: WabaConfigType, client: RequesterClass) {\n this.config = config;\n this.client = client;\n }\n\n protected sendJson<T>(method: HttpMethodsEnum, endpoint: string, timeout: number, body?: any): Promise<T> {\n return this.client.getJson<T>(method, endpoint, timeout, body);\n }\n\n protected sendFormData<T>(method: HttpMethodsEnum, endpoint: string, timeout: number, body?: any): Promise<T> {\n return this.client.sendFormData<T>(method, endpoint, timeout, body);\n }\n\n protected sendUrlEncodedForm<T>(\n method: HttpMethodsEnum,\n endpoint: string,\n timeout: number,\n body: UrlEncodedFormBody,\n ): Promise<T> {\n return this.client.sendUrlEncodedForm<T>(method, endpoint, timeout, body);\n }\n}\n","export enum CategoryEnum {\n Authentication = 'AUTHENTICATION',\n Marketing = 'MARKETING',\n Utility = 'UTILITY',\n}\n\nexport enum TemplateStatusEnum {\n Approved = 'APPROVED',\n Pending = 'PENDING',\n Rejected = 'REJECTED',\n}\n\nexport enum HttpMethodsEnum {\n Get = 'GET',\n Post = 'POST',\n Put = 'PUT',\n Delete = 'DELETE',\n}\n\nexport enum MessageTypesEnum {\n Audio = 'audio',\n Contacts = 'contacts',\n Document = 'document',\n Image = 'image',\n Interactive = 'interactive',\n Location = 'location',\n Reaction = 'reaction',\n Sticker = 'sticker',\n Template = 'template',\n Text = 'text',\n Video = 'video',\n Button = 'button',\n Order = 'order',\n System = 'system',\n Unsupported = 'unsupported',\n Unknown = 'unknown',\n /**\n * @deprecated Use WebhookProcessor.onStatus() instead of onMessage(MessageTypesEnum.Statuses)\n */\n Statuses = 'statuses',\n '*' = '*',\n}\n\nexport enum ParametersTypesEnum {\n Action = 'ACTION',\n CouponCode = 'COUPON_CODE',\n Currency = 'CURRENCY',\n DateTime = 'DATE_TIME',\n Document = 'DOCUMENT',\n ExpirationTimeMs = 'EXPIRATION_TIME_MS',\n Image = 'IMAGE',\n LimitedTimeOffer = 'LIMITED_TIME_OFFER',\n Location = 'LOCATION',\n OrderStatus = 'ORDER_STATUS',\n Payload = 'PAYLOAD',\n Product = 'PRODUCT',\n Text = 'TEXT',\n TtlMinutes = 'TTL_MINUTES',\n Video = 'VIDEO',\n WebviewInteraction = 'WEBVIEW_INTERACTION',\n WebviewPresentation = 'WEBVIEW_PRESENTATION',\n}\n\nexport enum InteractiveTypesEnum {\n Button = 'button',\n List = 'list',\n Product = 'product',\n ProductList = 'product_list',\n CatalogMessage = 'catalog_message',\n CallPermissionRequest = 'call_permission_request',\n CtaUrl = 'cta_url',\n Carousel = 'carousel',\n LocationRequest = 'location_request_message',\n AddressMessage = 'address_message',\n Flow = 'flow',\n}\n\nexport enum ButtonPositionEnum {\n First = 1,\n Second = 2,\n Third = 3,\n Fourth = 4,\n Fifth = 5,\n}\n\nexport enum SubTypeEnum {\n Catalog = 'CATALOG',\n CopyCode = 'COPY_CODE',\n Flow = 'FLOW',\n Mpm = 'MPM',\n OrderDetails = 'ORDER_DETAILS',\n PhoneNumber = 'PHONE_NUMBER',\n QuickReply = 'QUICK_REPLY',\n Reminder = 'REMINDER',\n Url = 'URL',\n VoiceCall = 'VOICE_CALL',\n}\n\nexport enum ComponentTypesEnum {\n Header = 'HEADER',\n Body = 'BODY',\n Button = 'BUTTON',\n Footer = 'FOOTER',\n}\n\nexport enum WabaConfigEnum {\n AppId = 'M4D_APP_ID',\n Port = 'WA_PORT',\n AppSecret = 'M4D_APP_SECRET',\n PhoneNumberId = 'WA_PHONE_NUMBER_ID',\n BusinessAcctId = 'WA_BUSINESS_ACCOUNT_ID',\n APIVersion = 'CLOUD_API_VERSION',\n AccessToken = 'CLOUD_API_ACCESS_TOKEN',\n WebhookEndpoint = 'WEBHOOK_ENDPOINT',\n WebhookVerificationToken = 'WEBHOOK_VERIFICATION_TOKEN',\n ListenerPort = 'LISTENER_PORT',\n MaxRetriesAfterWait = 'MAX_RETRIES_AFTER_WAIT',\n RequestTimeout = 'REQUEST_TIMEOUT',\n Debug = 'DEBUG',\n PrivatePem = 'FLOW_API_PRIVATE_PEM',\n Passphrase = 'FLOW_API_PASSPHRASE',\n}\n\nexport enum ConversationTypesEnum {\n BusinessInitiated = 'business_initiated',\n CustomerInitiated = 'customer_initiated',\n ReferralConversion = 'referral_conversion',\n}\n\nexport enum StatusEnum {\n Delivered = 'delivered',\n Read = 'read',\n Sent = 'sent',\n}\n\nexport enum VideoMediaTypesEnum {\n Mp4 = 'video/mp4',\n Threegp = 'video/3gp',\n}\n\nexport enum StickerMediaTypesEnum {\n Webp = 'image/webp',\n}\n\nexport enum ImageMediaTypesEnum {\n Jpeg = 'image/jpeg',\n Png = 'image/png',\n}\n\nexport enum DocumentMediaTypesEnum {\n Text = 'text/plain',\n Pdf = 'application/pdf',\n Ppt = 'application/vnd.ms-powerpoint',\n Word = 'application/msword',\n Excel = 'application/vnd.ms-excel',\n OpenDoc = 'application/vnd.openxmlformats-officedocument.wordprocessingml.document',\n OpenPres = 'application/vnd.openxmlformats-officedocument.presentationml.presentation',\n OpenSheet = 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',\n}\n\nexport enum AudioMediaTypesEnum {\n Aac = 'audio/aac',\n Mp4 = 'audio/mp4',\n Mpeg = 'audio/mpeg',\n Amr = 'audio/amr',\n Ogg = 'audio/ogg',\n}\n\nexport enum WebhookTypesEnum {\n Audio = 'audio',\n Button = 'button',\n Document = 'document',\n Text = 'text',\n Image = 'image',\n Interactive = 'interactive',\n Order = 'order',\n Sticker = 'sticker',\n System = 'system',\n Unknown = 'unknown',\n Video = 'video',\n}\n\nexport enum SystemChangeTypesEnum {\n CustomerChangedNumber = 'customer_changed_number',\n CustomerIdentityChanged = 'customer_identity_changed',\n}\n\nexport enum ReferralSourceTypesEnum {\n Ad = 'ad',\n Post = 'post',\n}\n\nexport enum RequestCodeMethodsEnum {\n Sms = 'SMS',\n Voice = 'VOICE',\n}\n\nexport enum LanguagesEnum {\n Afrikaans = 'af',\n Albanian = 'sq',\n Arabic = 'ar',\n Azerbaijani = 'az',\n Bengali = 'bn',\n Bulgarian = 'bg',\n Catalan = 'ca',\n Chinese_CHN = 'zh_CN',\n Chinese_HKG = 'zh_HK',\n Chinese_TAI = 'zh_TW',\n Croatian = 'hr',\n Czech = 'cs',\n Danish = 'da',\n Dutch = 'nl',\n English = 'en',\n English_UK = 'en_GB',\n English_US = 'en_US',\n Estonian = 'et',\n Filipino = 'fil',\n Finnish = 'fi',\n French = 'fr',\n Georgian = 'ka',\n German = 'de',\n Greek = 'el',\n Gujarati = 'gu',\n Hausa = 'ha',\n Hebrew = 'he',\n Hindi = 'hi',\n Hungarian = 'hu',\n Indonesian = 'id',\n Irish = 'ga',\n Italian = 'it',\n Japanese = 'ja',\n Kannada = 'kn',\n Kazakh = 'kk',\n Kinyarwanda = 'rw_RW',\n Korean = 'ko',\n Kyrgyz_Kyrgyzstan = 'ky_KG',\n Lao = 'lo',\n Latvian = 'lv',\n Lithuanian = 'lt',\n Macedonian = 'mk',\n Malay = 'ms',\n Malayalam = 'ml',\n Marathi = 'mr',\n Norwegian = 'nb',\n Persian = 'fa',\n Polish = 'pl',\n Portuguese_BR = 'pt_BR',\n Portuguese_POR = 'pt_PT',\n Punjabi = 'pa',\n Romanian = 'ro',\n Russian = 'ru',\n Serbian = 'sr',\n Slovak = 'sk',\n Slovenian = 'sl',\n Spanish = 'es',\n Spanish_ARG = 'es_AR',\n Spanish_SPA = 'es_ES',\n Spanish_MEX = 'es_MX',\n Swahili = 'sw',\n Swedish = 'sv',\n Tamil = 'ta',\n Telugu = 'te',\n Thai = 'th',\n Turkish = 'tr',\n Ukrainian = 'uk',\n Urdu = 'ur',\n Uzbek = 'uz',\n Vietnamese = 'vi',\n Zulu = 'zu',\n}\n\nexport enum CurrencyCodesEnum {\n AFN = 'AFN',\n EUR = 'EUR',\n ALL = 'ALL',\n DZD = 'DZD',\n USD = 'USD',\n AOA = 'AOA',\n XCD = 'XCD',\n ARS = 'ARS',\n AMD = 'AMD',\n AWG = 'AWG',\n AUD = 'AUD',\n AZN = 'AZN',\n BSD = 'BSD',\n BHD = 'BHD',\n BDT = 'BDT',\n BBD = 'BBD',\n BYN = 'BYN',\n BZD = 'BZD',\n XOF = 'XOF',\n BMD = 'BMD',\n INR = 'INR',\n BTN = 'BTN',\n BOB = 'BOB',\n BOV = 'BOV',\n BAM = 'BAM',\n BWP = 'BWP',\n NOK = 'NOK',\n BRL = 'BRL',\n BND = 'BND',\n BGN = 'BGN',\n BIF = 'BIF',\n CVE = 'CVE',\n KHR = 'KHR',\n XAF = 'XAF',\n CAD = 'CAD',\n KYD = 'KYD',\n CLP = 'CLP',\n CLF = 'CLF',\n CNY = 'CNY',\n COP = 'COP',\n COU = 'COU',\n KMF = 'KMF',\n CDF = 'CDF',\n NZD = 'NZD',\n CRC = 'CRC',\n HRK = 'HRK',\n CUP = 'CUP',\n CUC = 'CUC',\n ANG = 'ANG',\n CZK = 'CZK',\n DKK = 'DKK',\n DJF = 'DJF',\n DOP = 'DOP',\n EGP = 'EGP',\n SVC = 'SVC',\n ERN = 'ERN',\n SZL = 'SZL',\n ETB = 'ETB',\n FKP = 'FKP',\n FJD = 'FJD',\n XPF = 'XPF',\n GMD = 'GMD',\n GEL = 'GEL',\n GHS = 'GHS',\n GIP = 'GIP',\n GTQ = 'GTQ',\n GBP = 'GBP',\n GNF = 'GNF',\n GYD = 'GYD',\n HTG = 'HTG',\n HNL = 'HNL',\n HKD = 'HKD',\n HUF = 'HUF',\n ISK = 'ISK',\n IDR = 'IDR',\n XDR = 'XDR',\n IRR = 'IRR',\n IQD = 'IQD',\n ILS = 'ILS',\n JMD = 'JMD',\n JPY = 'JPY',\n JOD = 'JOD',\n KZT = 'KZT',\n KES = 'KES',\n KPW = 'KPW',\n KRW = 'KRW',\n KWD = 'KWD',\n KGS = 'KGS',\n LAK = 'LAK',\n LBP = 'LBP',\n LSL = 'LSL',\n ZAR = 'ZAR',\n LRD = 'LRD',\n LYD = 'LYD',\n CHF = 'CHF',\n MOP = 'MOP',\n MKD = 'MKD',\n MGA = 'MGA',\n MWK = 'MWK',\n MYR = 'MYR',\n MVR = 'MVR',\n MRU = 'MRU',\n MUR = 'MUR',\n XUA = 'XUA',\n MXN = 'MXN',\n MXV = 'MXV',\n MDL = 'MDL',\n MNT = 'MNT',\n MAD = 'MAD',\n MZN = 'MZN',\n MMK = 'MMK',\n NAD = 'NAD',\n NPR = 'NPR',\n NIO = 'NIO',\n NGN = 'NGN',\n OMR = 'OMR',\n PKR = 'PKR',\n PAB = 'PAB',\n PGK = 'PGK',\n PYG = 'PYG',\n PEN = 'PEN',\n PHP = 'PHP',\n PLN = 'PLN',\n QAR = 'QAR',\n RON = 'RON',\n RUB = 'RUB',\n RWF = 'RWF',\n SHP = 'SHP',\n WST = 'WST',\n STN = 'STN',\n SAR = 'SAR',\n RSD = 'RSD',\n SCR = 'SCR',\n SLL = 'SLL',\n SGD = 'SGD',\n XSU = 'XSU',\n SBD = 'SBD',\n SOS = 'SOS',\n SSP = 'SSP',\n LKR = 'LKR',\n SDG = 'SDG',\n SRD = 'SRD',\n SEK = 'SEK',\n CHE = 'CHE',\n CHW = 'CHW',\n SYP = 'SYP',\n TWD = 'TWD',\n TJS = 'TJS',\n TZS = 'TZS',\n THB = 'THB',\n TOP = 'TOP',\n TTD = 'TTD',\n TND = 'TND',\n TRY = 'TRY',\n TMT = 'TMT',\n UGX = 'UGX',\n UAH = 'UAH',\n AED = 'AED',\n USN = 'USN',\n UYU = 'UYU',\n UYI = 'UYI',\n UYW = 'UYW',\n UZS = 'UZS',\n VUV = 'VUV',\n VES = 'VES',\n VND = 'VND',\n YER = 'YER',\n ZMW = 'ZMW',\n ZWL = 'ZWL',\n XBA = 'XBA',\n XBB = 'XBB',\n XBC = 'XBC',\n XBD = 'XBD',\n XTS = 'XTS',\n XXX = 'XXX',\n XAU = 'XAU',\n XPD = 'XPD',\n XPT = 'XPT',\n XAG = 'XAG',\n AFA = 'AFA',\n FIM = 'FIM',\n ALK = 'ALK',\n ADP = 'ADP',\n ESP = 'ESP',\n FRF = 'FRF',\n AOK = 'AOK',\n AON = 'AON',\n AOR = 'AOR',\n ARA = 'ARA',\n ARP = 'ARP',\n ARY = 'ARY',\n RUR = 'RUR',\n ATS = 'ATS',\n AYM = 'AYM',\n AZM = 'AZM',\n BYB = 'BYB',\n BYR = 'BYR',\n BEC = 'BEC',\n BEF = 'BEF',\n BEL = 'BEL',\n BOP = 'BOP',\n BAD = 'BAD',\n BRB = 'BRB',\n BRC = 'BRC',\n BRE = 'BRE',\n BRN = 'BRN',\n BRR = 'BRR',\n BGJ = 'BGJ',\n BGK = 'BGK',\n BGL = 'BGL',\n BUK = 'BUK',\n HRD = 'HRD',\n CYP = 'CYP',\n CSJ = 'CSJ',\n CSK = 'CSK',\n ECS = 'ECS',\n ECV = 'ECV',\n GQE = 'GQE',\n EEK = 'EEK',\n XEU = 'XEU',\n GEK = 'GEK',\n DDM = 'DDM',\n DEM = 'DEM',\n GHC = 'GHC',\n GHP = 'GHP',\n GRD = 'GRD',\n GNE = 'GNE',\n GNS = 'GNS',\n GWE = 'GWE',\n GWP = 'GWP',\n ITL = 'ITL',\n ISJ = 'ISJ',\n IEP = 'IEP',\n ILP = 'ILP',\n ILR = 'ILR',\n LAJ = 'LAJ',\n LVL = 'LVL',\n LVR = 'LVR',\n LSM = 'LSM',\n ZAL = 'ZAL',\n LTL = 'LTL',\n LTT = 'LTT',\n LUC = 'LUC',\n LUF = 'LUF',\n LUL = 'LUL',\n MGF = 'MGF',\n MVQ = 'MVQ',\n MLF = 'MLF',\n MTL = 'MTL',\n MTP = 'MTP',\n MRO = 'MRO',\n MXP = 'MXP',\n MZE = 'MZE',\n MZM = 'MZM',\n NLG = 'NLG',\n NIC = 'NIC',\n PEH = 'PEH',\n PEI = 'PEI',\n PES = 'PES',\n PLZ = 'PLZ',\n PTE = 'PTE',\n ROK = 'ROK',\n ROL = 'ROL',\n STD = 'STD',\n CSD = 'CSD',\n SKK = 'SKK',\n SIT = 'SIT',\n RHD = 'RHD',\n ESA = 'ESA',\n ESB = 'ESB',\n SDD = 'SDD',\n SDP = 'SDP',\n SRG = 'SRG',\n CHC = 'CHC',\n TJR = 'TJR',\n TPE = 'TPE',\n TRL = 'TRL',\n TMM = 'TMM',\n UGS = 'UGS',\n UGW = 'UGW',\n UAK = 'UAK',\n SUR = 'SUR',\n USS = 'USS',\n UYN = 'UYN',\n UYP = 'UYP',\n VEB = 'VEB',\n VEF = 'VEF',\n VNC = 'VNC',\n YDD = 'YDD',\n YUD = 'YUD',\n YUM = 'YUM',\n YUN = 'YUN',\n ZRN = 'ZRN',\n ZRZ = 'ZRZ',\n ZMK = 'ZMK',\n ZWC = 'ZWC',\n ZWD = 'ZWD',\n ZWN = 'ZWN',\n ZWR = 'ZWR',\n XFO = 'XFO',\n XRE = 'XRE',\n XFU = 'XFU',\n}\n\nexport enum DataLocalizationRegionEnum {\n // APAC\n AU = 'AU', // Australia\n ID = 'ID', // Indonesia\n IN = 'IN', // India\n JP = 'JP', // Japan\n SG = 'SG', // Singapore\n KR = 'KR', // South Korea\n\n // Europe\n DE = 'DE', // EU (Germany)\n CH = 'CH', // Switzerland\n GB = 'GB', // United Kingdom\n\n // LATAM\n BR = 'BR', // Brazil\n\n // MEA\n BH = 'BH', // Bahrain\n ZA = 'ZA', // South Africa\n AE = 'AE', // United Arab Emirates\n\n // NORAM\n CA = 'CA', // Canada\n}\n\n/**\n * Business category values for WhatsApp Business Profile.\n * These values map to specific strings displayed in the WhatsApp client.\n */\nexport enum BusinessVerticalEnum {\n /**\n * Alcoholic Beverages\n */\n ALCOHOL = 'ALCOHOL',\n /**\n * Clothing and Apparel\n */\n APPAREL = 'APPAREL',\n /**\n * Automotive\n */\n AUTO = 'AUTO',\n /**\n * Beauty, Spa and Salon\n */\n BEAUTY = 'BEAUTY',\n /**\n * Education\n */\n EDU = 'EDU',\n /**\n * Entertainment\n */\n ENTERTAIN = 'ENTERTAIN',\n /**\n * Event Planning and Service\n */\n EVENT_PLAN = 'EVENT_PLAN',\n /**\n * Finance and Banking\n */\n FINANCE = 'FINANCE',\n /**\n * Public Service\n */\n GOVT = 'GOVT',\n /**\n * Food and Grocery\n */\n GROCERY = 'GROCERY',\n /**\n * Medical and Health\n */\n HEALTH = 'HEALTH',\n /**\n * Hotel and Lodging\n */\n HOTEL = 'HOTEL',\n /**\n * Non-profit\n */\n NONPROFIT = 'NONPROFIT',\n /**\n * Online Gambling & Gaming\n */\n ONLINE_GAMBLING = 'ONLINE_GAMBLING',\n /**\n * Over-the-Counter Drugs\n */\n OTC_DRUGS = 'OTC_DRUGS',\n /**\n * Other\n */\n OTHER = 'OTHER',\n /**\n * Non-Online Gambling & Gaming (E.g. Brick and mortar)\n */\n PHYSICAL_GAMBLING = 'PHYSICAL_GAMBLING',\n /**\n * Professional Services\n */\n PROF_SERVICES = 'PROF_SERVICES',\n /**\n * Restaurant\n */\n RESTAURANT = 'RESTAURANT',\n /**\n * Shopping and Retail\n */\n RETAIL = 'RETAIL',\n /**\n * Travel and Transportation\n */\n TRAVEL = 'TRAVEL',\n}\n","export const objectToQueryString = (params: Record<string, any>): string => {\n if (!params || Object.keys(params).length === 0) {\n return '';\n }\n\n const queryParts: string[] = [];\n\n for (const [key, value] of Object.entries(params)) {\n if (value !== undefined) {\n const encodedKey = encodeURIComponent(key);\n const encodedValue = encodeURIComponent(String(value));\n queryParts.push(`${encodedKey}=${encodedValue}`);\n }\n }\n\n return queryParts.length > 0 ? `?${queryParts.join('&')}` : '';\n};\n","export type MetaErrorData = {\n message: string;\n type: string;\n code: number;\n error_data?: {\n messaging_product?: 'whatsapp';\n details?: string;\n };\n error_subcode?: number;\n fbtrace_id: string;\n};\n\nexport interface MetaError extends Error {\n error: MetaErrorData;\n}\n\nexport const WHATSAPP_ERROR_CODES = [\n 0, 1, 2, 3, 4, 10, 33, 100, 190, 200, 299, 368, 613, 80007, 130429, 130472, 130497, 131000, 131005, 131008, 131009,\n 131016, 131020, 131021, 131026, 131030, 131031, 131037, 131041, 131042, 131044, 131045, 131047, 131048, 131049,\n 131050, 131051, 131052, 131053, 131055, 131056, 131057, 131059, 131201, 131202, 131203, 131204, 131207, 131208,\n 131209, 131210, 131211, 131212, 131213, 131214, 131215, 132000, 132001, 132005, 132007, 132008, 132012, 132015,\n 132016, 132068, 132069, 133000, 133004, 133005, 133006, 133008, 133009, 133010, 133015, 133016, 134011, 134100,\n 134101, 134102, 135000, 137000, 138000, 138001, 138002, 138003, 138004, 138005, 138006, 138007, 138009, 138012,\n 138013, 138018, 139000, 139001, 139002, 139003, 139004, 139100, 139101, 139102, 139103, 200005, 200006, 200007,\n 1752041, 2388001, 2388012, 2388019, 2388040, 2388047, 2388072, 2388073, 2388091, 2388093, 2388103, 2388293, 2388299,\n 2494100, 2593079, 2593085, 2593107, 2593108,\n] as const;\n\nconst WHATSAPP_ERROR_CODE_SET = new Set<number>(WHATSAPP_ERROR_CODES);\n\nexport type ApiPermissionErrorCode = number;\nexport type WhatsAppErrorCode = (typeof WHATSAPP_ERROR_CODES)[number] | ApiPermissionErrorCode;\n\nexport const AUTHORIZATION_ERROR_CODES = [0, 3, 10, 190] as const;\nexport const THROTTLING_ERROR_CODES = [4, 80007, 130429, 131048, 131056] as const;\nexport const INTEGRITY_ERROR_CODES = [368, 130497, 131031] as const;\nexport const SEND_MESSAGE_ERROR_CODES = [\n 130472, 131000, 131005, 131008, 131009, 131016, 131021, 131026, 131030, 131042, 131044, 131045, 131047, 131050,\n 131051, 131052, 131053, 131056, 131057, 131048, 132000, 132001, 132005, 132007, 132008, 132012, 132015, 132016,\n 132068, 132069, 135000, 137000,\n] as const;\nexport const FLOW_ERROR_CODES = [139000, 139001, 139002, 139003, 139004] as const;\nexport const BLOCK_USER_ERROR_CODES = [139100, 139101, 139102, 139103] as const;\nexport const CALLING_ERROR_CODES = [\n 138000, 138001, 138002, 138003, 138004, 138005, 138006, 138007, 138009, 138012, 138013, 138018, 613,\n] as const;\nexport const GROUP_ERROR_CODES = [\n 131020, 131041, 131059, 131201, 131202, 131203, 131204, 131207, 131208, 131209, 131210, 131211, 131212, 131213,\n 131214, 131215,\n] as const;\n\nconst AUTHORIZATION_ERROR_CODE_SET = new Set<number>(AUTHORIZATION_ERROR_CODES);\nconst THROTTLING_ERROR_CODE_SET = new Set<number>(THROTTLING_ERROR_CODES);\nconst INTEGRITY_ERROR_CODE_SET = new Set<number>(INTEGRITY_ERROR_CODES);\nconst SEND_MESSAGE_ERROR_CODE_SET = new Set<number>(SEND_MESSAGE_ERROR_CODES);\nconst FLOW_ERROR_CODE_SET = new Set<number>(FLOW_ERROR_CODES);\nconst BLOCK_USER_ERROR_CODE_SET = new Set<number>(BLOCK_USER_ERROR_CODES);\nconst CALLING_ERROR_CODE_SET = new Set<number>(CALLING_ERROR_CODES);\nconst GROUP_ERROR_CODE_SET = new Set<number>(GROUP_ERROR_CODES);\n\nexport function isWhatsAppErrorCode(code: number): code is WhatsAppErrorCode {\n if (isApiPermissionErrorCode(code)) return true;\n return WHATSAPP_ERROR_CODE_SET.has(code);\n}\n\nexport function isApiPermissionErrorCode(code: number): code is ApiPermissionErrorCode {\n return code >= 200 && code < 300;\n}\n\nexport function isAuthorizationErrorCode(\n code: number,\n): code is ApiPermissionErrorCode | (typeof AUTHORIZATION_ERROR_CODES)[number] {\n return isApiPermissionErrorCode(code) || AUTHORIZATION_ERROR_CODE_SET.has(code);\n}\n\nexport function isThrottlingErrorCode(code: number): code is (typeof THROTTLING_ERROR_CODES)[number] {\n return THROTTLING_ERROR_CODE_SET.has(code);\n}\n\nexport function isIntegrityErrorCode(code: number): code is (typeof INTEGRITY_ERROR_CODES)[number] {\n return INTEGRITY_ERROR_CODE_SET.has(code);\n}\n\nexport function isSendMessageErrorCode(code: number): code is (typeof SEND_MESSAGE_ERROR_CODES)[number] {\n return SEND_MESSAGE_ERROR_CODE_SET.has(code);\n}\n\nexport function isFlowErrorCode(code: number): code is (typeof FLOW_ERROR_CODES)[number] {\n return FLOW_ERROR_CODE_SET.has(code);\n}\n\nexport function isBlockUserErrorCode(code: number): code is (typeof BLOCK_USER_ERROR_CODES)[number] {\n return BLOCK_USER_ERROR_CODE_SET.has(code);\n}\n\nexport function isCallingErrorCode(code: number): code is (typeof CALLING_ERROR_CODES)[number] {\n return CALLING_ERROR_CODE_SET.has(code);\n}\n\nexport function isGroupErrorCode(code: number): code is (typeof GROUP_ERROR_CODES)[number] {\n return GROUP_ERROR_CODE_SET.has(code);\n}\n\nexport class WhatsAppError extends Error {\n constructor(message: string) {\n super(message);\n this.name = 'WhatsAppError';\n }\n}\n\nexport class WhatsAppApiError extends WhatsAppError {\n readonly error: MetaErrorData;\n readonly statusCode?: number;\n\n constructor(message: string, error: MetaErrorData, statusCode?: number) {\n super(message);\n this.name = 'WhatsAppApiError';\n this.error = error;\n this.statusCode = statusCode;\n }\n}\n\nexport class WhatsAppAuthorizationError extends WhatsAppApiError {\n constructor(message: string, error: MetaErrorData, statusCode?: number) {\n super(message, error, statusCode);\n this.name = 'WhatsAppAuthorizationError';\n }\n}\n\nexport class WhatsAppThrottlingError extends WhatsAppApiError {\n constructor(message: string, error: MetaErrorData, statusCode?: number) {\n super(message, error, statusCode);\n this.name = 'WhatsAppThrottlingError';\n }\n}\n\nexport class WhatsAppIntegrityError extends WhatsAppApiError {\n constructor(message: string, error: MetaErrorData, statusCode?: number) {\n super(message, error, statusCode);\n this.name = 'WhatsAppIntegrityError';\n }\n}\n\nexport class WhatsAppSendMessageError extends WhatsAppApiError {\n constructor(message: string, error: MetaErrorData, statusCode?: number) {\n super(message, error, statusCode);\n this.name = 'WhatsAppSendMessageError';\n }\n}\n\nexport class WhatsAppFlowError extends WhatsAppApiError {\n constructor(message: string, error: MetaErrorData, statusCode?: number) {\n super(message, error, statusCode);\n this.name = 'WhatsAppFlowError';\n }\n}\n\nexport class WhatsAppBlockUserError extends WhatsAppApiError {\n constructor(message: string, error: MetaErrorData, statusCode?: number) {\n super(message, error, statusCode);\n this.name = 'WhatsAppBlockUserError';\n }\n}\n\nexport class WhatsAppCallingError extends WhatsAppApiError {\n constructor(message: string, error: MetaErrorData, statusCode?: number) {\n super(message, error, statusCode);\n this.name = 'WhatsAppCallingError';\n }\n}\n\nexport class WhatsAppGroupError extends WhatsAppApiError {\n constructor(message: string, error: MetaErrorData, statusCode?: number) {\n super(message, error, statusCode);\n this.name = 'WhatsAppGroupError';\n }\n}\n\nexport function createWhatsAppApiError(error: MetaErrorData, statusCode?: number): WhatsAppApiError {\n const code = error.code;\n\n if (isAuthorizationErrorCode(code)) {\n return new WhatsAppAuthorizationError(error.message, error, statusCode);\n }\n if (isThrottlingErrorCode(code)) {\n return new WhatsAppThrottlingError(error.message, error, statusCode);\n }\n if (isIntegrityErrorCode(code)) {\n return new WhatsAppIntegrityError(error.message, error, statusCode);\n }\n if (isSendMessageErrorCode(code)) {\n return new WhatsAppSendMessageError(error.message, error, statusCode);\n }\n if (isFlowErrorCode(code)) {\n return new WhatsAppFlowError(error.message, error, statusCode);\n }\n if (isBlockUserErrorCode(code)) {\n return new WhatsAppBlockUserError(error.message, error, statusCode);\n }\n if (isCallingErrorCode(code)) {\n return new WhatsAppCallingError(error.message, error, statusCode);\n }\n if (isGroupErrorCode(code)) {\n return new WhatsAppGroupError(error.message, error, statusCode);\n }\n\n return new WhatsAppApiError(error.message, error, statusCode);\n}\n\nexport class WhatsAppNetworkError extends WhatsAppError {\n readonly cause?: unknown;\n\n constructor(message: string, cause?: unknown) {\n super(message);\n this.name = 'WhatsAppNetworkError';\n this.cause = cause;\n }\n}\n\nexport class WhatsAppUnknownError extends WhatsAppError {\n readonly cause?: unknown;\n\n constructor(message: string, cause?: unknown) {\n super(message);\n this.name = 'WhatsAppUnknownError';\n this.cause = cause;\n }\n}\n\n/**\n * Thrown when an API method receives invalid input (e.g., malformed phone number,\n * empty required array). This error is thrown client-side before any API call is made.\n */\nexport class WhatsAppValidationError extends Error {\n constructor(message: string) {\n super(message);\n this.name = 'WhatsAppValidationError';\n }\n}\n\n/**\n * Determines if the error is a Meta API error response\n * @param error Any error object to check\n * @returns Type guard indicating if error is a Meta API error\n */\nexport function isMetaError(error: any): error is MetaError {\n if (error == null || typeof error !== 'object') return false;\n if (!('error' in error) || typeof error.error !== 'object' || error.error == null) return false;\n\n const metaError = error.error as Record<string, unknown>;\n\n if (typeof metaError.message !== 'string') return false;\n if (typeof metaError.type !== 'string') return false;\n if (typeof metaError.code !== 'number') return false;\n if (typeof metaError.fbtrace_id !== 'string') return false;\n\n if ('error_data' in metaError && metaError.error_data != null) {\n if (typeof metaError.error_data !== 'object') return false;\n const errorData = metaError.error_data as Record<string, unknown>;\n if ('messaging_product' in errorData && errorData.messaging_product !== 'whatsapp') return false;\n if ('details' in errorData && typeof errorData.details !== 'string') return false;\n }\n\n if ('error_subcode' in metaError && typeof metaError.error_subcode !== 'number') return false;\n\n return true;\n}\n\nexport function isWhatsAppApiErrorResponse(error: any): error is MetaError & { error: { code: WhatsAppErrorCode } } {\n return isMetaError(error) && isWhatsAppErrorCode(error.error.code);\n}\n\nexport function isWhatsAppAuthorizationError(error: unknown): error is WhatsAppAuthorizationError {\n return error instanceof WhatsAppAuthorizationError;\n}\n\nexport function isWhatsAppThrottlingError(error: unknown): error is WhatsAppThrottlingError {\n return error instanceof WhatsAppThrottlingError;\n}\n\nexport function isWhatsAppIntegrityError(error: unknown): error is WhatsAppIntegrityError {\n return error instanceof WhatsAppIntegrityError;\n}\n\nexport function isWhatsAppSendMessageError(error: unknown): error is WhatsAppSendMessageError {\n return error instanceof WhatsAppSendMessageError;\n}\n\nexport function isWhatsAppFlowError(error: unknown): error is WhatsAppFlowError {\n return error instanceof WhatsAppFlowError;\n}\n\nexport function isWhatsAppBlockUserError(error: unknown): error is WhatsAppBlockUserError {\n return error instanceof WhatsAppBlockUserError;\n}\n\nexport function isWhatsAppCallingError(error: unknown): error is WhatsAppCallingError {\n return error instanceof WhatsAppCallingError;\n}\n\nexport function isWhatsAppGroupError(error: unknown): error is WhatsAppGroupError {\n return error instanceof WhatsAppGroupError;\n}\n\nexport function normalizeMetaError(errorData: unknown, statusCode?: number): MetaError {\n if (isMetaError(errorData)) return errorData;\n\n let message = 'Unknown error occurred';\n if (errorData && typeof errorData === 'object' && 'message' in errorData) {\n const candidate = (errorData as { message?: unknown }).message;\n if (typeof candidate === 'string') message = candidate;\n }\n\n return {\n name: 'MetaError',\n message,\n error: {\n message,\n type: 'UnknownError',\n code: typeof statusCode === 'number' ? statusCode : 500,\n fbtrace_id: '',\n },\n };\n}\n","import { WhatsAppValidationError } from './isMetaError';\n\n/**\n * Asserts that a phone number is in valid E.164 format.\n * Accepts numbers with or without leading '+'.\n * Must be 10-15 digits (not counting the '+').\n *\n * @throws WhatsAppValidationError if the phone number is invalid\n *\n * @example\n * assertPhoneNumber('+14155552671'); // ok\n * assertPhoneNumber('14155552671'); // ok\n * assertPhoneNumber('123'); // throws\n */\nexport function assertPhoneNumber(phone: string): void {\n if (!/^\\+?\\d{10,15}$/.test(phone)) {\n throw new WhatsAppValidationError(\n `Invalid phone number: \"${phone}\". Expected E.164 format (e.g. +14155552671 or 14155552671).`,\n );\n }\n}\n\n/**\n * Asserts that an array is non-empty.\n * Also guards against null/undefined to preserve backward compatibility\n * with callers that may pass untyped values.\n *\n * @throws WhatsAppValidationError if the array is null, undefined, or empty\n *\n * @example\n * assertNonEmpty(['user1'], 'users'); // ok\n * assertNonEmpty([], 'users'); // throws\n */\nexport function assertNonEmpty<T>(arr: T[] | null | undefined, name: string): void {\n if (!arr || arr.length === 0) {\n throw new WhatsAppValidationError(`\"${name}\" must contain at least one item.`);\n }\n}\n","// Docs: https://developers.facebook.com/documentation/business-messaging/whatsapp/block-users/\n\n// Endpoints:\n// - POST /{PHONE_NUMBER_ID}/block_users\n// - DELETE /{PHONE_NUMBER_ID}/block_users\n// - GET /{PHONE_NUMBER_ID}/block_users?limit&after&before\n\nimport { WHATSAPP_MESSAGING_PRODUCT } from '../../config/defaults';\nimport { BaseAPI } from '../../types/base';\nimport { HttpMethodsEnum, WabaConfigEnum } from '../../types/enums';\nimport { objectToQueryString } from '../../utils/objectToQueryString';\nimport { assertNonEmpty } from '../../utils/validate';\nimport type * as blockUsers from './types/blockUsers';\n\n/**\n * API for blocking and unblocking WhatsApp users.\n *\n * Provides methods to block, unblock, and list blocked users for your\n * WhatsApp Business phone number.\n *\n * Limitations:\n * - Can only block users that have messaged your business in the last 24 hours\n * - 64k blocklist limit\n *\n * Endpoints covered:\n * - `POST /{PHONE_NUMBER_ID}/block_users` - Block one or more users\n * - `DELETE /{PHONE_NUMBER_ID}/block_users` - Unblock one or more users\n * - `GET /{PHONE_NUMBER_ID}/block_users` - List blocked users with pagination\n *\n * @see https://developers.facebook.com/documentation/business-messaging/whatsapp/block-users/\n */\nexport default class BlockUsersApi extends BaseAPI implements blockUsers.BlockUsersClass {\n private readonly endpoint = 'block_users';\n\n /**\n * Build the request body for block/unblock operations.\n *\n * @param users - Array of phone numbers or WhatsApp IDs.\n * @returns The formatted request body.\n */\n private buildBlockUsersBody(users: string[]): blockUsers.BlockUsersRequest {\n return {\n messaging_product: WHATSAPP_MESSAGING_PRODUCT,\n block_users: users.map((user) => ({ user })),\n };\n }\n\n /**\n * Block one or more WhatsApp users\n * @param users - Array of phone numbers or WhatsApp IDs to block\n * @returns Response with successfully blocked and failed users\n * @throws Error if users have not messaged in last 24 hours\n * @see https://developers.facebook.com/documentation/business-messaging/whatsapp/block-users/\n *\n * @example\n * ```typescript\n * // Block single user\n * const result = await client.blockUsers.block(['1234567890']);\n *\n * // Block multiple users\n * const result = await client.blockUsers.block(['1234567890', '0987654321']);\n *\n * // Check results\n * console.log('Blocked:', result.block_users.added_users);\n * console.log('Failed:', result.block_users.failed_users);\n * ```\n */\n async block(users: string[]): Promise<blockUsers.BlockUsersResponse> {\n assertNonEmpty(users, 'users');\n\n const body = this.buildBlockUsersBody(users);\n\n return await this.sendJson<blockUsers.BlockUsersResponse>(\n HttpMethodsEnum.Post,\n `${this.config[WabaConfigEnum.PhoneNumberId]}/${this.endpoint}`,\n this.config[WabaConfigEnum.RequestTimeout],\n JSON.stringify(body),\n );\n }\n\n /**\n * Unblock one or more WhatsApp users\n * @param users - Array of phone numbers or WhatsApp IDs to unblock\n * @returns Response with successfully unblocked and failed users\n * @see https://developers.facebook.com/documentation/business-messaging/whatsapp/block-users/\n *\n * @example\n * ```typescript\n * // Unblock single user\n * const result = await client.blockUsers.unblock(['1234567890']);\n *\n * // Unblock multiple users\n * const result = await client.blockUsers.unblock(['1234567890', '0987654321']);\n *\n * // Check results\n * console.log('Unblocked:', result.block_users.added_users);\n * console.log('Failed:', result.block_users.failed_users);\n * ```\n */\n async unblock(users: string[]): Promise<blockUsers.BlockUsersResponse> {\n assertNonEmpty(users, 'users');\n\n const body = this.buildBlockUsersBody(users);\n\n return await this.sendJson<blockUsers.BlockUsersResponse>(\n HttpMethodsEnum.Delete,\n `${this.config[WabaConfigEnum.PhoneNumberId]}/${this.endpoint}`,\n this.config[WabaConfigEnum.RequestTimeout],\n JSON.stringify(body),\n );\n }\n\n /**\n * Get list of blocked WhatsApp users with pagination\n * @param params - Optional pagination parameters\n * @returns List of blocked users with pagination info\n * @see https://developers.facebook.com/documentation/business-messaging/whatsapp/block-users/\n *\n * @example\n * ```typescript\n * // Get first 10 blocked users\n * const result = await client.blockUsers.listBlockedUsers({ limit: 10 });\n *\n * // Pagination with cursor\n * const nextPage = await client.blockUsers.listBlockedUsers({\n * limit: 10,\n * after: result.paging?.cursors?.after\n * });\n *\n * // Get all blocked users\n * const allBlocked = await client.blockUsers.listBlockedUsers();\n * ```\n */\n async listBlockedUsers(params?: blockUsers.ListBlockedUsersParams): Promise<blockUsers.ListBlockedUsersResponse> {\n let endpoint = `${this.config[WabaConfigEnum.PhoneNumberId]}/${this.endpoint}`;\n\n // Add query parameters if provided\n if (params) {\n const queryString = objectToQueryString(params);\n if (queryString) {\n endpoint += queryString;\n }\n }\n\n return await this.sendJson<blockUsers.ListBlockedUsersResponse>(\n HttpMethodsEnum.Get,\n endpoint,\n this.config[WabaConfigEnum.RequestTimeout],\n );\n }\n}\n","// Docs: https://developers.facebook.com/documentation/business-messaging/whatsapp/overview/\n\n// Endpoints:\n// - GET /{APPLICATION_ID}/connected_client_businesses\n// - POST /{BUSINESS_ID}/add_phone_numbers\n// - GET /{BUSINESS_ID}\n// - GET /{BUSINESS_ID}/preverified_numbers\n// - GET /{BUSINESS_ID}/client_whatsapp_business_accounts\n// - POST /{BUSINESS_ID}/onboard_partners_to_mm_lite\n// - GET /{BUSINESS_ID}/owned_whatsapp_business_accounts\n// - POST /{BUSINESS_ID}/share_preverified_numbers\n// - GET /{BUSINESS_ID}/extendedcredits\n// - GET /{USER_ID}/assigned_whatsapp_business_accounts\n// - GET /{WHATSAPP_ACCOUNT_NUMBER_ID}\n// - GET /{PRE_VERIFIED_PHONE_NUMBER_ID}\n// - DELETE /{PRE_VERIFIED_PHONE_NUMBER_ID}\n// - GET /{PRE_VERIFIED_PHONE_NUMBER_ID}/partners\n// - POST /{PRE_VERIFIED_PHONE_NUMBER_ID}/request_code\n// - POST /{PRE_VERIFIED_PHONE_NUMBER_ID}/verify_code\n\nimport { BaseAPI } from '../../types/base';\nimport { HttpMethodsEnum, WabaConfigEnum } from '../../types/enums';\nimport type { ResponseSuccess } from '../../types/request';\nimport { objectToQueryString } from '../../utils/objectToQueryString';\n\nimport type * as business from './types';\n\nexport default class BusinessApi extends BaseAPI implements business.BusinessClass {\n private toQuery(params?: business.BusinessListParams): string {\n if (!params) return '';\n\n const fields = Array.isArray(params.fields) ? params.fields.join(',') : params.fields;\n const filtering = Array.isArray(params.filtering) ? JSON.stringify(params.filtering) : params.filtering;\n\n return objectToQueryString({\n fields,\n filtering,\n sort: params.sort,\n limit: params.limit,\n after: params.after,\n before: params.before,\n });\n }\n\n private fieldsQuery(fields?: business.BusinessFieldsParam): string {\n const fieldsValue = Array.isArray(fields) ? fields.join(',') : fields;\n return fieldsValue ? objectToQueryString({ fields: fieldsValue }) : '';\n }\n\n async getConnectedClientBusinesses(\n applicationId: string = this.config[WabaConfigEnum.AppId],\n params?: business.BusinessListParams,\n ): Promise<business.BusinessGraphListResponse> {\n return this.sendJson(\n HttpMethodsEnum.Get,\n `${applicationId}/connected_client_businesses${this.toQuery(params)}`,\n this.config[WabaConfigEnum.RequestTimeout],\n null,\n );\n }\n\n async addPhoneNumbers(businessId: string, request: business.AddPhoneNumbersRequest): Promise<ResponseSuccess> {\n return this.sendJson(\n HttpMethodsEnum.Post,\n `${businessId}/add_phone_numbers`,\n this.config[WabaConfigEnum.RequestTimeout],\n JSON.stringify(request),\n );\n }\n\n async getBusinessPortfolio(\n businessId: string,\n fields?: business.BusinessFieldsParam,\n ): Promise<business.BusinessGraphObject> {\n return this.sendJson(\n HttpMethodsEnum.Get,\n `${businessId}${this.fieldsQuery(fields)}`,\n this.config[WabaConfigEnum.RequestTimeout],\n null,\n );\n }\n\n async getPreVerifiedPhoneNumbers(\n businessId: string,\n params?: business.BusinessListParams,\n ): Promise<business.BusinessGraphListResponse> {\n return this.sendJson(\n HttpMethodsEnum.Get,\n `${businessId}/preverified_numbers${this.toQuery(params)}`,\n this.config[WabaConfigEnum.RequestTimeout],\n null,\n );\n }\n\n async getClientWhatsAppBusinessAccounts(\n businessId: string,\n params?: business.BusinessListParams,\n ): Promise<business.BusinessGraphListResponse> {\n return this.sendJson(\n HttpMethodsEnum.Get,\n `${businessId}/client_whatsapp_business_accounts${this.toQuery(params)}`,\n this.config[WabaConfigEnum.RequestTimeout],\n null,\n );\n }\n\n async onboardPartnersToMMLite(\n businessId: string,\n request: business.OnboardPartnersToMMLiteRequest,\n ): Promise<business.BusinessGraphObject> {\n return this.sendJson(\n HttpMethodsEnum.Post,\n `${businessId}/onboard_partners_to_mm_lite`,\n this.config[WabaConfigEnum.RequestTimeout],\n JSON.stringify(request),\n );\n }\n\n async getOwnedWhatsAppBusinessAccounts(\n businessId: string,\n params?: business.BusinessListParams,\n ): Promise<business.BusinessGraphListResponse> {\n return this.sendJson(\n HttpMethodsEnum.Get,\n `${businessId}/owned_whatsapp_business_accounts${this.toQuery(params)}`,\n this.config[WabaConfigEnum.RequestTimeout],\n null,\n );\n }\n\n async sharePreVerifiedPhoneNumber(\n businessId: string,\n request: business.SharePreVerifiedPhoneNumberRequest,\n ): Promise<ResponseSuccess> {\n return this.sendJson(\n HttpMethodsEnum.Post,\n `${businessId}/share_preverified_numbers`,\n this.config[WabaConfigEnum.RequestTimeout],\n JSON.stringify(request),\n );\n }\n\n async getCreditLines(businessId: string): Promise<business.BusinessGraphListResponse> {\n return this.sendJson(\n HttpMethodsEnum.Get,\n `${businessId}/extendedcredits`,\n this.config[WabaConfigEnum.RequestTimeout],\n null,\n );\n }\n\n async getAssignedWhatsAppBusinessAccounts(\n userId: string,\n params?: business.BusinessListParams,\n ): Promise<business.BusinessGraphListResponse> {\n return this.sendJson(\n HttpMethodsEnum.Get,\n `${userId}/assigned_whatsapp_business_accounts${this.toQuery(params)}`,\n this.config[WabaConfigEnum.RequestTimeout],\n null,\n );\n }\n\n async getWhatsAppAccountNumberDetails(\n accountNumberId: string,\n fields?: business.BusinessFieldsParam,\n ): Promise<business.BusinessGraphObject> {\n return this.sendJson(\n HttpMethodsEnum.Get,\n `${accountNumberId}${this.fieldsQuery(fields)}`,\n this.config[WabaConfigEnum.RequestTimeout],\n null,\n );\n }\n\n async getPreVerifiedPhoneNumberDetails(\n preVerifiedPhoneNumberId: string,\n fields?: business.BusinessFieldsParam,\n ): Promise<business.BusinessGraphObject> {\n return this.sendJson(\n HttpMethodsEnum.Get,\n `${preVerifiedPhoneNumberId}${this.fieldsQuery(fields)}`,\n this.config[WabaConfigEnum.RequestTimeout],\n null,\n );\n }\n\n async deletePreVerifiedPhoneNumber(preVerifiedPhoneNumberId: string): Promise<ResponseSuccess> {\n return this.sendJson(\n HttpMethodsEnum.Delete,\n preVerifiedPhoneNumberId,\n this.config[WabaConfigEnum.RequestTimeout],\n null,\n );\n }\n\n async getPreVerifiedPhoneNumberPartners(\n preVerifiedPhoneNumberId: string,\n params?: business.BusinessListParams,\n ): Promise<business.BusinessGraphListResponse> {\n return this.sendJson(\n HttpMethodsEnum.Get,\n `${preVerifiedPhoneNumberId}/partners${this.toQuery(params)}`,\n this.config[WabaConfigEnum.RequestTimeout],\n null,\n );\n }\n\n async requestPreVerifiedPhoneNumberCode(\n preVerifiedPhoneNumberId: string,\n request: business.RequestPreVerifiedPhoneNumberCodeRequest,\n ): Promise<ResponseSuccess> {\n return this.sendJson(\n HttpMethodsEnum.Post,\n `${preVerifiedPhoneNumberId}/request_code`,\n this.config[WabaConfigEnum.RequestTimeout],\n JSON.stringify(request),\n );\n }\n\n async verifyPreVerifiedPhoneNumberCode(\n preVerifiedPhoneNumberId: string,\n request: business.VerifyPreVerifiedPhoneNumberCodeRequest,\n ): Promise<ResponseSuccess> {\n return this.sendJson(\n HttpMethodsEnum.Post,\n `${preVerifiedPhoneNumberId}/verify_code`,\n this.config[WabaConfigEnum.RequestTimeout],\n JSON.stringify(request),\n );\n }\n}\n","// Docs: https://developers.facebook.com/documentation/business-messaging/whatsapp/calling/reference/\n\n// Endpoints:\n// - POST /{PHONE_NUMBER_ID}/settings\n// - GET /{PHONE_NUMBER_ID}/settings?fields&include_sip_credentials\n// - GET /{PHONE_NUMBER_ID}/call_permissions?user_wa_id\n// - POST /{PHONE_NUMBER_ID}/calls\n\nimport { WHATSAPP_MESSAGING_PRODUCT } from '../../config/defaults';\nimport { BaseAPI } from '../../types/base';\nimport { HttpMethodsEnum, WabaConfigEnum } from '../../types/enums';\nimport type { ResponseSuccess } from '../../types/request';\nimport { objectToQueryString } from '../../utils/objectToQueryString';\n\nimport type * as calling from './types';\n\n/**\n * API for WhatsApp Calling features.\n *\n * Provides methods to manage calling settings, permissions, and call lifecycle\n * (initiate, pre-accept, accept, reject, terminate).\n *\n * Endpoints covered:\n * - `POST /{PHONE_NUMBER_ID}/settings` - Update calling settings\n * - `GET /{PHONE_NUMBER_ID}/settings` - Get calling settings\n * - `GET /{PHONE_NUMBER_ID}/call_permissions` - Get call permissions for a user\n * - `POST /{PHONE_NUMBER_ID}/calls` - Initiate, pre-accept, accept, reject, or terminate a call\n *\n * @see https://developers.facebook.com/documentation/business-messaging/whatsapp/calling/reference/\n */\nexport default class CallingApi extends BaseAPI implements calling.CallingClass {\n private readonly endpoint = 'calls';\n\n /**\n * Update calling settings for the phone number, such as enabling/disabling calling\n * or configuring SIP credentials.\n *\n * @param params - The calling settings to update.\n * @returns A success response confirming the settings were updated.\n * @see https://developers.facebook.com/documentation/business-messaging/whatsapp/calling/reference/\n */\n async updateCallingSettings(params: calling.UpdateCallingSettingsRequest): Promise<ResponseSuccess> {\n return this.sendJson(\n HttpMethodsEnum.Post,\n `${this.config[WabaConfigEnum.PhoneNumberId]}/settings`,\n this.config[WabaConfigEnum.RequestTimeout],\n JSON.stringify(params),\n );\n }\n\n /**\n * Retrieve the current calling settings for the phone number.\n *\n * @param params - Optional query parameters to filter the response.\n * @param params.fields - Specific fields to include in the response.\n * @param params.include_sip_credentials - Whether to include SIP credentials in the response.\n * @returns The current calling settings configuration.\n * @see https://developers.facebook.com/documentation/business-messaging/whatsapp/calling/reference/\n */\n async getCallingSettings(params?: {\n fields?: string[] | string;\n include_sip_credentials?: boolean;\n }): Promise<calling.CallingSettingsResponse> {\n const fieldsValue = Array.isArray(params?.fields) ? params?.fie