meta-cloud-api 0.0.2 → 0.0.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (43) hide show
  1. package/README.md +216 -0
  2. package/package.json +34 -4
  3. package/src/api/base.ts +0 -19
  4. package/src/api/encryption.ts +0 -34
  5. package/src/api/flow.ts +0 -253
  6. package/src/api/index.ts +0 -24
  7. package/src/api/media.ts +0 -52
  8. package/src/api/messages.ts +0 -160
  9. package/src/api/phoneNumber.ts +0 -59
  10. package/src/api/qrCode.ts +0 -64
  11. package/src/api/registration.ts +0 -38
  12. package/src/api/template.ts +0 -70
  13. package/src/api/twoStepVerification.ts +0 -24
  14. package/src/api/waba.ts +0 -55
  15. package/src/httpsClient.ts +0 -83
  16. package/src/index.ts +0 -3
  17. package/src/request.ts +0 -104
  18. package/src/types/base.ts +0 -5
  19. package/src/types/config.ts +0 -68
  20. package/src/types/encryption.ts +0 -11
  21. package/src/types/enums.ts +0 -563
  22. package/src/types/flow.ts +0 -274
  23. package/src/types/httpsClient.ts +0 -28
  24. package/src/types/index.ts +0 -16
  25. package/src/types/logger.ts +0 -7
  26. package/src/types/media.ts +0 -31
  27. package/src/types/messages.ts +0 -453
  28. package/src/types/phoneNumber.ts +0 -111
  29. package/src/types/qrCode.ts +0 -30
  30. package/src/types/registration.ts +0 -17
  31. package/src/types/request.ts +0 -66
  32. package/src/types/template.ts +0 -134
  33. package/src/types/twoStepVerification.ts +0 -9
  34. package/src/types/waba.ts +0 -18
  35. package/src/types/whatsapp.ts +0 -31
  36. package/src/utils/.gitkeep +0 -0
  37. package/src/utils/generateXHub256Sig.ts +0 -5
  38. package/src/utils/importConfig.ts +0 -55
  39. package/src/utils/index.ts +0 -2
  40. package/src/utils/isMetaError.ts +0 -44
  41. package/src/utils/logger.ts +0 -46
  42. package/src/utils/objectToQueryString.ts +0 -16
  43. package/src/whatsapp.ts +0 -96
