core-services-sdk 1.3.48 → 1.3.50
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.
- package/package.json +1 -1
- package/src/instant-messages/index.js +2 -0
- package/src/instant-messages/message-types.js +26 -32
- package/src/instant-messages/telegram-apis/telegram-apis.js +301 -0
- package/src/instant-messages/whatsapp-apis/whatsapp-apis.js +401 -0
- package/tests/instant-messages/message-unified-mapper-telegram.unit.test.js +0 -1
- package/tests/instant-messages/telegram-apis.unit.test.js +157 -0
- package/tests/instant-messages/unified-message-type.unit.test.js +78 -0
- package/tests/instant-messages/whatsapp-apis.unit.test.js +277 -0
- package/types/instant-messages/index.d.ts +2 -0
- package/types/instant-messages/message-types.d.ts +74 -26
- package/types/instant-messages/telegram-apis/telegram-apis.d.ts +105 -0
- package/types/instant-messages/whatsapp-apis/whatsapp-apis.d.ts +73 -0
|
@@ -0,0 +1,277 @@
|
|
|
1
|
+
// @ts-nocheck
|
|
2
|
+
import { describe, it, expect, beforeEach, vi } from 'vitest'
|
|
3
|
+
|
|
4
|
+
import {
|
|
5
|
+
whatsappApis,
|
|
6
|
+
getWhatsAppApiUrls,
|
|
7
|
+
getWhatsAppMediaInfo,
|
|
8
|
+
downloadWhatsAppMedia,
|
|
9
|
+
} from '../../src/instant-messages/whatsapp-apis/whatsapp-apis.js'
|
|
10
|
+
|
|
11
|
+
import * as httpModule from '../../src/http/http.js'
|
|
12
|
+
|
|
13
|
+
global.fetch = vi.fn()
|
|
14
|
+
|
|
15
|
+
describe('getWhatsAppMediaInfo', () => {
|
|
16
|
+
beforeEach(() => {
|
|
17
|
+
fetch.mockReset()
|
|
18
|
+
})
|
|
19
|
+
|
|
20
|
+
it('returns media metadata correctly', async () => {
|
|
21
|
+
const mockResponse = {
|
|
22
|
+
url: 'https://cdn.whatsapp.com/file.jpg',
|
|
23
|
+
mime_type: 'image/jpeg',
|
|
24
|
+
id: 'ABC123',
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
fetch.mockResolvedValue({
|
|
28
|
+
ok: true,
|
|
29
|
+
json: async () => mockResponse,
|
|
30
|
+
})
|
|
31
|
+
|
|
32
|
+
const result = await getWhatsAppMediaInfo({
|
|
33
|
+
mediaId: 'ABC123',
|
|
34
|
+
token: 'TOKEN',
|
|
35
|
+
})
|
|
36
|
+
|
|
37
|
+
expect(fetch).toHaveBeenCalledWith(
|
|
38
|
+
'https://graph.facebook.com/v21.0/ABC123',
|
|
39
|
+
{
|
|
40
|
+
headers: {
|
|
41
|
+
Authorization: 'Bearer TOKEN',
|
|
42
|
+
},
|
|
43
|
+
},
|
|
44
|
+
)
|
|
45
|
+
|
|
46
|
+
expect(result).toEqual(mockResponse)
|
|
47
|
+
})
|
|
48
|
+
|
|
49
|
+
it('throws on non successful response', async () => {
|
|
50
|
+
fetch.mockResolvedValue({
|
|
51
|
+
ok: false,
|
|
52
|
+
status: 403,
|
|
53
|
+
})
|
|
54
|
+
|
|
55
|
+
await expect(
|
|
56
|
+
getWhatsAppMediaInfo({
|
|
57
|
+
mediaId: 'MEDIA_ID',
|
|
58
|
+
token: 'TOKEN',
|
|
59
|
+
}),
|
|
60
|
+
).rejects.toThrow('Failed to retrieve media info: 403')
|
|
61
|
+
})
|
|
62
|
+
})
|
|
63
|
+
|
|
64
|
+
describe('downloadWhatsAppMedia', () => {
|
|
65
|
+
beforeEach(() => {
|
|
66
|
+
fetch.mockReset()
|
|
67
|
+
})
|
|
68
|
+
|
|
69
|
+
it('downloads media as buffer', async () => {
|
|
70
|
+
const mockMetadata = {
|
|
71
|
+
url: 'https://cdn.whatsapp.com/file.jpg',
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
const mockBinary = new Uint8Array([10, 20, 30])
|
|
75
|
+
|
|
76
|
+
fetch
|
|
77
|
+
.mockResolvedValueOnce({
|
|
78
|
+
ok: true,
|
|
79
|
+
json: async () => mockMetadata,
|
|
80
|
+
})
|
|
81
|
+
.mockResolvedValueOnce({
|
|
82
|
+
ok: true,
|
|
83
|
+
arrayBuffer: async () => mockBinary.buffer,
|
|
84
|
+
})
|
|
85
|
+
|
|
86
|
+
const buffer = await downloadWhatsAppMedia({
|
|
87
|
+
token: 'TOKEN',
|
|
88
|
+
mediaId: 'MEDIA_ID',
|
|
89
|
+
mode: 'buffer',
|
|
90
|
+
})
|
|
91
|
+
|
|
92
|
+
expect(Buffer.isBuffer(buffer)).toBe(true)
|
|
93
|
+
expect(buffer.equals(Buffer.from(mockBinary))).toBe(true)
|
|
94
|
+
})
|
|
95
|
+
|
|
96
|
+
it('returns stream when mode=stream', async () => {
|
|
97
|
+
const mockStream = { fake: 'stream' }
|
|
98
|
+
|
|
99
|
+
fetch
|
|
100
|
+
.mockResolvedValueOnce({
|
|
101
|
+
ok: true,
|
|
102
|
+
json: async () => ({ url: 'http://cdn.com/x' }),
|
|
103
|
+
})
|
|
104
|
+
.mockResolvedValueOnce({
|
|
105
|
+
ok: true,
|
|
106
|
+
body: mockStream,
|
|
107
|
+
})
|
|
108
|
+
|
|
109
|
+
const stream = await downloadWhatsAppMedia({
|
|
110
|
+
token: 'TOKEN',
|
|
111
|
+
mediaId: 'ID',
|
|
112
|
+
mode: 'stream',
|
|
113
|
+
})
|
|
114
|
+
|
|
115
|
+
expect(stream).toBe(mockStream)
|
|
116
|
+
})
|
|
117
|
+
})
|
|
118
|
+
|
|
119
|
+
describe('getWhatsAppApiUrls', () => {
|
|
120
|
+
it('generates correct messages URL', () => {
|
|
121
|
+
const url = getWhatsAppApiUrls({
|
|
122
|
+
phoneNumberId: '12345',
|
|
123
|
+
version: 'v21.0',
|
|
124
|
+
})
|
|
125
|
+
|
|
126
|
+
expect(url).toBe('https://graph.facebook.com/v21.0/12345/messages')
|
|
127
|
+
})
|
|
128
|
+
|
|
129
|
+
it('supports custom base URL', () => {
|
|
130
|
+
const url = getWhatsAppApiUrls({
|
|
131
|
+
phoneNumberId: '99',
|
|
132
|
+
baseUrl: 'http://localhost:3000',
|
|
133
|
+
version: 'v21.0',
|
|
134
|
+
})
|
|
135
|
+
|
|
136
|
+
expect(url).toBe('http://localhost:3000/v21.0/99/messages')
|
|
137
|
+
})
|
|
138
|
+
})
|
|
139
|
+
|
|
140
|
+
describe('whatsappApis', () => {
|
|
141
|
+
let postMock
|
|
142
|
+
|
|
143
|
+
beforeEach(() => {
|
|
144
|
+
postMock = vi
|
|
145
|
+
.spyOn(httpModule, 'post')
|
|
146
|
+
.mockResolvedValue({ ok: true, data: 'mock-response' })
|
|
147
|
+
})
|
|
148
|
+
|
|
149
|
+
const token = 'TOKEN'
|
|
150
|
+
const phoneNumberId = '111'
|
|
151
|
+
|
|
152
|
+
const baseUrl = 'https://graph.facebook.com/v21.0/111/messages'
|
|
153
|
+
|
|
154
|
+
it('sendMessage sends correct payload', async () => {
|
|
155
|
+
const api = whatsappApis({ token, phoneNumberId })
|
|
156
|
+
|
|
157
|
+
await api.sendMessage({
|
|
158
|
+
chatId: '9725000000',
|
|
159
|
+
text: 'Hello',
|
|
160
|
+
})
|
|
161
|
+
|
|
162
|
+
expect(postMock).toHaveBeenCalledWith({
|
|
163
|
+
url: baseUrl,
|
|
164
|
+
headers: { Authorization: 'Bearer TOKEN' },
|
|
165
|
+
body: {
|
|
166
|
+
recipient_type: 'individual',
|
|
167
|
+
messaging_product: 'whatsapp',
|
|
168
|
+
to: '9725000000',
|
|
169
|
+
type: 'text',
|
|
170
|
+
text: {
|
|
171
|
+
preview_url: true,
|
|
172
|
+
body: 'Hello',
|
|
173
|
+
},
|
|
174
|
+
},
|
|
175
|
+
})
|
|
176
|
+
})
|
|
177
|
+
|
|
178
|
+
it('sendPhoto sends correct body', async () => {
|
|
179
|
+
const api = whatsappApis({ token, phoneNumberId })
|
|
180
|
+
|
|
181
|
+
await api.sendPhoto({
|
|
182
|
+
chatId: '1',
|
|
183
|
+
photo: 'http://img.jpg',
|
|
184
|
+
caption: 'Hi',
|
|
185
|
+
})
|
|
186
|
+
|
|
187
|
+
expect(postMock).toHaveBeenCalledWith({
|
|
188
|
+
url: baseUrl,
|
|
189
|
+
headers: { Authorization: 'Bearer TOKEN' },
|
|
190
|
+
body: {
|
|
191
|
+
recipient_type: 'individual',
|
|
192
|
+
messaging_product: 'whatsapp',
|
|
193
|
+
to: '1',
|
|
194
|
+
type: 'image',
|
|
195
|
+
image: {
|
|
196
|
+
link: 'http://img.jpg',
|
|
197
|
+
caption: 'Hi',
|
|
198
|
+
},
|
|
199
|
+
},
|
|
200
|
+
})
|
|
201
|
+
})
|
|
202
|
+
|
|
203
|
+
it('sendVideo sends filename when provided', async () => {
|
|
204
|
+
const api = whatsappApis({ token, phoneNumberId })
|
|
205
|
+
|
|
206
|
+
await api.sendVideo({
|
|
207
|
+
chatId: '77',
|
|
208
|
+
video: 'http://video.mp4',
|
|
209
|
+
caption: 'watch',
|
|
210
|
+
filename: 'clip.mp4',
|
|
211
|
+
})
|
|
212
|
+
|
|
213
|
+
expect(postMock).toHaveBeenCalledWith({
|
|
214
|
+
url: baseUrl,
|
|
215
|
+
headers: { Authorization: 'Bearer TOKEN' },
|
|
216
|
+
body: {
|
|
217
|
+
recipient_type: 'individual',
|
|
218
|
+
messaging_product: 'whatsapp',
|
|
219
|
+
to: '77',
|
|
220
|
+
type: 'video',
|
|
221
|
+
video: {
|
|
222
|
+
link: 'http://video.mp4',
|
|
223
|
+
caption: 'watch',
|
|
224
|
+
filename: 'clip.mp4',
|
|
225
|
+
},
|
|
226
|
+
},
|
|
227
|
+
})
|
|
228
|
+
})
|
|
229
|
+
|
|
230
|
+
it('sendDocument works without filename', async () => {
|
|
231
|
+
const api = whatsappApis({ token, phoneNumberId })
|
|
232
|
+
|
|
233
|
+
await api.sendDocument({
|
|
234
|
+
chatId: '33',
|
|
235
|
+
document: 'http://file.pdf',
|
|
236
|
+
caption: 'doc',
|
|
237
|
+
})
|
|
238
|
+
|
|
239
|
+
expect(postMock).toHaveBeenCalledWith({
|
|
240
|
+
url: baseUrl,
|
|
241
|
+
headers: { Authorization: 'Bearer TOKEN' },
|
|
242
|
+
body: {
|
|
243
|
+
recipient_type: 'individual',
|
|
244
|
+
messaging_product: 'whatsapp',
|
|
245
|
+
to: '33',
|
|
246
|
+
type: 'document',
|
|
247
|
+
document: {
|
|
248
|
+
link: 'http://file.pdf',
|
|
249
|
+
caption: 'doc',
|
|
250
|
+
},
|
|
251
|
+
},
|
|
252
|
+
})
|
|
253
|
+
})
|
|
254
|
+
|
|
255
|
+
it('sendAudio sends correct structure', async () => {
|
|
256
|
+
const api = whatsappApis({ token, phoneNumberId })
|
|
257
|
+
|
|
258
|
+
await api.sendAudio({
|
|
259
|
+
chatId: '555',
|
|
260
|
+
audio: 'http://a.mp3',
|
|
261
|
+
})
|
|
262
|
+
|
|
263
|
+
expect(postMock).toHaveBeenCalledWith({
|
|
264
|
+
url: baseUrl,
|
|
265
|
+
headers: { Authorization: 'Bearer TOKEN' },
|
|
266
|
+
body: {
|
|
267
|
+
recipient_type: 'individual',
|
|
268
|
+
messaging_product: 'whatsapp',
|
|
269
|
+
to: '555',
|
|
270
|
+
type: 'audio',
|
|
271
|
+
audio: {
|
|
272
|
+
link: 'http://a.mp3',
|
|
273
|
+
},
|
|
274
|
+
},
|
|
275
|
+
})
|
|
276
|
+
})
|
|
277
|
+
})
|
|
@@ -2,37 +2,64 @@
|
|
|
2
2
|
* *
|
|
3
3
|
*/
|
|
4
4
|
export type MESSAGE_MEDIA_TYPE = string
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
5
|
+
/**
|
|
6
|
+
* Enumerates all supported incoming media/content types
|
|
7
|
+
* across messaging platforms (Telegram, WhatsApp, etc).
|
|
8
|
+
*
|
|
9
|
+
* This is the unified taxonomy used inside the system
|
|
10
|
+
* after normalization of the raw message payload.
|
|
11
|
+
*
|
|
12
|
+
* @readonly
|
|
13
|
+
* @enum {string}
|
|
14
|
+
* @type {{ [key: string]: string }}
|
|
15
|
+
*
|
|
16
|
+
* @property {"text"} TEXT
|
|
17
|
+
* @property {"poll"} POLL
|
|
18
|
+
* @property {"video"} VIDEO
|
|
19
|
+
* @property {"photo"} PHOTO
|
|
20
|
+
* @property {"image"} IMAGE
|
|
21
|
+
* @property {"voice"} VOICE
|
|
22
|
+
* @property {"audio"} AUDIO
|
|
23
|
+
* @property {"sticker"} STICKER
|
|
24
|
+
* @property {"contact"} CONTACT
|
|
25
|
+
* @property {"reaction"} REACTION
|
|
26
|
+
* @property {"document"} DOCUMENT
|
|
27
|
+
* @property {"location"} LOCATION
|
|
28
|
+
* @property {"contacts"} CONTACTS
|
|
29
|
+
* @property {"video_note"} VIDEO_NOTE
|
|
30
|
+
* @property {"button_click"} BUTTON_CLICK
|
|
31
|
+
* @property {"button_click_multiple"} BUTTON_CLICK_MULTIPLE
|
|
32
|
+
*/
|
|
33
|
+
export const MESSAGE_MEDIA_TYPE: {
|
|
34
|
+
[key: string]: string
|
|
23
35
|
}
|
|
24
36
|
/**
|
|
25
37
|
* *
|
|
26
38
|
*/
|
|
27
39
|
export type MESSAGE_TYPE = string
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
40
|
+
/**
|
|
41
|
+
* Additional high-level message categories.
|
|
42
|
+
*
|
|
43
|
+
* These represent logical groupings rather than raw media types.
|
|
44
|
+
*
|
|
45
|
+
* @readonly
|
|
46
|
+
* @enum {string}
|
|
47
|
+
* @type {{ [key: string]: string }}
|
|
48
|
+
*
|
|
49
|
+
* @property {"message"} MESSAGE
|
|
50
|
+
* Regular message container (base type in some providers).
|
|
51
|
+
*
|
|
52
|
+
* @property {"button_click"} BUTTON_CLICK
|
|
53
|
+
* A click on a single interactive button.
|
|
54
|
+
*
|
|
55
|
+
* @property {"button_click_multiple"} BUTTON_CLICK_MULTIPLE
|
|
56
|
+
* A selection from a list of interactive reply choices.
|
|
57
|
+
*
|
|
58
|
+
* @property {"unknown_message_type"} UNKNOWN_MESSAGE_TYPE
|
|
59
|
+
* Used when the system cannot identify or normalize the message type.
|
|
60
|
+
*/
|
|
61
|
+
export const MESSAGE_TYPE: {
|
|
62
|
+
[key: string]: string
|
|
36
63
|
}
|
|
37
64
|
/**
|
|
38
65
|
* *
|
|
@@ -60,3 +87,24 @@ export const MESSAGE_MEDIA_TYPE_MAPPER: {
|
|
|
60
87
|
[MESSAGE_MEDIA_TYPE.PHOTO]: string
|
|
61
88
|
[MESSAGE_MEDIA_TYPE.CONTACTS]: string
|
|
62
89
|
}
|
|
90
|
+
/**
|
|
91
|
+
* *
|
|
92
|
+
*/
|
|
93
|
+
export type UNIFIED_MESSAGE_MEDIA_TYPE = string
|
|
94
|
+
/**
|
|
95
|
+
* Unified message media types based on existing MESSAGE_MEDIA_TYPE and MESSAGE_TYPE.
|
|
96
|
+
*
|
|
97
|
+
* This enum flattens and merges all raw message media types
|
|
98
|
+
* into a single canonical type list.
|
|
99
|
+
*
|
|
100
|
+
* VOICE → AUDIO
|
|
101
|
+
* PHOTO → IMAGE
|
|
102
|
+
* CONTACTS → CONTACT
|
|
103
|
+
*
|
|
104
|
+
* @readonly
|
|
105
|
+
* @enum {string}
|
|
106
|
+
* @type {{ [key: string]: string }}
|
|
107
|
+
*/
|
|
108
|
+
export const UNIFIED_MESSAGE_MEDIA_TYPE: {
|
|
109
|
+
[key: string]: string
|
|
110
|
+
}
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
export function getTelegramApiUrls({
|
|
2
|
+
token,
|
|
3
|
+
telegramBaseUrl,
|
|
4
|
+
}: {
|
|
5
|
+
token: string
|
|
6
|
+
telegramBaseUrl?: string
|
|
7
|
+
}): TelegramApiUrls
|
|
8
|
+
export function telegramApis({ token }: { token: string }): TelegramApis
|
|
9
|
+
/**
|
|
10
|
+
* Builds a full set of Telegram Bot API endpoint URLs
|
|
11
|
+
* based on the provided bot token and an optional base URL.
|
|
12
|
+
*
|
|
13
|
+
* This helper centralizes all Telegram endpoints used by the system,
|
|
14
|
+
* making it easier to mock, override, or customize for testing environments.
|
|
15
|
+
*/
|
|
16
|
+
export type TelegramApiUrls = {
|
|
17
|
+
/**
|
|
18
|
+
* URL to send a text message to a chat using the Telegram Bot API.
|
|
19
|
+
*/
|
|
20
|
+
SEND_MESSAGE: string
|
|
21
|
+
/**
|
|
22
|
+
* URL to forward an existing message from one chat to another.
|
|
23
|
+
*/
|
|
24
|
+
FORWARD_MESSAGE: string
|
|
25
|
+
/**
|
|
26
|
+
* URL to send a photo to a chat.
|
|
27
|
+
*/
|
|
28
|
+
SEND_PHOTO: string
|
|
29
|
+
/**
|
|
30
|
+
* URL to send an audio file.
|
|
31
|
+
*/
|
|
32
|
+
SEND_AUDIO: string
|
|
33
|
+
/**
|
|
34
|
+
* URL to send files such as PDF, DOC, ZIP, and others supported by Telegram.
|
|
35
|
+
*/
|
|
36
|
+
SEND_DOCUMENT: string
|
|
37
|
+
/**
|
|
38
|
+
* URL to send a sticker.
|
|
39
|
+
*/
|
|
40
|
+
SEND_STICKER: string
|
|
41
|
+
/**
|
|
42
|
+
* URL to send a video file.
|
|
43
|
+
*/
|
|
44
|
+
SEND_VIDEO: string
|
|
45
|
+
/**
|
|
46
|
+
* URL to send a voice note.
|
|
47
|
+
*/
|
|
48
|
+
SEND_VOICE: string
|
|
49
|
+
/**
|
|
50
|
+
* URL to send a geolocation point.
|
|
51
|
+
*/
|
|
52
|
+
SEND_LOCATION: string
|
|
53
|
+
/**
|
|
54
|
+
* URL to send a chat action (typing, uploading photo, etc).
|
|
55
|
+
*/
|
|
56
|
+
SEND_CHAT_ACTION: string
|
|
57
|
+
/**
|
|
58
|
+
* URL to retrieve the profile photos of a specific user.
|
|
59
|
+
*/
|
|
60
|
+
GET_USER_PROFILE_PHOTOS: string
|
|
61
|
+
/**
|
|
62
|
+
* URL to poll for new updates (not used when using webhooks).
|
|
63
|
+
*/
|
|
64
|
+
GET_UPDATES: string
|
|
65
|
+
/**
|
|
66
|
+
* URL to fetch a file path for downloading a file uploaded to Telegram servers.
|
|
67
|
+
*/
|
|
68
|
+
GET_FILE: string
|
|
69
|
+
}
|
|
70
|
+
/**
|
|
71
|
+
* Factory that creates a set of high level Telegram Bot API helper methods.
|
|
72
|
+
*
|
|
73
|
+
* Each method sends a specific type of message (text, photo, video, document)
|
|
74
|
+
* through the Telegram Bot API using the provided bot token.
|
|
75
|
+
*
|
|
76
|
+
* This abstraction wraps the raw URL generation logic and HTTP calls,
|
|
77
|
+
* allowing higher level services to use clean method calls instead of
|
|
78
|
+
* managing endpoint URLs manually.
|
|
79
|
+
*/
|
|
80
|
+
export type TelegramApis = {
|
|
81
|
+
/**
|
|
82
|
+
* Sends a text message to a specific chat.
|
|
83
|
+
*/
|
|
84
|
+
sendMessage: Function
|
|
85
|
+
/**
|
|
86
|
+
* Sends a text message with an inline keyboard button group.
|
|
87
|
+
*/
|
|
88
|
+
sendButtonsGroup: Function
|
|
89
|
+
/**
|
|
90
|
+
* Sends a photo with an optional caption.
|
|
91
|
+
*/
|
|
92
|
+
sendPhoto: Function
|
|
93
|
+
/**
|
|
94
|
+
* Sends a video with an optional caption.
|
|
95
|
+
*/
|
|
96
|
+
sendVideo: Function
|
|
97
|
+
/**
|
|
98
|
+
* Sends an audio file with an optional caption.
|
|
99
|
+
*/
|
|
100
|
+
sendAudio: Function
|
|
101
|
+
/**
|
|
102
|
+
* Sends a document file with an optional caption.
|
|
103
|
+
*/
|
|
104
|
+
sendDocument: Function
|
|
105
|
+
}
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
export function getWhatsAppMediaInfo({
|
|
2
|
+
token,
|
|
3
|
+
mediaId,
|
|
4
|
+
version,
|
|
5
|
+
baseUrl,
|
|
6
|
+
}: {
|
|
7
|
+
mediaId: string
|
|
8
|
+
token: string
|
|
9
|
+
version?: string
|
|
10
|
+
}): Promise<any>
|
|
11
|
+
export function downloadWhatsAppMedia({
|
|
12
|
+
token,
|
|
13
|
+
mediaId,
|
|
14
|
+
mode,
|
|
15
|
+
}: {
|
|
16
|
+
mediaId: string
|
|
17
|
+
token: string
|
|
18
|
+
mode: 'buffer' | 'stream'
|
|
19
|
+
}): Promise<Buffer | ReadableStream>
|
|
20
|
+
export function getWhatsAppApiUrls({
|
|
21
|
+
phoneNumberId,
|
|
22
|
+
version,
|
|
23
|
+
baseUrl,
|
|
24
|
+
}: {
|
|
25
|
+
phoneNumberId: string
|
|
26
|
+
version?: string
|
|
27
|
+
baseUrl?: string
|
|
28
|
+
}): string
|
|
29
|
+
export function whatsappApis({
|
|
30
|
+
token,
|
|
31
|
+
phoneNumberId,
|
|
32
|
+
version,
|
|
33
|
+
}: {
|
|
34
|
+
token: string
|
|
35
|
+
phoneNumberId: string
|
|
36
|
+
version?: string
|
|
37
|
+
}): WhatsAppApis
|
|
38
|
+
/**
|
|
39
|
+
* Factory that creates WhatsApp Cloud API helper methods.
|
|
40
|
+
*
|
|
41
|
+
* This module wraps the WhatsApp Graph API endpoints and exposes
|
|
42
|
+
* high level functions for sending text messages, interactive buttons,
|
|
43
|
+
* images, videos, documents, and audio files.
|
|
44
|
+
*
|
|
45
|
+
* Each returned method builds the correct request format according
|
|
46
|
+
* to the WhatsApp Cloud API specification.
|
|
47
|
+
*/
|
|
48
|
+
export type WhatsAppApis = {
|
|
49
|
+
/**
|
|
50
|
+
* Sends a plain text message to an individual WhatsApp user.
|
|
51
|
+
*/
|
|
52
|
+
sendMessage: Function
|
|
53
|
+
/**
|
|
54
|
+
* Sends an interactive message containing buttons.
|
|
55
|
+
*/
|
|
56
|
+
sendButtonsGroup: Function
|
|
57
|
+
/**
|
|
58
|
+
* Sends an image message using a public URL.
|
|
59
|
+
*/
|
|
60
|
+
sendPhoto: Function
|
|
61
|
+
/**
|
|
62
|
+
* Sends a video file using a public URL.
|
|
63
|
+
*/
|
|
64
|
+
sendVideo: Function
|
|
65
|
+
/**
|
|
66
|
+
* Sends a document message using a public URL.
|
|
67
|
+
*/
|
|
68
|
+
sendDocument: Function
|
|
69
|
+
/**
|
|
70
|
+
* Sends an audio file using a public URL.
|
|
71
|
+
*/
|
|
72
|
+
sendAudio: Function
|
|
73
|
+
}
|