@rempays/shared-core 1.0.2-beta.13 → 1.0.2-beta.14
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.
|
@@ -1,9 +1,10 @@
|
|
|
1
|
-
import type { SendTextParams, SendTemplateParams, SendInteractiveParams, SendInteractiveListParams, SendImageParams, SendDocumentParams, SendLocationParams, SetTypingParams, MarkAsReadParams, SendAudioParams, SendVideoParams, MediaInfoResponse, CreateTemplateParams } from "./types";
|
|
1
|
+
import type { SendTextParams, SendTemplateParams, SendInteractiveParams, SendInteractiveListParams, SendImageParams, SendDocumentParams, SendLocationParams, SetTypingParams, MarkAsReadParams, SendAudioParams, SendVideoParams, MediaInfoResponse, CreateTemplateParams, BusinessProfileParams, BusinessProfileResponse, UpdateDisplayNameParams, DisplayNameStatusResponse } from "./types";
|
|
2
2
|
export declare class FacebookApi {
|
|
3
3
|
private static token;
|
|
4
4
|
private static phoneNumberId;
|
|
5
5
|
private static apiVersion;
|
|
6
|
-
|
|
6
|
+
private static appId;
|
|
7
|
+
constructor(token?: string, phoneNumberId?: string, apiVersion?: string, appId?: string);
|
|
7
8
|
private static init;
|
|
8
9
|
private static post;
|
|
9
10
|
static sendText(params: SendTextParams): Promise<any>;
|
|
@@ -23,4 +24,22 @@ export declare class FacebookApi {
|
|
|
23
24
|
static listTemplates(wabaId: string): Promise<any>;
|
|
24
25
|
static createTemplate(params: CreateTemplateParams): Promise<any>;
|
|
25
26
|
static deleteTemplate(wabaId: string, name: string): Promise<any>;
|
|
27
|
+
/**
|
|
28
|
+
* Uploads an image and updates the business profile picture.
|
|
29
|
+
* @param buffer Image binary data
|
|
30
|
+
* @param mimeType Image MIME type (image/jpeg or image/png)
|
|
31
|
+
*/
|
|
32
|
+
static updateProfilePicture(buffer: Buffer, mimeType: string): Promise<any>;
|
|
33
|
+
/**
|
|
34
|
+
* Uploads media for chat (messages).
|
|
35
|
+
* @param buffer Media binary data
|
|
36
|
+
* @param mimeType MIME type of the file
|
|
37
|
+
*/
|
|
38
|
+
static uploadMedia(buffer: Buffer, mimeType: string): Promise<{
|
|
39
|
+
id: string;
|
|
40
|
+
}>;
|
|
41
|
+
static getBusinessProfile(): Promise<BusinessProfileResponse>;
|
|
42
|
+
static updateBusinessProfile(params: BusinessProfileParams): Promise<any>;
|
|
43
|
+
static updateDisplayName(params: UpdateDisplayNameParams): Promise<any>;
|
|
44
|
+
static getDisplayNameStatus(): Promise<DisplayNameStatusResponse>;
|
|
26
45
|
}
|
|
@@ -3,13 +3,15 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.FacebookApi = void 0;
|
|
4
4
|
const http_1 = require("./http");
|
|
5
5
|
class FacebookApi {
|
|
6
|
-
constructor(token, phoneNumberId, apiVersion) {
|
|
6
|
+
constructor(token, phoneNumberId, apiVersion, appId) {
|
|
7
7
|
if (token)
|
|
8
8
|
FacebookApi.token = token;
|
|
9
9
|
if (phoneNumberId)
|
|
10
10
|
FacebookApi.phoneNumberId = phoneNumberId;
|
|
11
11
|
if (apiVersion)
|
|
12
12
|
FacebookApi.apiVersion = apiVersion;
|
|
13
|
+
if (appId)
|
|
14
|
+
FacebookApi.appId = appId;
|
|
13
15
|
}
|
|
14
16
|
static async init() {
|
|
15
17
|
if (this.token && this.phoneNumberId && this.apiVersion)
|
|
@@ -19,6 +21,7 @@ class FacebookApi {
|
|
|
19
21
|
this.phoneNumberId || process.env.FACEBOOK_PHONE_NUMBER_ID || null;
|
|
20
22
|
this.apiVersion =
|
|
21
23
|
this.apiVersion || process.env.FACEBOOK_API_VERSION || "v18.0";
|
|
24
|
+
this.appId = this.appId || process.env.FACEBOOK_APP_ID || null;
|
|
22
25
|
if (!this.token || !this.phoneNumberId) {
|
|
23
26
|
throw new Error("Facebook API environment variables are not properly configured (FACEBOOK_API_TOKEN, FACEBOOK_PHONE_NUMBER_ID)");
|
|
24
27
|
}
|
|
@@ -142,7 +145,11 @@ class FacebookApi {
|
|
|
142
145
|
messaging_product: "whatsapp",
|
|
143
146
|
to: params.to,
|
|
144
147
|
type: "image",
|
|
145
|
-
image: {
|
|
148
|
+
image: {
|
|
149
|
+
link: params.link,
|
|
150
|
+
id: params.id,
|
|
151
|
+
caption: params.caption
|
|
152
|
+
},
|
|
146
153
|
};
|
|
147
154
|
return await this.post("messages", payload);
|
|
148
155
|
}
|
|
@@ -156,6 +163,7 @@ class FacebookApi {
|
|
|
156
163
|
type: "document",
|
|
157
164
|
document: {
|
|
158
165
|
link: params.link,
|
|
166
|
+
id: params.id,
|
|
159
167
|
caption: params.caption,
|
|
160
168
|
filename: params.filename,
|
|
161
169
|
},
|
|
@@ -172,6 +180,7 @@ class FacebookApi {
|
|
|
172
180
|
type: "audio",
|
|
173
181
|
audio: {
|
|
174
182
|
link: params.link,
|
|
183
|
+
id: params.id,
|
|
175
184
|
},
|
|
176
185
|
};
|
|
177
186
|
return await this.post("messages", payload);
|
|
@@ -186,6 +195,7 @@ class FacebookApi {
|
|
|
186
195
|
type: "video",
|
|
187
196
|
video: {
|
|
188
197
|
link: params.link,
|
|
198
|
+
id: params.id,
|
|
189
199
|
caption: params.caption,
|
|
190
200
|
},
|
|
191
201
|
};
|
|
@@ -293,8 +303,120 @@ class FacebookApi {
|
|
|
293
303
|
});
|
|
294
304
|
return data;
|
|
295
305
|
}
|
|
306
|
+
/*
|
|
307
|
+
PROFILE PICTURE UPLOAD (TWO-STEP)
|
|
308
|
+
*/
|
|
309
|
+
/**
|
|
310
|
+
* Uploads an image and updates the business profile picture.
|
|
311
|
+
* @param buffer Image binary data
|
|
312
|
+
* @param mimeType Image MIME type (image/jpeg or image/png)
|
|
313
|
+
*/
|
|
314
|
+
static async updateProfilePicture(buffer, mimeType) {
|
|
315
|
+
await this.init();
|
|
316
|
+
if (!this.appId) {
|
|
317
|
+
throw new Error("FACEBOOK_APP_ID is required for profile picture uploads");
|
|
318
|
+
}
|
|
319
|
+
const http = (0, http_1.getHttpClient)(this.token);
|
|
320
|
+
// 1. Create upload session
|
|
321
|
+
const sessionUrl = `https://graph.facebook.com/${this.apiVersion}/${this.appId}/uploads`;
|
|
322
|
+
const { data: sessionData } = await http.post(sessionUrl, null, {
|
|
323
|
+
params: {
|
|
324
|
+
file_length: buffer.length,
|
|
325
|
+
file_type: mimeType,
|
|
326
|
+
access_token: this.token
|
|
327
|
+
}
|
|
328
|
+
});
|
|
329
|
+
const sessionId = sessionData.id;
|
|
330
|
+
// 2. Upload the file data
|
|
331
|
+
const uploadUrl = `https://graph.facebook.com/${this.apiVersion}/${sessionId}`;
|
|
332
|
+
const { data: uploadData } = await http.post(uploadUrl, buffer, {
|
|
333
|
+
headers: {
|
|
334
|
+
'file_offset': 0,
|
|
335
|
+
'Content-Type': mimeType
|
|
336
|
+
}
|
|
337
|
+
});
|
|
338
|
+
const handle = uploadData.h;
|
|
339
|
+
// 3. Update the business profile with the handle
|
|
340
|
+
return await this.updateBusinessProfile({
|
|
341
|
+
profile_picture_handle: handle
|
|
342
|
+
});
|
|
343
|
+
}
|
|
344
|
+
/*
|
|
345
|
+
CHAT MEDIA UPLOAD
|
|
346
|
+
*/
|
|
347
|
+
/**
|
|
348
|
+
* Uploads media for chat (messages).
|
|
349
|
+
* @param buffer Media binary data
|
|
350
|
+
* @param mimeType MIME type of the file
|
|
351
|
+
*/
|
|
352
|
+
static async uploadMedia(buffer, mimeType) {
|
|
353
|
+
await this.init();
|
|
354
|
+
const http = (0, http_1.getHttpClient)(this.token);
|
|
355
|
+
const url = `https://graph.facebook.com/${this.apiVersion}/${this.phoneNumberId}/media`;
|
|
356
|
+
const formData = new FormData();
|
|
357
|
+
const blob = new Blob([buffer], { type: mimeType });
|
|
358
|
+
formData.append('file', blob, 'media');
|
|
359
|
+
formData.append('type', mimeType);
|
|
360
|
+
formData.append('messaging_product', 'whatsapp');
|
|
361
|
+
const { data } = await http.post(url, formData, {
|
|
362
|
+
headers: {
|
|
363
|
+
'Content-Type': 'multipart/form-data'
|
|
364
|
+
}
|
|
365
|
+
});
|
|
366
|
+
return data; // Returns { id: "media_id" }
|
|
367
|
+
}
|
|
368
|
+
/*
|
|
369
|
+
BUSINESS PROFILE
|
|
370
|
+
*/
|
|
371
|
+
static async getBusinessProfile() {
|
|
372
|
+
await this.init();
|
|
373
|
+
const http = (0, http_1.getHttpClient)(this.token);
|
|
374
|
+
const url = `https://graph.facebook.com/${this.apiVersion}/${this.phoneNumberId}/whatsapp_business_profile`;
|
|
375
|
+
const { data } = await http.get(url, {
|
|
376
|
+
params: {
|
|
377
|
+
fields: "about,address,description,email,profile_picture_url,websites,vertical"
|
|
378
|
+
}
|
|
379
|
+
});
|
|
380
|
+
// The response is usually { data: [ { ... } ] }
|
|
381
|
+
return data.data?.[0] || data;
|
|
382
|
+
}
|
|
383
|
+
static async updateBusinessProfile(params) {
|
|
384
|
+
const payload = {
|
|
385
|
+
messaging_product: "whatsapp",
|
|
386
|
+
...params
|
|
387
|
+
};
|
|
388
|
+
return await this.post("whatsapp_business_profile", payload);
|
|
389
|
+
}
|
|
390
|
+
/*
|
|
391
|
+
DISPLAY NAME
|
|
392
|
+
*/
|
|
393
|
+
static async updateDisplayName(params) {
|
|
394
|
+
await this.init();
|
|
395
|
+
const http = (0, http_1.getHttpClient)(this.token);
|
|
396
|
+
// Using phone number ID directly with query params as per Meta documentation
|
|
397
|
+
const url = `https://graph.facebook.com/${this.apiVersion}/${this.phoneNumberId}`;
|
|
398
|
+
const { data } = await http.post(url, null, {
|
|
399
|
+
params: {
|
|
400
|
+
new_display_name: params.new_display_name
|
|
401
|
+
}
|
|
402
|
+
});
|
|
403
|
+
return data;
|
|
404
|
+
}
|
|
405
|
+
static async getDisplayNameStatus() {
|
|
406
|
+
await this.init();
|
|
407
|
+
const http = (0, http_1.getHttpClient)(this.token);
|
|
408
|
+
// Using phone number ID to get status of display names
|
|
409
|
+
const url = `https://graph.facebook.com/${this.apiVersion}/${this.phoneNumberId}`;
|
|
410
|
+
const { data } = await http.get(url, {
|
|
411
|
+
params: {
|
|
412
|
+
fields: "verified_name,name_status,new_display_name,new_name_status"
|
|
413
|
+
}
|
|
414
|
+
});
|
|
415
|
+
return data;
|
|
416
|
+
}
|
|
296
417
|
}
|
|
297
418
|
exports.FacebookApi = FacebookApi;
|
|
298
419
|
FacebookApi.token = null;
|
|
299
420
|
FacebookApi.phoneNumberId = null;
|
|
300
421
|
FacebookApi.apiVersion = null;
|
|
422
|
+
FacebookApi.appId = null;
|
|
@@ -49,12 +49,14 @@ export interface SendInteractiveListParams {
|
|
|
49
49
|
}
|
|
50
50
|
export interface SendImageParams {
|
|
51
51
|
to: string;
|
|
52
|
-
link
|
|
52
|
+
link?: string;
|
|
53
|
+
id?: string;
|
|
53
54
|
caption?: string;
|
|
54
55
|
}
|
|
55
56
|
export interface SendDocumentParams {
|
|
56
57
|
to: string;
|
|
57
|
-
link
|
|
58
|
+
link?: string;
|
|
59
|
+
id?: string;
|
|
58
60
|
filename?: string;
|
|
59
61
|
caption?: string;
|
|
60
62
|
}
|
|
@@ -115,11 +117,13 @@ export interface PhoneNumberInfo {
|
|
|
115
117
|
}
|
|
116
118
|
export interface SendAudioParams {
|
|
117
119
|
to: string;
|
|
118
|
-
link
|
|
120
|
+
link?: string;
|
|
121
|
+
id?: string;
|
|
119
122
|
}
|
|
120
123
|
export interface SendVideoParams {
|
|
121
124
|
to: string;
|
|
122
|
-
link
|
|
125
|
+
link?: string;
|
|
126
|
+
id?: string;
|
|
123
127
|
caption?: string;
|
|
124
128
|
}
|
|
125
129
|
export interface MediaInfoResponse {
|
|
@@ -135,3 +139,33 @@ export interface CreateTemplateParams {
|
|
|
135
139
|
language: string;
|
|
136
140
|
bodyText: string;
|
|
137
141
|
}
|
|
142
|
+
export interface BusinessProfileParams {
|
|
143
|
+
about?: string;
|
|
144
|
+
address?: string;
|
|
145
|
+
description?: string;
|
|
146
|
+
email?: string;
|
|
147
|
+
websites?: string[];
|
|
148
|
+
vertical?: WhatsAppBusinessVertical;
|
|
149
|
+
profile_picture_handle?: string;
|
|
150
|
+
}
|
|
151
|
+
export type WhatsAppBusinessVertical = "" | "UNDEFINED" | "OTHER" | "AUTO" | "BEAUTY" | "APPAREL" | "EDU" | "ENTERTAIN" | "EVENT_PLAN" | "FINANCE" | "GROCERY" | "GOVT" | "HOTEL" | "HEALTH" | "NONPROFIT" | "PROF_SERVICES" | "RETAIL" | "TRAVEL" | "RESTAURANT" | "NOT_A_BIZ";
|
|
152
|
+
export interface BusinessProfileResponse {
|
|
153
|
+
messaging_product: "whatsapp";
|
|
154
|
+
about: string;
|
|
155
|
+
address: string;
|
|
156
|
+
description: string;
|
|
157
|
+
email: string;
|
|
158
|
+
websites: string[];
|
|
159
|
+
vertical: WhatsAppBusinessVertical;
|
|
160
|
+
profile_picture_url?: string;
|
|
161
|
+
}
|
|
162
|
+
export interface UpdateDisplayNameParams {
|
|
163
|
+
new_display_name: string;
|
|
164
|
+
}
|
|
165
|
+
export interface DisplayNameStatusResponse {
|
|
166
|
+
verified_name: string;
|
|
167
|
+
name_status: string;
|
|
168
|
+
new_display_name?: string;
|
|
169
|
+
new_name_status?: string;
|
|
170
|
+
id: string;
|
|
171
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@rempays/shared-core",
|
|
3
|
-
"version": "1.0.2-beta.
|
|
3
|
+
"version": "1.0.2-beta.14",
|
|
4
4
|
"description": "Core utilities layer for RemPays platform with AWS services integration (Cognito, S3, Secrets Manager, Textract, Facebook API, DynamoDB)",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"types": "dist/index.d.ts",
|