@@ -1,134 +0,0 @@
1
- import { CategoryEnum, LanguagesEnum, TemplateStatusEnum } from './enums';
2
- import { GeneralRequestBody, RequesterResponseInterface, ResponsePagination, ResponseSuccess } from './request';
3
-
4
- export type TemplateFormat = 'TEXT' | 'IMAGE' | 'VIDEO' | 'DOCUMENT' | 'LOCATION';
5
-
6
- export type PhoneNumberButton = {
7
- type: 'PHONE_NUMBER';
8
- text: string; // max 25 chars
9
- phone_number: string; // max 20 chars
10
- };
11
-
12
- export type URLButton = {
13
- type: 'URL';
14
- text: string; // max 25 chars
15
- url: string; // max 2000 chars
16
- example?: string[]; // Required if url contains variable
17
- };
18
-
19
- export type QuickReplyButton = {
20
- type: 'QUICK_REPLY';
21
- text: string; // max 25 chars
22
- };
23
-
24
- export type CopyCodeButton = {
25
- type: 'COPY_CODE';
26
- example: string; // max 15 chars
27
- };
28
-
29
- export type FlowButton = {
30
- type: 'FLOW';
31
- text: string; // max 25 chars
32
- flow_id?: string;
33
- flow_name?: string;
34
- flow_json?: string;
35
- flow_action?: 'navigate' | 'data_exchange';
36
- navigate_screen?: string;
37
- };
38
-
39
- export type MPMButton = {
40
- type: 'MPM';
41
- };
42
-
43
- export type OTPButton = {
44
- type: 'OTP';
45
- };
46
-
47
- export type SPMButton = {
48
- type: 'SPM';
49
- };
50
-
51
- export type TemplateButton =
52
- | PhoneNumberButton
53
- | URLButton
54
- | QuickReplyButton
55
- | CopyCodeButton
56
- | FlowButton
57
- | MPMButton
58
- | OTPButton
59
- | SPMButton;
60
-
61
- export type TemplateHeaderExample = {
62
- header_text?: string[];
63
- header_text_named_params?: Array<{
64
- param_name: string;
65
- example: string;
66
- }>;
67
- header_handle?: string[];
68
- };
69
-
70
- export type TemplateHeader = {
71
- type: 'HEADER';
72
- format: TemplateFormat;
73
- text?: string; // max 60 chars
74
- example?: TemplateHeaderExample;
75
- };
76
-
77
- export type TemplateBody = {
78
- type: 'BODY';
79
- text: string; // max 1024 chars
80
- example?: {
81
- body_text?: Array<Array<string>>; // For positional parameters
82
- body_text_named_params?: Array<{
83
- param_name: string; // lowercase letters and underscores only
84
- example: string;
85
- }>; // For named parameters
86
- };
87
- };
88
-
89
- export type TemplateFooter = {
90
- type: 'FOOTER';
91
- text: string; // max 60 chars
92
- };
93
-
94
- export type ComponentTypes = TemplateHeader | TemplateBody | TemplateFooter | TemplateButton;
95
-
96
- export type TemplateRequestBody = GeneralRequestBody & {
97
- name: string;
98
- language: LanguagesEnum;
99
- category?: CategoryEnum;
100
- components?: ComponentTypes[];
101
- };
102
-
103
- export type TemplateResponse = {
104
- id: string;
105
- status: string;
106
- language: LanguagesEnum;
107
- category: CategoryEnum;
108
- name: string;
109
- components: ComponentTypes[];
110
- };
111
-
112
- export type TemplateGetParams = {
113
- limit?: number;
114
- name?: string;
115
- language?: LanguagesEnum;
116
- category?: CategoryEnum;
117
- status?: TemplateStatusEnum;
118
- };
119
-
120
- export type TemplateDeleteParams = {
121
- hsm_id: string;
122
- name: string;
123
- };
124
-
125
- export declare class TemplateClass {
126
- getTemplate(templateId: string): Promise<RequesterResponseInterface<TemplateResponse>>;
127
- updateTemplate(
128
- templateId: string,
129
- template: Partial<TemplateRequestBody>,
130
- ): Promise<RequesterResponseInterface<ResponseSuccess>>;
131
- getTemplates(params: TemplateGetParams): Promise<RequesterResponseInterface<ResponsePagination<TemplateResponse>>>;
132
- createTemplate(template: TemplateRequestBody): Promise<RequesterResponseInterface<TemplateResponse>>;
133
- deleteTemplate(params: TemplateDeleteParams): Promise<RequesterResponseInterface<ResponseSuccess>>;
134
- }
@@ -1,9 +0,0 @@
1
- import { RequesterResponseInterface, ResponseSuccess } from './request';
2
-
3
- export type TwoStepVerificationRequest = {
4
- pin: string;
5
- };
6
-
7
- export interface TwoStepVerificationClass {
8
- setTwoStepVerificationCode(pin: string): Promise<RequesterResponseInterface<ResponseSuccess>>;
9
- }
package/src/types/waba.ts DELETED
@@ -1,18 +0,0 @@
1
- import { RequesterResponseInterface, ResponseData, ResponseSuccess } from './request';
2
-
3
- export type WabaSubscription = {
4
- whatsapp_business_api_data: {
5
- id: string;
6
- link: string;
7
- name: string;
8
- };
9
- };
10
-
11
- export type WabaSubscriptions = ResponseData<Array<WabaSubscription>>;
12
-
13
- export declare class WABAClass {
14
- getAllWabaSubscriptions(): Promise<RequesterResponseInterface<WabaSubscriptions>>;
15
- subscribeToWaba(): Promise<RequesterResponseInterface<ResponseSuccess>>;
16
- unsubscribeFromWaba(): Promise<RequesterResponseInterface<ResponseSuccess>>;
17
- overrideWabaWebhook(webhookUrl: string, verifyToken: string): Promise<RequesterResponseInterface<ResponseSuccess>>;
18
- }
@@ -1,31 +0,0 @@
1
- /**
2
- * Copyright (c) Meta Platforms, Inc. and affiliates.
3
- * All rights reserved.
4
- *
5
- * This source code is licensed under the license found in the
6
- * LICENSE file in the root directory of this source tree.
7
- */
8
-
9
- export type WhatsAppConfig = {
10
- accessToken: string;
11
- baseUrl?: string;
12
- appId?: string;
13
- appSecret?: string;
14
- phoneNumberId?: number;
15
- businessAcctId?: string;
16
- apiVersion?: string;
17
- webhookEndpoint?: string;
18
- webhookVerificationToken?: string;
19
- listenerPort?: number;
20
- debug?: boolean;
21
- maxRetriesAfterWait?: number;
22
- requestTimeout?: number;
23
- };
24
-
25
- export declare class WhatsAppClass {
26
- constructor(config?: WhatsAppConfig);
27
- updateTimeout(ms: number): boolean;
28
- updatePhoneNumberId(phoneNumberId: number): boolean;
29
- updateAccessToken(accessToken: string): boolean;
30
- updateWabaId(wabaId: string): boolean;
31
- }
File without changes
@@ -1,5 +0,0 @@
1
- import * as crypto from 'crypto';
2
-
3
- export const generateXHub256Sig = (body: string, appSecret: string) => {
4
- return crypto.createHmac('sha256', appSecret).update(body, 'utf-8').digest('hex');
5
- };
@@ -1,55 +0,0 @@
1
- import Logger from './logger';
2
- import type { WabaConfigType } from '../types/config';
3
- import { WabaConfigEnum } from '../types/enums';
4
- import { WhatsAppConfig } from 'src/types/whatsapp';
5
-
6
- const LIB_NAME = 'UTILS';
7
- const LOG_LOCAL = false;
8
- const LOGGER = new Logger(LIB_NAME, process.env.DEBUG === 'true' || LOG_LOCAL);
9
- const DEFAULT_BASE_URL = 'graph.facebook.com';
10
- const DEFAULT_APIVersion = 'v22.0';
11
- const DEFAULT_LISTENER_PORT = 3000;
12
- const DEFAULT_MAX_RETRIES_AFTER_WAIT = 30;
13
- const DEFAULT_REQUEST_TIMEOUT = 20000;
14
-
15
- const emptyConfigChecker = (phoneNumberId?: number, accessToken?: string) => {
16
- if (!process.env[WabaConfigEnum.PhoneNumberId] && !phoneNumberId) {
17
- LOGGER.log(`Environmental variable: WA_PHONE_NUMBER_ID and/or sender phone number id argument is undefined.`);
18
- throw new Error('Missing WhatsApp sender phone number Id.');
19
- }
20
-
21
- if (!process.env[WabaConfigEnum.AccessToken] && !accessToken) {
22
- LOGGER.log(`Environmental variable: CLOUD_API_ACCESS_TOKEN and/or access token argument is undefined.`);
23
- throw new Error('Missing WhatsApp access token.');
24
- }
25
-
26
- if (!process.env[WabaConfigEnum.APIVersion]) {
27
- LOGGER.log(`Environmental variable: CLOUD_API_VERSION is undefined.`);
28
- throw new Error('Missing WhatsApp API version.');
29
- }
30
- };
31
-
32
- export const importConfig = (inputConfig?: WhatsAppConfig) => {
33
- emptyConfigChecker(inputConfig?.phoneNumberId, inputConfig?.accessToken);
34
-
35
- const wabaConfig: WabaConfigType = {
36
- [WabaConfigEnum.BaseURL]: process.env.WA_BASE_URL || DEFAULT_BASE_URL,
37
- [WabaConfigEnum.AppId]: process.env.M4D_APP_ID || '',
38
- [WabaConfigEnum.AppSecret]: process.env.M4D_APP_SECRET || '',
39
- [WabaConfigEnum.PhoneNumberId]: inputConfig?.phoneNumberId || parseInt(process.env.WA_PHONE_NUMBER_ID || ''),
40
- [WabaConfigEnum.BusinessAcctId]: process.env.WA_BUSINESS_ACCOUNT_ID || '',
41
- [WabaConfigEnum.APIVersion]: process.env.CLOUD_API_VERSION || DEFAULT_APIVersion,
42
- [WabaConfigEnum.AccessToken]: inputConfig?.accessToken || process.env.CLOUD_API_ACCESS_TOKEN || '',
43
- [WabaConfigEnum.WebhookEndpoint]: process.env.WEBHOOK_ENDPOINT || '',
44
- [WabaConfigEnum.WebhookVerificationToken]: process.env.WEBHOOK_VERIFICATION_TOKEN || '',
45
- [WabaConfigEnum.ListenerPort]: parseInt(process.env.LISTENER_PORT || '') || DEFAULT_LISTENER_PORT,
46
- [WabaConfigEnum.MaxRetriesAfterWait]:
47
- parseInt(process.env.MAX_RETRIES_AFTER_WAIT || '') || DEFAULT_MAX_RETRIES_AFTER_WAIT,
48
- [WabaConfigEnum.RequestTimeout]: parseInt(process.env.REQUEST_TIMEOUT || '') || DEFAULT_REQUEST_TIMEOUT,
49
- [WabaConfigEnum.Debug]: process.env.DEBUG === 'true',
50
- };
51
-
52
- LOGGER.log(`Configuration loaded for App Id ${wabaConfig[WabaConfigEnum.AppId]}`);
53
-
54
- return wabaConfig;
55
- };
@@ -1,2 +0,0 @@
1
- export * from './isMetaError';
2
- export * from './importConfig';
@@ -1,44 +0,0 @@
1
- export interface MetaError extends Error {
2
- error: {
3
- message: string;
4
- type: string;
5
- code: number;
6
- error_data?: {
7
- messaging_product: 'whatsapp';
8
- details: string;
9
- };
10
- error_subcode?: number;
11
- fbtrace_id: string;
12
- };
13
- }
14
-
15
- /**
16
- * Determines if the error is a Meta API error response
17
- * @param error Any error object to check
18
- * @returns Type guard indicating if error is a Meta API error
19
- */
20
- export function isMetaError(error: any): error is MetaError {
21
- return (
22
- error != null &&
23
- typeof error === 'object' &&
24
- 'error' in error &&
25
- typeof error.error === 'object' &&
26
- error.error != null &&
27
- 'message' in error.error &&
28
- typeof error.error.message === 'string' &&
29
- 'type' in error.error &&
30
- typeof error.error.type === 'string' &&
31
- 'code' in error.error &&
32
- typeof error.error.code === 'number' &&
33
- 'fbtrace_id' in error.error &&
34
- typeof error.error.fbtrace_id === 'string' &&
35
- (!('error_data' in error.error) ||
36
- (typeof error.error.error_data === 'object' &&
37
- error.error.error_data != null &&
38
- 'messaging_product' in error.error.error_data &&
39
- error.error.error_data.messaging_product === 'whatsapp' &&
40
- 'details' in error.error.error_data &&
41
- typeof error.error.error_data.details === 'string')) &&
42
- (!('error_subcode' in error.error) || typeof error.error.error_subcode === 'number')
43
- );
44
- }
@@ -1,46 +0,0 @@
1
- // @ts-nocheck
2
- import type { LoggerInterface } from '../types/logger';
3
-
4
- export default class Logger implements LoggerInterface {
5
- private name: string;
6
- private debug: boolean;
7
-
8
- constructor(name: string, debug: boolean = false) {
9
- this.name = name;
10
- this.debug = debug;
11
- }
12
-
13
- log(...data: any[]) {
14
- if (this.debug) {
15
- let prefix = `[ ${Date.now()} ]`;
16
- if (this.name) {
17
- prefix += ` - ${this.name}`;
18
- }
19
- console.log.apply(console, [prefix, ': ', ...data]);
20
- }
21
- }
22
-
23
- error(...data: any[]) {
24
- let prefix = `[ ${Date.now()} ] - ERROR`;
25
- if (this.name) {
26
- prefix += ` - ${this.name}`;
27
- }
28
- console.error.apply(console, [prefix, ': ', ...data]);
29
- }
30
-
31
- warn(...data: any[]) {
32
- let prefix = `[ ${Date.now()} ] - WARN`;
33
- if (this.name) {
34
- prefix += ` - ${this.name}`;
35
- }
36
- console.warn.apply(console, [prefix, ': ', ...data]);
37
- }
38
-
39
- info(...data: any[]) {
40
- let prefix = `[ ${Date.now()} ] - INFO`;
41
- if (this.name) {
42
- prefix += ` - ${this.name}`;
43
- }
44
- console.info.apply(console, [prefix, ': ', ...data]);
45
- }
46
- }
@@ -1,16 +0,0 @@
1
- export const objectToQueryString = (params: Record<string, any>): string => {
2
- if (!params || Object.keys(params).length === 0) {
3
- return '';
4
- }
5
-
6
- const searchParams = new URLSearchParams();
7
-
8
- for (const [key, value] of Object.entries(params)) {
9
- if (value !== undefined) {
10
- searchParams.append(key, String(value));
11
- }
12
- }
13
-
14
- const queryString = searchParams.toString();
15
- return queryString ? `?${queryString}` : '';
16
- };
package/src/whatsapp.ts DELETED
@@ -1,96 +0,0 @@
1
- import { WabaConfigType } from './types/config';
2
- import * as SDKEnums from './types/enums';
3
- import Logger from './utils/logger';
4
-
5
- import { importConfig } from './utils/importConfig';
6
- import Requester from './request';
7
- import { WhatsAppClass, WhatsAppConfig } from './types/whatsapp';
8
- import {
9
- MessagesAPI,
10
- PhoneNumberAPI,
11
- TemplateAPI,
12
- QrCodeAPI,
13
- EncryptionAPI,
14
- TwoStepVerificationAPI,
15
- RegistrationAPI,
16
- MediaAPI,
17
- WabaAPI,
18
- FlowAPI,
19
- } from './api';
20
-
21
- const LIB_NAME = 'WHATSAPP';
22
- const LOG_LOCAL = false;
23
- const LOGGER = new Logger(LIB_NAME, process.env.DEBUG === 'true' || LOG_LOCAL);
24
-
25
- const headerPrefix = 'WA_SDK';
26
-
27
- export default class WhatsApp implements WhatsAppClass {
28
- config: WabaConfigType;
29
-
30
- requester: Readonly<Requester>;
31
-
32
- readonly messages: MessagesAPI;
33
- readonly templates: TemplateAPI;
34
- readonly phoneNumber: PhoneNumberAPI;
35
- readonly qrCode: QrCodeAPI;
36
- readonly encryption: EncryptionAPI;
37
- readonly twoStepVerification: TwoStepVerificationAPI;
38
- readonly registration: RegistrationAPI;
39
- readonly media: MediaAPI;
40
- readonly waba: WabaAPI;
41
- readonly flow: FlowAPI;
42
- static readonly Enums = SDKEnums;
43
-
44
- constructor(config?: WhatsAppConfig) {
45
- this.config = importConfig(config);
46
- this.requester = new Requester(
47
- this.config[SDKEnums.WabaConfigEnum.BaseURL],
48
- this.config[SDKEnums.WabaConfigEnum.APIVersion],
49
- this.config[SDKEnums.WabaConfigEnum.PhoneNumberId],
50
- this.config[SDKEnums.WabaConfigEnum.AccessToken],
51
- this.config[SDKEnums.WabaConfigEnum.BusinessAcctId],
52
- this.userAgent(),
53
- );
54
-
55
- this.messages = new MessagesAPI(this.config, this.requester);
56
- this.templates = new TemplateAPI(this.config, this.requester);
57
- this.phoneNumber = new PhoneNumberAPI(this.config, this.requester);
58
- this.qrCode = new QrCodeAPI(this.config, this.requester);
59
- this.encryption = new EncryptionAPI(this.config, this.requester);
60
- this.twoStepVerification = new TwoStepVerificationAPI(this.config, this.requester);
61
- this.registration = new RegistrationAPI(this.config, this.requester);
62
- this.media = new MediaAPI(this.config, this.requester);
63
- this.waba = new WabaAPI(this.config, this.requester);
64
- this.flow = new FlowAPI(this.config, this.requester);
65
- LOGGER.log('WhatsApp Node.js SDK instantiated!');
66
- }
67
-
68
- private userAgent(): string {
69
- const userAgentString = `${headerPrefix}/${'0.0.1'} (Node.js ${process.version})`;
70
- return userAgentString;
71
- }
72
-
73
- updateTimeout(ms: number): boolean {
74
- this.config[SDKEnums.WabaConfigEnum.RequestTimeout] = ms;
75
- LOGGER.log(`Updated request timeout to ${ms}ms`);
76
- return true;
77
- }
78
-
79
- updatePhoneNumberId(phoneNumberId: number): boolean {
80
- this.config[SDKEnums.WabaConfigEnum.PhoneNumberId] = phoneNumberId;
81
- LOGGER.log(`Updated sender phone number id to ${phoneNumberId}`);
82
- return true;
83
- }
84
-
85
- updateAccessToken(accessToken: string): boolean {
86
- this.config[SDKEnums.WabaConfigEnum.AccessToken] = accessToken;
87
- LOGGER.log(`Updated access token`);
88
- return true;
89
- }
90
-
91
- updateWabaId(wabaId: string): boolean {
92
- this.config[SDKEnums.WabaConfigEnum.BusinessAcctId] = wabaId;
93
- LOGGER.log(`Updated business account id to ${wabaId}`);
94
- return true;
95
- }
96
- }