@warriorteam/messenger-sdk 1.3.0 → 1.4.1
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/README.md +182 -2
- package/dist/index.cjs +2 -2
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +217 -311
- package/dist/index.d.ts +217 -311
- package/dist/index.js +2 -2
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -5,11 +5,14 @@ A modern TypeScript SDK for the Facebook Messenger Platform API, designed with s
|
|
|
5
5
|
## Features
|
|
6
6
|
|
|
7
7
|
- 🚀 **Zero runtime dependencies** - Built with native fetch
|
|
8
|
-
- 📝 **Full TypeScript support** - Complete type definitions
|
|
8
|
+
- 📝 **Full TypeScript support** - Complete type definitions with discriminated unions
|
|
9
9
|
- 🔄 **Dual module support** - ESM and CommonJS
|
|
10
10
|
- ✅ **Comprehensive validation** - Built-in message and template validation
|
|
11
11
|
- 🛡️ **Error handling** - Detailed error types and messages
|
|
12
12
|
- 📚 **Complete API coverage** - Send API, Templates, Attachments, Moderation, Profile
|
|
13
|
+
- 🔐 **Webhook utilities** - Complete webhook type system and signature verification
|
|
14
|
+
- 🎯 **Token override** - Per-method access token override support
|
|
15
|
+
- 🔧 **Type-safe webhooks** - Discriminated unions for proper TypeScript narrowing
|
|
13
16
|
|
|
14
17
|
## Installation
|
|
15
18
|
|
|
@@ -47,7 +50,7 @@ console.log('Message sent:', result.message_id);
|
|
|
47
50
|
|
|
48
51
|
```typescript
|
|
49
52
|
const messenger = new Messenger({
|
|
50
|
-
accessToken
|
|
53
|
+
accessToken?: string; // Optional: Default page access token
|
|
51
54
|
version?: string; // Optional: API version (default: 'v23.0')
|
|
52
55
|
baseUrl?: string; // Optional: Custom base URL
|
|
53
56
|
timeout?: number; // Optional: Request timeout in ms (default: 30000)
|
|
@@ -55,6 +58,35 @@ const messenger = new Messenger({
|
|
|
55
58
|
});
|
|
56
59
|
```
|
|
57
60
|
|
|
61
|
+
### Token Override Support
|
|
62
|
+
|
|
63
|
+
Every API method supports per-call access token override, perfect for multi-tenant applications:
|
|
64
|
+
|
|
65
|
+
```typescript
|
|
66
|
+
const messenger = new Messenger({
|
|
67
|
+
accessToken: 'default_page_token'
|
|
68
|
+
});
|
|
69
|
+
|
|
70
|
+
// Use default token
|
|
71
|
+
await messenger.send.message({
|
|
72
|
+
recipient: { id: 'USER_PSID' },
|
|
73
|
+
message: { text: 'Hello from default page!' }
|
|
74
|
+
});
|
|
75
|
+
|
|
76
|
+
// Override token for this specific call
|
|
77
|
+
await messenger.send.message({
|
|
78
|
+
recipient: { id: 'USER_PSID' },
|
|
79
|
+
message: { text: 'Hello from different page!' }
|
|
80
|
+
}, {
|
|
81
|
+
accessToken: 'other_page_token'
|
|
82
|
+
});
|
|
83
|
+
|
|
84
|
+
// Works with all API methods
|
|
85
|
+
const profile = await messenger.profile.getBasic('USER_PSID', {
|
|
86
|
+
accessToken: 'specific_token'
|
|
87
|
+
});
|
|
88
|
+
```
|
|
89
|
+
|
|
58
90
|
### Send API
|
|
59
91
|
|
|
60
92
|
#### Send Text Message
|
|
@@ -240,6 +272,151 @@ await messenger.send.message({
|
|
|
240
272
|
|
|
241
273
|
**Note**: Profile API requires "Advanced User Profile Access" feature and user interaction to grant permissions.
|
|
242
274
|
|
|
275
|
+
## Webhook Support
|
|
276
|
+
|
|
277
|
+
The SDK provides comprehensive webhook support with full TypeScript safety through discriminated unions.
|
|
278
|
+
|
|
279
|
+
### Webhook Types and Processing
|
|
280
|
+
|
|
281
|
+
```typescript
|
|
282
|
+
import {
|
|
283
|
+
processWebhookEvents,
|
|
284
|
+
extractWebhookEvents,
|
|
285
|
+
getWebhookEventType,
|
|
286
|
+
getWebhookPayloadEventTypes,
|
|
287
|
+
WebhookEventType,
|
|
288
|
+
GenericWebhookPayload
|
|
289
|
+
} from '@warriorteam/messenger-sdk';
|
|
290
|
+
|
|
291
|
+
// Process webhook with type-safe handlers
|
|
292
|
+
app.post('/webhook', express.json(), async (req, res) => {
|
|
293
|
+
const payload: GenericWebhookPayload = req.body;
|
|
294
|
+
|
|
295
|
+
await processWebhookEvents(payload, {
|
|
296
|
+
onMessage: async (event) => {
|
|
297
|
+
// TypeScript knows this is MessageWebhookEvent
|
|
298
|
+
console.log(`Received message: ${event.message.text}`);
|
|
299
|
+
},
|
|
300
|
+
onMessageEdit: async (event) => {
|
|
301
|
+
// TypeScript knows this is MessageEditWebhookEvent
|
|
302
|
+
console.log(`Message edited to: ${event.message_edit.text}`);
|
|
303
|
+
},
|
|
304
|
+
onMessageReaction: async (event) => {
|
|
305
|
+
// TypeScript knows this is MessageReactionWebhookEvent
|
|
306
|
+
console.log(`Reaction: ${event.reaction.reaction}`);
|
|
307
|
+
},
|
|
308
|
+
onMessagingPostback: async (event) => {
|
|
309
|
+
// TypeScript knows this is MessagingPostbackWebhookEvent
|
|
310
|
+
console.log(`Postback: ${event.postback.payload}`);
|
|
311
|
+
}
|
|
312
|
+
});
|
|
313
|
+
|
|
314
|
+
res.sendStatus(200);
|
|
315
|
+
});
|
|
316
|
+
```
|
|
317
|
+
|
|
318
|
+
### Manual Event Processing
|
|
319
|
+
|
|
320
|
+
```typescript
|
|
321
|
+
// Extract events manually
|
|
322
|
+
const events = extractWebhookEvents(payload);
|
|
323
|
+
for (const event of events) {
|
|
324
|
+
const eventType = getWebhookEventType(event);
|
|
325
|
+
|
|
326
|
+
switch (eventType) {
|
|
327
|
+
case WebhookEventType.MESSAGE:
|
|
328
|
+
// Handle message event
|
|
329
|
+
break;
|
|
330
|
+
case WebhookEventType.MESSAGE_EDIT:
|
|
331
|
+
// Handle edit event
|
|
332
|
+
break;
|
|
333
|
+
// ... other cases
|
|
334
|
+
}
|
|
335
|
+
}
|
|
336
|
+
|
|
337
|
+
// Check what event types are in the payload
|
|
338
|
+
const eventTypes = getWebhookPayloadEventTypes(payload);
|
|
339
|
+
console.log('Received event types:', eventTypes);
|
|
340
|
+
```
|
|
341
|
+
|
|
342
|
+
### Webhook Verification
|
|
343
|
+
|
|
344
|
+
The SDK provides utilities for both subscription verification and signature validation:
|
|
345
|
+
|
|
346
|
+
```typescript
|
|
347
|
+
import {
|
|
348
|
+
verifyWebhookSubscription,
|
|
349
|
+
verifyWebhookSignature
|
|
350
|
+
} from '@warriorteam/messenger-sdk';
|
|
351
|
+
|
|
352
|
+
// Subscription verification (GET request)
|
|
353
|
+
app.get('/webhook', (req, res) => {
|
|
354
|
+
const challenge = verifyWebhookSubscription(
|
|
355
|
+
req.query as any,
|
|
356
|
+
process.env.VERIFY_TOKEN!
|
|
357
|
+
);
|
|
358
|
+
|
|
359
|
+
if (challenge) {
|
|
360
|
+
res.send(challenge);
|
|
361
|
+
} else {
|
|
362
|
+
res.status(403).send('Forbidden');
|
|
363
|
+
}
|
|
364
|
+
});
|
|
365
|
+
|
|
366
|
+
// Signature verification (POST request)
|
|
367
|
+
app.post('/webhook', express.raw({type: 'application/json'}), async (req, res) => {
|
|
368
|
+
const signature = req.get('X-Hub-Signature-256');
|
|
369
|
+
const result = await verifyWebhookSignature(
|
|
370
|
+
req.body,
|
|
371
|
+
signature,
|
|
372
|
+
process.env.APP_SECRET!
|
|
373
|
+
);
|
|
374
|
+
|
|
375
|
+
if (!result.isValid) {
|
|
376
|
+
return res.status(401).json({error: result.error});
|
|
377
|
+
}
|
|
378
|
+
|
|
379
|
+
// Process webhook events...
|
|
380
|
+
const payload = JSON.parse(req.body.toString());
|
|
381
|
+
// ... handle events
|
|
382
|
+
});
|
|
383
|
+
```
|
|
384
|
+
|
|
385
|
+
### Type-Safe Event Handling
|
|
386
|
+
|
|
387
|
+
The SDK uses discriminated unions for perfect TypeScript support:
|
|
388
|
+
|
|
389
|
+
```typescript
|
|
390
|
+
import {
|
|
391
|
+
MessengerWebhookEvent,
|
|
392
|
+
isMessageEvent,
|
|
393
|
+
isMessageEditEvent,
|
|
394
|
+
isMessagingPostbackEvent
|
|
395
|
+
} from '@warriorteam/messenger-sdk';
|
|
396
|
+
|
|
397
|
+
function handleWebhookEvent(event: MessengerWebhookEvent) {
|
|
398
|
+
if (isMessageEvent(event)) {
|
|
399
|
+
// TypeScript knows event.message exists
|
|
400
|
+
console.log(`Message: ${event.message.text}`);
|
|
401
|
+
} else if (isMessageEditEvent(event)) {
|
|
402
|
+
// TypeScript knows event.message_edit exists
|
|
403
|
+
console.log(`Edit: ${event.message_edit.text}`);
|
|
404
|
+
} else if (isMessagingPostbackEvent(event)) {
|
|
405
|
+
// TypeScript knows event.postback exists
|
|
406
|
+
console.log(`Postback: ${event.postback.payload}`);
|
|
407
|
+
}
|
|
408
|
+
}
|
|
409
|
+
```
|
|
410
|
+
|
|
411
|
+
### Supported Webhook Event Types
|
|
412
|
+
|
|
413
|
+
- `MESSAGE` - User sends a message
|
|
414
|
+
- `MESSAGE_EDIT` - User edits a sent message
|
|
415
|
+
- `MESSAGE_REACTION` - User reacts to a message
|
|
416
|
+
- `MESSAGE_READ` - User reads messages (read receipts)
|
|
417
|
+
- `MESSAGING_FEEDBACK` - User submits feedback via templates
|
|
418
|
+
- `MESSAGING_POSTBACK` - User clicks buttons/quick replies
|
|
419
|
+
|
|
243
420
|
## Error Handling
|
|
244
421
|
|
|
245
422
|
The SDK provides specific error types for different scenarios:
|
|
@@ -277,6 +454,9 @@ Check the `examples/` directory for complete usage examples:
|
|
|
277
454
|
- `send-template.ts` - Template messages
|
|
278
455
|
- `user-profile.ts` - Profile API usage
|
|
279
456
|
- `moderation.ts` - User moderation
|
|
457
|
+
- `webhook-handler.ts` - Complete webhook setup with type safety
|
|
458
|
+
- `multi-tenant.ts` - Token override for multi-tenant applications
|
|
459
|
+
- `signature-verification.ts` - Webhook security implementation
|
|
280
460
|
|
|
281
461
|
## Development
|
|
282
462
|
|
package/dist/index.cjs
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
'use strict';var F="v23.0",L="https://graph.facebook.com";var c={MESSAGES:"/me/messages",MESSAGE_ATTACHMENTS:"/me/message_attachments",MODERATE_CONVERSATIONS:"/me/moderate_conversations"},k={TEXT_MESSAGE_MAX_CHARS:2e3},se={IMAGE_MAX_SIZE:8*1024*1024,OTHER_MAX_SIZE:25*1024*1024,VIDEO_TIMEOUT:75,OTHER_TIMEOUT:10},i={GENERIC_ELEMENTS_MAX:10,GENERIC_TITLE_MAX_CHARS:80,GENERIC_SUBTITLE_MAX_CHARS:80,BUTTON_TEXT_MAX_CHARS:640,BUTTONS_MAX_COUNT:3,BUTTON_TITLE_MAX_CHARS:20,POSTBACK_PAYLOAD_MAX_CHARS:1e3,MEDIA_ELEMENTS_COUNT:1,MEDIA_BUTTONS_MAX_COUNT:3};var l=class extends Error{code;type;subcode;fbtrace_id;statusCode;response;constructor(e,s,a){super(e.message),this.name="MessengerAPIError",this.code=e.code,this.type=e.type,this.subcode=e.error_subcode,this.fbtrace_id=e.fbtrace_id,this.statusCode=s,this.response=a;}},T=class extends Error{cause;constructor(e,s){super(e),this.name="MessengerNetworkError",this.cause=s;}},u=class extends Error{timeout;constructor(e){super(`Request timed out after ${e}ms`),this.name="MessengerTimeoutError",this.timeout=e;}},d=class extends Error{constructor(e){super(e),this.name="MessengerConfigError";}};var S=class{config;constructor(e){this.config={accessToken:e.accessToken,version:e.version,baseUrl:e.baseUrl||L,timeout:e.timeout||3e4,maxRetries:e.maxRetries||3};}async request(e){let s=this.buildUrl(e.path,e.query,e.accessToken),a;for(let o=0;o<=this.config.maxRetries;o++)try{let r=await this.makeRequest(s,e);return await this.handleResponse(r)}catch(r){if(a=r,r instanceof l&&r.statusCode>=400&&r.statusCode<500||o===this.config.maxRetries)throw r;await this.delay(1e3*(o+1));}throw a||new Error("Unknown error occurred")}buildUrl(e,s,a){let o=new URL(`${this.config.baseUrl}/${this.config.version}${e}`),r=a||this.config.accessToken;if(!r)throw new Error("Access token is required. Provide it in constructor or method options.");return o.searchParams.append("access_token",r),s&&Object.entries(s).forEach(([p,g])=>{o.searchParams.append(p,String(g));}),o.toString()}async makeRequest(e,s){let a=new AbortController,o=setTimeout(()=>a.abort(),this.config.timeout);try{let r={method:s.method,headers:{"Content-Type":"application/json"},signal:a.signal};return s.body&&(r.body=JSON.stringify(s.body)),await fetch(e,r)}catch(r){throw r instanceof Error?r.name==="AbortError"?new u(this.config.timeout):new T(`Network request failed: ${r.message}`,r):r}finally{clearTimeout(o);}}async handleResponse(e){let a=e.headers.get("content-type")?.includes("application/json");if(!e.ok)if(a){let o=await e.json();throw new l(o.error,e.status,o)}else {let o=await e.text();throw new l({message:o||`HTTP ${e.status} ${e.statusText}`,type:"http_error",code:e.status,fbtrace_id:""},e.status,o)}return a?await e.json():await e.text()}delay(e){return new Promise(s=>setTimeout(s,e))}};var b=class extends Error{constructor(e){super(e),this.name="MessageValidationError";}};function H(t){if(!t||t.trim()==="")throw new b("Text message cannot be empty");if(t.length>k.TEXT_MESSAGE_MAX_CHARS)throw new b(`Text message cannot exceed ${k.TEXT_MESSAGE_MAX_CHARS} characters`)}var M=class{constructor(e){this.httpClient=e;}async message(e,s){return e.message?.text&&H(e.message.text),this.httpClient.request({method:"POST",path:c.MESSAGES,body:e,accessToken:s?.accessToken})}async action(e,s,a){return this.httpClient.request({method:"POST",path:c.MESSAGES,body:{recipient:{id:e},messaging_type:"RESPONSE",sender_action:s},accessToken:a?.accessToken})}async typingOn(e,s){return this.action(e,"typing_on",s)}async typingOff(e,s){return this.action(e,"typing_off",s)}async markSeen(e,s){return this.action(e,"mark_seen",s)}async attachment(e,s){return this.message({recipient:e.recipient,messaging_type:e.messaging_type??"RESPONSE",message:{attachment:{type:e.type,payload:{attachment_id:e.attachment_id}}}},s)}async attachmentFromUrl(e,s){return this.message({recipient:e.recipient,messaging_type:e.messaging_type??"RESPONSE",message:{attachment:{type:e.type,payload:{url:e.url}}}},s)}};var y=class{constructor(e){this.httpClient=e;}async upload(e,s){let a={message:{attachment:{type:e.type,payload:{url:e.url,is_reusable:e.is_reusable??true}}}};return this.httpClient.request({method:"POST",path:c.MESSAGE_ATTACHMENTS,body:a,accessToken:s?.accessToken})}};var f=class{constructor(e){this.httpClient=e;}async moderate(e,s){return this.httpClient.request({method:"POST",path:c.MODERATE_CONVERSATIONS,body:e,accessToken:s?.accessToken})}async blockUser(e,s){let a=Array.isArray(e)?e.map(o=>({id:o})):[{id:e}];return this.moderate({user_ids:a,actions:["block_user"]},s)}async unblockUser(e,s){let a=Array.isArray(e)?e.map(o=>({id:o})):[{id:e}];return this.moderate({user_ids:a,actions:["unblock_user"]},s)}async banUser(e,s){let a=Array.isArray(e)?e.map(o=>({id:o})):[{id:e}];return this.moderate({user_ids:a,actions:["ban_user"]},s)}async unbanUser(e,s){let a=Array.isArray(e)?e.map(o=>({id:o})):[{id:e}];return this.moderate({user_ids:a,actions:["unban_user"]},s)}async moveToSpam(e,s){let a=Array.isArray(e)?e.map(o=>({id:o})):[{id:e}];return this.moderate({user_ids:a,actions:["move_to_spam"]},s)}async blockAndSpam(e,s){let a=Array.isArray(e)?e.map(o=>({id:o})):[{id:e}];return this.moderate({user_ids:a,actions:["block_user","move_to_spam"]},s)}};var n=class extends Error{constructor(e){super(e),this.name="TemplateValidationError";}};function B(t){if(t.length===0)throw new n("Generic template must have at least 1 element");if(t.length>i.GENERIC_ELEMENTS_MAX)throw new n(`Generic template cannot have more than ${i.GENERIC_ELEMENTS_MAX} elements`);t.forEach((e,s)=>{re(e,s);});}function re(t,e){if(!t.title||t.title.trim()==="")throw new n(`Element ${e}: title is required`);if(t.title.length>i.GENERIC_TITLE_MAX_CHARS)throw new n(`Element ${e}: title cannot exceed ${i.GENERIC_TITLE_MAX_CHARS} characters`);if(t.subtitle&&t.subtitle.length>i.GENERIC_SUBTITLE_MAX_CHARS)throw new n(`Element ${e}: subtitle cannot exceed ${i.GENERIC_SUBTITLE_MAX_CHARS} characters`);if(t.image_url&&!h(t.image_url))throw new n(`Element ${e}: image_url must be HTTPS`);if(t.buttons&&R(t.buttons,`Element ${e}`),!!!(t.subtitle||t.image_url||t.default_action||t.buttons&&t.buttons.length>0))throw new n(`Element ${e}: must have at least one additional property beyond title`)}function X(t,e){if(!t||t.trim()==="")throw new n("Button template text is required");if(t.length>i.BUTTON_TEXT_MAX_CHARS)throw new n(`Button template text cannot exceed ${i.BUTTON_TEXT_MAX_CHARS} characters`);if(e.length===0)throw new n("Button template must have at least 1 button");R(e,"Button template");}function q(t){if(!t.media_type)throw new n("Media template element must have media_type");if(!t.url&&!t.attachment_id)throw new n("Media template element must have either url or attachment_id");if(t.url&&t.attachment_id)throw new n("Media template element cannot have both url and attachment_id");if(t.url&&!h(t.url))throw new n("Media template url must be HTTPS");if(t.buttons){if(t.buttons.length>i.MEDIA_BUTTONS_MAX_COUNT)throw new n(`Media template cannot have more than ${i.MEDIA_BUTTONS_MAX_COUNT} buttons`);R(t.buttons,"Media template");}}function R(t,e){if(t.length>i.BUTTONS_MAX_COUNT)throw new n(`${e} cannot have more than ${i.BUTTONS_MAX_COUNT} buttons`);t.forEach((s,a)=>{ie(s,`${e} button ${a}`);});}function ie(t,e){if(!t.type)throw new n(`${e}: type is required`);if(t.type!=="account_unlink"&&(!t.title||t.title.trim()===""))throw new n(`${e}: title is required for ${t.type} buttons`);if(t.title&&t.title.length>i.BUTTON_TITLE_MAX_CHARS)throw new n(`${e}: title cannot exceed ${i.BUTTON_TITLE_MAX_CHARS} characters`);switch(t.type){case "web_url":if(!t.url)throw new n(`${e}: url is required for web_url buttons`);if(!h(t.url))throw new n(`${e}: url must be HTTPS for web_url buttons`);break;case "postback":if(!t.payload)throw new n(`${e}: payload is required for postback buttons`);if(t.payload.length>i.POSTBACK_PAYLOAD_MAX_CHARS)throw new n(`${e}: payload cannot exceed ${i.POSTBACK_PAYLOAD_MAX_CHARS} characters`);break;case "phone_number":if(!t.payload)throw new n(`${e}: payload is required for phone_number buttons`);if(!t.payload.startsWith("+"))throw new n(`${e}: phone_number payload must start with + (e.g., +1234567890)`);break;case "game_play":break;case "account_link":if(!t.url)throw new n(`${e}: url is required for account_link buttons`);if(!h(t.url))throw new n(`${e}: url must be HTTPS for account_link buttons`);break;}if(t.type==="web_url"&&t.messenger_extensions&&t.fallback_url&&!h(t.fallback_url))throw new n(`${e}: fallback_url must be HTTPS`)}function h(t){try{return new URL(t).protocol==="https:"}catch{return false}}var _=class{constructor(e){this.httpClient=e;}async generic(e,s){B(e.elements);let a={template_type:"generic",elements:e.elements,image_aspect_ratio:e.image_aspect_ratio},o={recipient:e.recipient,messaging_type:e.messaging_type||"UPDATE",message:{attachment:{type:"template",payload:a}},notification_type:e.notification_type,tag:e.tag};return this.httpClient.request({method:"POST",path:c.MESSAGES,body:o,accessToken:s?.accessToken})}async button(e,s){X(e.text,e.buttons);let a={template_type:"button",text:e.text,buttons:e.buttons},o={recipient:e.recipient,messaging_type:e.messaging_type||"UPDATE",message:{attachment:{type:"template",payload:a}},notification_type:e.notification_type,tag:e.tag};return this.httpClient.request({method:"POST",path:c.MESSAGES,body:o,accessToken:s?.accessToken})}async media(e,s){q(e.element);let a={template_type:"media",elements:[e.element]},o={recipient:e.recipient,messaging_type:e.messaging_type||"UPDATE",message:{attachment:{type:"template",payload:a}},notification_type:e.notification_type,tag:e.tag};return this.httpClient.request({method:"POST",path:c.MESSAGES,body:o,accessToken:s?.accessToken})}async product(e,s){let a={template_type:"product",elements:e.elements},o={recipient:e.recipient,messaging_type:e.messaging_type||"UPDATE",message:{attachment:{type:"template",payload:a}},notification_type:e.notification_type,tag:e.tag};return this.httpClient.request({method:"POST",path:c.MESSAGES,body:o,accessToken:s?.accessToken})}};var A=class{constructor(e){this.httpClient=e;}async get(e,s){let{psid:a,fields:o=["first_name","last_name"]}=e,r=new URLSearchParams({fields:o.join(",")});return this.httpClient.request({method:"GET",path:`/${a}?${r.toString()}`,body:void 0,accessToken:s?.accessToken})}async getBasic(e,s){return this.get({psid:e,fields:["first_name","last_name","profile_pic"]},s)}async getFull(e,s){return this.get({psid:e,fields:["id","name","first_name","last_name","profile_pic","locale","timezone","gender"]},s)}async getName(e,s){return this.get({psid:e,fields:["first_name","last_name"]},s)}async getProfilePicture(e,s){return this.get({psid:e,fields:["profile_pic"]},s)}};var x=class{send;attachments;moderation;templates;profile;httpClient;constructor(e={}){this.validateConfig(e);let s={accessToken:e.accessToken,version:e.version||F,baseUrl:e.baseUrl,timeout:e.timeout,maxRetries:e.maxRetries};this.httpClient=new S(s),this.send=new M(this.httpClient),this.attachments=new y(this.httpClient),this.moderation=new f(this.httpClient),this.templates=new _(this.httpClient),this.profile=new A(this.httpClient);}validateConfig(e){if(e.accessToken!==void 0&&(typeof e.accessToken!="string"||e.accessToken.trim()===""))throw new d("Access token must be a non-empty string");if(e.version&&typeof e.version!="string")throw new d("API version must be a string");if(e.timeout&&(typeof e.timeout!="number"||e.timeout<=0))throw new d("Timeout must be a positive number");if(e.maxRetries&&(typeof e.maxRetries!="number"||e.maxRetries<0))throw new d("Max retries must be a non-negative number")}};function ce(t){return t&&typeof t=="object"&&"message_edit"in t}function pe(t){return {messageId:t.message_edit.mid,senderId:t.sender.id,recipientId:t.recipient.id,updatedText:t.message_edit.text,editCount:t.message_edit.num_edit,editTimestamp:t.timestamp}}var ge={MAX_EDITS:5,EVENT_TYPE:"message_edit"};var C=(m=>(m.LIKE="like",m.DISLIKE="dislike",m.LOVE="love",m.SAD="sad",m.ANGRY="angry",m.WOW="wow",m.SMILE="smile",m.OTHER="other",m))(C||{}),I=(s=>(s.REACT="react",s.UNREACT="unreact",s))(I||{});function me(t){return t&&typeof t=="object"&&"read"in t}function de(t){return {senderId:t.sender.id,recipientId:t.recipient.id,watermarkTimestamp:t.read.watermark,readTimestamp:t.timestamp,watermarkDate:new Date(t.read.watermark),readDate:new Date(t.timestamp)}}function j(t,e){return t<=e}function $(t,e){return t.filter(s=>j(s.timestamp,e))}function le(t,e){return $(t,e).length}var Ee={EVENT_TYPE:"message_reads",READ_PROPERTY:"read"};function Te(t){return t&&typeof t=="object"&&"postback"in t}function K(t){return t.postback&&"referral"in t.postback&&t.postback.referral!=null}function V(t){return t&&typeof t.id=="string"&&t.id.length>0}function ue(t){let e=K(t),s=V(t.sender);return {payload:t.postback.payload,senderId:t.sender.id,userRef:t.sender.user_ref,recipientId:t.recipient.id,buttonTitle:t.postback.title,messageId:t.postback.mid,timestamp:t.timestamp,referralContext:e?{ref:t.postback.referral.ref,source:t.postback.referral.source,type:t.postback.referral.type}:void 0,isReferred:e,isIdentifiedUser:s}}var be={GET_STARTED:"GET_STARTED",MAIN_MENU:"MAIN_MENU",HELP:"HELP",SUPPORT:"SUPPORT",CONTACT:"CONTACT",CONTACT_SALES:"CONTACT_SALES",CONTACT_SUPPORT:"CONTACT_SUPPORT",BACK:"BACK",NEXT:"NEXT",CANCEL:"CANCEL",SETTINGS:"SETTINGS",PREFERENCES:"PREFERENCES"},Me={MAX_PAYLOAD_LENGTH:1e3,EVENT_TYPE:"postback",REFERRAL_SOURCES:{SHORTLINK:"SHORTLINK",ADS:"ADS",MESSENGER_CODE:"MESSENGER_CODE"},REFERRAL_TYPES:{OPEN_THREAD:"OPEN_THREAD"}};var O=(a=>(a.CSAT="csat",a.NPS="nps",a.CES="ces",a))(O||{}),N=(a=>(a.ONE_TO_FIVE="one_to_five",a.FIVE_STARS="five_stars",a.FIVE_EMOJIS="five_emojis",a))(N||{}),v=(e=>(e.ZERO_TO_TEN="zero_to_ten",e))(v||{}),w=(e=>(e.ONE_TO_SEVEN="one_to_seven",e))(w||{}),W=(e=>(e.FREE_FORM="free_form",e))(W||{});function ye(t){return t&&typeof t=="object"&&"messaging_feedback"in t}function fe(t){let e=[];return t.messaging_feedback.feedback_screens.forEach(s=>{Object.entries(s.questions).forEach(([a,o])=>{e.push({questionId:a,feedbackType:o.type,score:parseInt(o.payload,10),textFeedback:o.follow_up?.payload,screenId:s.screen_id});});}),{senderId:t.sender.id,recipientId:t.recipient.id,submissionTimestamp:t.timestamp,screenCount:t.messaging_feedback.feedback_screens.length,allResponses:e}}function he(t){let e=new Map;return t.messaging_feedback.feedback_screens.forEach(s=>{Object.values(s.questions).forEach(a=>{let o=parseInt(a.payload,10),r=e.get(a.type)||[];e.set(a.type,[...r,o]);});}),e}function _e(t){let e=[];return t.messaging_feedback.feedback_screens.forEach(s=>{Object.values(s.questions).forEach(a=>{a.follow_up?.payload&&e.push(a.follow_up.payload);});}),e}var E={MAX_TEXT_FEEDBACK_LENGTH:400,SCORE_RANGES:{csat:{min:1,max:5},nps:{min:0,max:10},ces:{min:1,max:7}},TEMPLATE_EXPIRY:{MIN_DAYS:1,MAX_DAYS:7,DEFAULT_DAYS:1},QUESTION_ID:{MAX_LENGTH:80,VALID_PATTERN:/^[a-zA-Z0-9_]+$/},TEMPLATE_LIMITS:{MAX_TITLES:1,MAX_SCORING_COMPONENTS:1},EVENT_TYPE:"messaging_feedback"};function Ae(t,e){let s=E.SCORE_RANGES[t];return Number.isInteger(e)&&e>=s.min&&e<=s.max}function ke(t){return t.length<=E.QUESTION_ID.MAX_LENGTH&&E.QUESTION_ID.VALID_PATTERN.test(t)}function Se(t){return t.length<=E.MAX_TEXT_FEEDBACK_LENGTH}var D=(g=>(g.AUDIO="audio",g.FILE="file",g.IMAGE="image",g.VIDEO="video",g.FALLBACK="fallback",g.REEL="reel",g.IG_REEL="ig_reel",g))(D||{}),U=(a=>(a.OPEN_THREAD="OPEN_THREAD",a.PRODUCT="product",a.ADS="ads",a))(U||{}),G=(r=>(r.MESSENGER_CODE="MESSENGER_CODE",r.DISCOVER_TAB="DISCOVER_TAB",r.ADS="ADS",r.SHORTLINK="SHORTLINK",r.CUSTOMER_CHAT_PLUGIN="CUSTOMER_CHAT_PLUGIN",r))(G||{});function Pe(t){return t&&typeof t=="object"&&"message"in t}function Re(t){return typeof t.text=="string"&&t.text.length>0}function P(t){return Array.isArray(t.attachments)&&t.attachments.length>0}function Y(t){return t.quick_reply!==void 0}function Q(t){return t.reply_to!==void 0}function z(t){return t.referral!==void 0}function Z(t,e){return t.type===e}function xe(t){let{message:e}=t;return {messageId:e.mid,senderId:t.sender.id,recipientId:t.recipient.id,text:e.text,hasAttachments:P(e),isQuickReply:Y(e),isReply:Q(e),hasReferral:z(e),timestamp:t.timestamp,quickReplyPayload:e.quick_reply?.payload,repliedToMessageId:e.reply_to?.mid}}function Ce(t,e){return P(t)?t.attachments.filter(s=>Z(s,e)):[]}function Ie(t){return P(t)?t.attachments.map(e=>e.payload.url):[]}var Oe={MAX_TEXT_LENGTH:2e3,MAX_QUICK_REPLY_PAYLOAD_LENGTH:1e3,MAX_REFERRAL_REF_LENGTH:250,EVENT_TYPE:"message"},Ne={image:["image/jpeg","image/png","image/gif","image/webp"],video:["video/mp4","video/avi","video/quicktime","video/webm"],audio:["audio/mpeg","audio/mp4","audio/wav","audio/ogg"],file:["application/pdf","application/msword","application/vnd.openxmlformats-officedocument.wordprocessingml.document","text/plain"]};var J=(p=>(p.MESSAGE="message",p.MESSAGE_EDIT="message_edit",p.MESSAGE_REACTION="reaction",p.MESSAGE_READ="read",p.MESSAGING_FEEDBACK="messaging_feedback",p.MESSAGING_POSTBACK="postback",p))(J||{});function ee(t){return "message"in t&&!("message_edit"in t)?"message":"message_edit"in t?"message_edit":"reaction"in t?"reaction":"read"in t?"read":"messaging_feedback"in t?"messaging_feedback":"postback"in t?"postback":null}function te(t){let e=[];if(t.object==="page"&&Array.isArray(t.entry))for(let s of t.entry)Array.isArray(s.messaging)&&e.push(...s.messaging);return e}async function ve(t,e){let s=te(t);for(let a of s)switch(ee(a)){case "message":e.onMessage&&await e.onMessage(a);break;case "message_edit":e.onMessageEdit&&await e.onMessageEdit(a);break;case "reaction":e.onMessageReaction&&await e.onMessageReaction(a);break;case "read":e.onMessageRead&&await e.onMessageRead(a);break;case "messaging_feedback":e.onMessagingFeedback&&await e.onMessagingFeedback(a);break;case "postback":e.onMessagingPostback&&await e.onMessagingPostback(a);break;default:e.onUnknown&&await e.onUnknown(a);break}}function we(t,e){return t["hub.mode"]==="subscribe"&&t["hub.verify_token"]===e?t["hub.challenge"]:null}
|
|
2
|
-
exports.ATTACHMENT_LIMITS=
|
|
1
|
+
'use strict';var q="v23.0",X="https://graph.facebook.com";var c={MESSAGES:"/me/messages",MESSAGE_ATTACHMENTS:"/me/message_attachments",MODERATE_CONVERSATIONS:"/me/moderate_conversations"},_={TEXT_MESSAGE_MAX_CHARS:2e3},re={IMAGE_MAX_SIZE:8*1024*1024,OTHER_MAX_SIZE:25*1024*1024,VIDEO_TIMEOUT:75,OTHER_TIMEOUT:10},i={GENERIC_ELEMENTS_MAX:10,GENERIC_TITLE_MAX_CHARS:80,GENERIC_SUBTITLE_MAX_CHARS:80,BUTTON_TEXT_MAX_CHARS:640,BUTTONS_MAX_COUNT:3,BUTTON_TITLE_MAX_CHARS:20,POSTBACK_PAYLOAD_MAX_CHARS:1e3,MEDIA_ELEMENTS_COUNT:1,MEDIA_BUTTONS_MAX_COUNT:3};var l=class extends Error{code;type;subcode;fbtrace_id;statusCode;response;constructor(e,s,o){super(e.message),this.name="MessengerAPIError",this.code=e.code,this.type=e.type,this.subcode=e.error_subcode,this.fbtrace_id=e.fbtrace_id,this.statusCode=s,this.response=o;}},b=class extends Error{cause;constructor(e,s){super(e),this.name="MessengerNetworkError",this.cause=s;}},h=class extends Error{timeout;constructor(e){super(`Request timed out after ${e}ms`),this.name="MessengerTimeoutError",this.timeout=e;}},m=class extends Error{constructor(e){super(e),this.name="MessengerConfigError";}};var P=class{config;constructor(e){this.config={accessToken:e.accessToken,version:e.version,baseUrl:e.baseUrl||X,timeout:e.timeout||3e4,maxRetries:e.maxRetries||3};}async request(e){let s=this.buildUrl(e.path,e.query,e.accessToken),o;for(let a=0;a<=this.config.maxRetries;a++)try{let n=await this.makeRequest(s,e);return await this.handleResponse(n)}catch(n){if(o=n,n instanceof l&&n.statusCode>=400&&n.statusCode<500||a===this.config.maxRetries)throw n;await this.delay(1e3*(a+1));}throw o||new Error("Unknown error occurred")}buildUrl(e,s,o){let a=new URL(`${this.config.baseUrl}/${this.config.version}${e}`),n=o||this.config.accessToken;if(!n)throw new Error("Access token is required. Provide it in constructor or method options.");return a.searchParams.append("access_token",n),s&&Object.entries(s).forEach(([p,g])=>{a.searchParams.append(p,String(g));}),a.toString()}async makeRequest(e,s){let o=new AbortController,a=setTimeout(()=>o.abort(),this.config.timeout);try{let n={method:s.method,headers:{"Content-Type":"application/json"},signal:o.signal};return s.body&&(n.body=JSON.stringify(s.body)),await fetch(e,n)}catch(n){throw n instanceof Error?n.name==="AbortError"?new h(this.config.timeout):new b(`Network request failed: ${n.message}`,n):n}finally{clearTimeout(a);}}async handleResponse(e){let o=e.headers.get("content-type")?.includes("application/json");if(!e.ok)if(o){let a=await e.json();throw new l(a.error,e.status,a)}else {let a=await e.text();throw new l({message:a||`HTTP ${e.status} ${e.statusText}`,type:"http_error",code:e.status,fbtrace_id:""},e.status,a)}return o?await e.json():await e.text()}delay(e){return new Promise(s=>setTimeout(s,e))}};var u=class extends Error{constructor(e){super(e),this.name="MessageValidationError";}};function j(t){if(!t||t.trim()==="")throw new u("Text message cannot be empty");if(t.length>_.TEXT_MESSAGE_MAX_CHARS)throw new u(`Text message cannot exceed ${_.TEXT_MESSAGE_MAX_CHARS} characters`)}var f=class{constructor(e){this.httpClient=e;}async message(e,s){return e.message?.text&&j(e.message.text),this.httpClient.request({method:"POST",path:c.MESSAGES,body:e,accessToken:s?.accessToken})}async action(e,s,o){return this.httpClient.request({method:"POST",path:c.MESSAGES,body:{recipient:{id:e},messaging_type:"RESPONSE",sender_action:s},accessToken:o?.accessToken})}async typingOn(e,s){return this.action(e,"typing_on",s)}async typingOff(e,s){return this.action(e,"typing_off",s)}async markSeen(e,s){return this.action(e,"mark_seen",s)}async attachment(e,s){return this.message({recipient:e.recipient,messaging_type:e.messaging_type??"RESPONSE",message:{attachment:{type:e.type,payload:{attachment_id:e.attachment_id}}}},s)}async attachmentFromUrl(e,s){return this.message({recipient:e.recipient,messaging_type:e.messaging_type??"RESPONSE",message:{attachment:{type:e.type,payload:{url:e.url}}}},s)}};var y=class{constructor(e){this.httpClient=e;}async upload(e,s){let o={message:{attachment:{type:e.type,payload:{url:e.url,is_reusable:e.is_reusable??true}}}};return this.httpClient.request({method:"POST",path:c.MESSAGE_ATTACHMENTS,body:o,accessToken:s?.accessToken})}};var T=class{constructor(e){this.httpClient=e;}async moderate(e,s){return this.httpClient.request({method:"POST",path:c.MODERATE_CONVERSATIONS,body:e,accessToken:s?.accessToken})}async blockUser(e,s){let o=Array.isArray(e)?e.map(a=>({id:a})):[{id:e}];return this.moderate({user_ids:o,actions:["block_user"]},s)}async unblockUser(e,s){let o=Array.isArray(e)?e.map(a=>({id:a})):[{id:e}];return this.moderate({user_ids:o,actions:["unblock_user"]},s)}async banUser(e,s){let o=Array.isArray(e)?e.map(a=>({id:a})):[{id:e}];return this.moderate({user_ids:o,actions:["ban_user"]},s)}async unbanUser(e,s){let o=Array.isArray(e)?e.map(a=>({id:a})):[{id:e}];return this.moderate({user_ids:o,actions:["unban_user"]},s)}async moveToSpam(e,s){let o=Array.isArray(e)?e.map(a=>({id:a})):[{id:e}];return this.moderate({user_ids:o,actions:["move_to_spam"]},s)}async blockAndSpam(e,s){let o=Array.isArray(e)?e.map(a=>({id:a})):[{id:e}];return this.moderate({user_ids:o,actions:["block_user","move_to_spam"]},s)}};var r=class extends Error{constructor(e){super(e),this.name="TemplateValidationError";}};function V(t){if(t.length===0)throw new r("Generic template must have at least 1 element");if(t.length>i.GENERIC_ELEMENTS_MAX)throw new r(`Generic template cannot have more than ${i.GENERIC_ELEMENTS_MAX} elements`);t.forEach((e,s)=>{ge(e,s);});}function ge(t,e){if(!t.title||t.title.trim()==="")throw new r(`Element ${e}: title is required`);if(t.title.length>i.GENERIC_TITLE_MAX_CHARS)throw new r(`Element ${e}: title cannot exceed ${i.GENERIC_TITLE_MAX_CHARS} characters`);if(t.subtitle&&t.subtitle.length>i.GENERIC_SUBTITLE_MAX_CHARS)throw new r(`Element ${e}: subtitle cannot exceed ${i.GENERIC_SUBTITLE_MAX_CHARS} characters`);if(t.image_url&&!M(t.image_url))throw new r(`Element ${e}: image_url must be HTTPS`);if(t.buttons&&C(t.buttons,`Element ${e}`),!!!(t.subtitle||t.image_url||t.default_action||t.buttons&&t.buttons.length>0))throw new r(`Element ${e}: must have at least one additional property beyond title`)}function $(t,e){if(!t||t.trim()==="")throw new r("Button template text is required");if(t.length>i.BUTTON_TEXT_MAX_CHARS)throw new r(`Button template text cannot exceed ${i.BUTTON_TEXT_MAX_CHARS} characters`);if(e.length===0)throw new r("Button template must have at least 1 button");C(e,"Button template");}function K(t){if(!t.media_type)throw new r("Media template element must have media_type");if(!t.url&&!t.attachment_id)throw new r("Media template element must have either url or attachment_id");if(t.url&&t.attachment_id)throw new r("Media template element cannot have both url and attachment_id");if(t.url&&!M(t.url))throw new r("Media template url must be HTTPS");if(t.buttons){if(t.buttons.length>i.MEDIA_BUTTONS_MAX_COUNT)throw new r(`Media template cannot have more than ${i.MEDIA_BUTTONS_MAX_COUNT} buttons`);C(t.buttons,"Media template");}}function C(t,e){if(t.length>i.BUTTONS_MAX_COUNT)throw new r(`${e} cannot have more than ${i.BUTTONS_MAX_COUNT} buttons`);t.forEach((s,o)=>{de(s,`${e} button ${o}`);});}function de(t,e){if(!t.type)throw new r(`${e}: type is required`);if(t.type!=="account_unlink"&&(!t.title||t.title.trim()===""))throw new r(`${e}: title is required for ${t.type} buttons`);if(t.title&&t.title.length>i.BUTTON_TITLE_MAX_CHARS)throw new r(`${e}: title cannot exceed ${i.BUTTON_TITLE_MAX_CHARS} characters`);switch(t.type){case "web_url":if(!t.url)throw new r(`${e}: url is required for web_url buttons`);if(!M(t.url))throw new r(`${e}: url must be HTTPS for web_url buttons`);break;case "postback":if(!t.payload)throw new r(`${e}: payload is required for postback buttons`);if(t.payload.length>i.POSTBACK_PAYLOAD_MAX_CHARS)throw new r(`${e}: payload cannot exceed ${i.POSTBACK_PAYLOAD_MAX_CHARS} characters`);break;case "phone_number":if(!t.payload)throw new r(`${e}: payload is required for phone_number buttons`);if(!t.payload.startsWith("+"))throw new r(`${e}: phone_number payload must start with + (e.g., +1234567890)`);break;case "game_play":break;case "account_link":if(!t.url)throw new r(`${e}: url is required for account_link buttons`);if(!M(t.url))throw new r(`${e}: url must be HTTPS for account_link buttons`);break;}if(t.type==="web_url"&&t.messenger_extensions&&t.fallback_url&&!M(t.fallback_url))throw new r(`${e}: fallback_url must be HTTPS`)}function M(t){try{return new URL(t).protocol==="https:"}catch{return false}}var k=class{constructor(e){this.httpClient=e;}async generic(e,s){V(e.elements);let o={template_type:"generic",elements:e.elements,image_aspect_ratio:e.image_aspect_ratio},a={recipient:e.recipient,messaging_type:e.messaging_type||"UPDATE",message:{attachment:{type:"template",payload:o}},notification_type:e.notification_type,tag:e.tag};return this.httpClient.request({method:"POST",path:c.MESSAGES,body:a,accessToken:s?.accessToken})}async button(e,s){$(e.text,e.buttons);let o={template_type:"button",text:e.text,buttons:e.buttons},a={recipient:e.recipient,messaging_type:e.messaging_type||"UPDATE",message:{attachment:{type:"template",payload:o}},notification_type:e.notification_type,tag:e.tag};return this.httpClient.request({method:"POST",path:c.MESSAGES,body:a,accessToken:s?.accessToken})}async media(e,s){K(e.element);let o={template_type:"media",elements:[e.element]},a={recipient:e.recipient,messaging_type:e.messaging_type||"UPDATE",message:{attachment:{type:"template",payload:o}},notification_type:e.notification_type,tag:e.tag};return this.httpClient.request({method:"POST",path:c.MESSAGES,body:a,accessToken:s?.accessToken})}async product(e,s){let o={template_type:"product",elements:e.elements},a={recipient:e.recipient,messaging_type:e.messaging_type||"UPDATE",message:{attachment:{type:"template",payload:o}},notification_type:e.notification_type,tag:e.tag};return this.httpClient.request({method:"POST",path:c.MESSAGES,body:a,accessToken:s?.accessToken})}};var S=class{constructor(e){this.httpClient=e;}async get(e,s){let{psid:o,fields:a=["first_name","last_name"]}=e,n=new URLSearchParams({fields:a.join(",")});return this.httpClient.request({method:"GET",path:`/${o}?${n.toString()}`,body:void 0,accessToken:s?.accessToken})}async getBasic(e,s){return this.get({psid:e,fields:["first_name","last_name","profile_pic"]},s)}async getFull(e,s){return this.get({psid:e,fields:["id","name","first_name","last_name","profile_pic","locale","timezone","gender"]},s)}async getName(e,s){return this.get({psid:e,fields:["first_name","last_name"]},s)}async getProfilePicture(e,s){return this.get({psid:e,fields:["profile_pic"]},s)}};var v=class{send;attachments;moderation;templates;profile;httpClient;constructor(e={}){this.validateConfig(e);let s={accessToken:e.accessToken,version:e.version||q,baseUrl:e.baseUrl,timeout:e.timeout,maxRetries:e.maxRetries};this.httpClient=new P(s),this.send=new f(this.httpClient),this.attachments=new y(this.httpClient),this.moderation=new T(this.httpClient),this.templates=new k(this.httpClient),this.profile=new S(this.httpClient);}validateConfig(e){if(e.accessToken!==void 0&&(typeof e.accessToken!="string"||e.accessToken.trim()===""))throw new m("Access token must be a non-empty string");if(e.version&&typeof e.version!="string")throw new m("API version must be a string");if(e.timeout&&(typeof e.timeout!="number"||e.timeout<=0))throw new m("Timeout must be a positive number");if(e.maxRetries&&(typeof e.maxRetries!="number"||e.maxRetries<0))throw new m("Max retries must be a non-negative number")}};var A=(p=>(p.MESSAGE="message",p.MESSAGE_EDIT="message_edit",p.MESSAGE_REACTION="reaction",p.MESSAGE_READ="read",p.MESSAGING_FEEDBACK="messaging_feedback",p.MESSAGING_POSTBACK="postback",p))(A||{});function me(t){return typeof t.id=="string"&&t.id.length>0}function Y(t){let e=[];if(t.object==="page"&&Array.isArray(t.entry))for(let s of t.entry)Array.isArray(s.messaging)&&e.push(...s.messaging);return e}function R(t){let e=me(t.sender);return {senderId:t.sender.id,userRef:t.sender.user_ref,recipientId:t.recipient.id,timestamp:t.timestamp,isIdentifiedUser:e,eventDate:new Date(t.timestamp)}}function le(t){return t&&typeof t=="object"&&"message_edit"in t}function Ee(t){return {...R(t),messageId:t.message_edit.mid,updatedText:t.message_edit.text,editCount:t.message_edit.num_edit}}var be={MAX_EDITS:5,EVENT_TYPE:"message_edit"};var W=(d=>(d.LIKE="like",d.DISLIKE="dislike",d.LOVE="love",d.SAD="sad",d.ANGRY="angry",d.WOW="wow",d.SMILE="smile",d.OTHER="other",d))(W||{}),I=(s=>(s.REACT="react",s.UNREACT="unreact",s))(I||{});function he(t){return t&&typeof t=="object"&&"read"in t}function ue(t){return {senderId:t.sender.id,recipientId:t.recipient.id,watermarkTimestamp:t.read.watermark,readTimestamp:t.timestamp,watermarkDate:new Date(t.read.watermark),readDate:new Date(t.timestamp)}}function Q(t,e){return t<=e}function z(t,e){return t.filter(s=>Q(s.timestamp,e))}function fe(t,e){return z(t,e).length}var ye={EVENT_TYPE:"message_reads",READ_PROPERTY:"read"};function Te(t){return t&&typeof t=="object"&&"postback"in t}function Z(t){return t.postback&&"referral"in t.postback&&t.postback.referral!=null}function J(t){return t&&typeof t.id=="string"&&t.id.length>0}function Me(t){let e=Z(t),s=J(t.sender);return {payload:t.postback.payload,senderId:t.sender.id,userRef:t.sender.user_ref,recipientId:t.recipient.id,buttonTitle:t.postback.title,messageId:t.postback.mid,timestamp:t.timestamp,referralContext:e?{ref:t.postback.referral.ref,source:t.postback.referral.source,type:t.postback.referral.type}:void 0,isReferred:e,isIdentifiedUser:s}}var ke={GET_STARTED:"GET_STARTED",MAIN_MENU:"MAIN_MENU",HELP:"HELP",SUPPORT:"SUPPORT",CONTACT:"CONTACT",CONTACT_SALES:"CONTACT_SALES",CONTACT_SUPPORT:"CONTACT_SUPPORT",BACK:"BACK",NEXT:"NEXT",CANCEL:"CANCEL",SETTINGS:"SETTINGS",PREFERENCES:"PREFERENCES"},Se={MAX_PAYLOAD_LENGTH:1e3,EVENT_TYPE:"postback",REFERRAL_SOURCES:{SHORTLINK:"SHORTLINK",ADS:"ADS",MESSENGER_CODE:"MESSENGER_CODE"},REFERRAL_TYPES:{OPEN_THREAD:"OPEN_THREAD"}};var O=(o=>(o.CSAT="csat",o.NPS="nps",o.CES="ces",o))(O||{}),N=(o=>(o.ONE_TO_FIVE="one_to_five",o.FIVE_STARS="five_stars",o.FIVE_EMOJIS="five_emojis",o))(N||{}),w=(e=>(e.ZERO_TO_TEN="zero_to_ten",e))(w||{}),G=(e=>(e.ONE_TO_SEVEN="one_to_seven",e))(G||{}),D=(e=>(e.FREE_FORM="free_form",e))(D||{});function Ae(t){return t&&typeof t=="object"&&"messaging_feedback"in t}function _e(t){let e=[];return t.messaging_feedback.feedback_screens.forEach(s=>{Object.entries(s.questions).forEach(([o,a])=>{e.push({questionId:o,feedbackType:a.type,score:parseInt(a.payload,10),textFeedback:a.follow_up?.payload,screenId:s.screen_id});});}),{senderId:t.sender.id,recipientId:t.recipient.id,submissionTimestamp:t.timestamp,screenCount:t.messaging_feedback.feedback_screens.length,allResponses:e}}function Pe(t){let e=new Map;return t.messaging_feedback.feedback_screens.forEach(s=>{Object.values(s.questions).forEach(o=>{let a=parseInt(o.payload,10),n=e.get(o.type)||[];e.set(o.type,[...n,a]);});}),e}function Re(t){let e=[];return t.messaging_feedback.feedback_screens.forEach(s=>{Object.values(s.questions).forEach(o=>{o.follow_up?.payload&&e.push(o.follow_up.payload);});}),e}var E={MAX_TEXT_FEEDBACK_LENGTH:400,SCORE_RANGES:{csat:{min:1,max:5},nps:{min:0,max:10},ces:{min:1,max:7}},TEMPLATE_EXPIRY:{MIN_DAYS:1,MAX_DAYS:7,DEFAULT_DAYS:1},QUESTION_ID:{MAX_LENGTH:80,VALID_PATTERN:/^[a-zA-Z0-9_]+$/},TEMPLATE_LIMITS:{MAX_TITLES:1,MAX_SCORING_COMPONENTS:1},EVENT_TYPE:"messaging_feedback"};function xe(t,e){let s=E.SCORE_RANGES[t];return Number.isInteger(e)&&e>=s.min&&e<=s.max}function Ce(t){return t.length<=E.QUESTION_ID.MAX_LENGTH&&E.QUESTION_ID.VALID_PATTERN.test(t)}function ve(t){return t.length<=E.MAX_TEXT_FEEDBACK_LENGTH}var U=(g=>(g.AUDIO="audio",g.FILE="file",g.IMAGE="image",g.VIDEO="video",g.FALLBACK="fallback",g.REEL="reel",g.IG_REEL="ig_reel",g))(U||{}),F=(o=>(o.OPEN_THREAD="OPEN_THREAD",o.PRODUCT="product",o.ADS="ads",o))(F||{}),B=(n=>(n.MESSENGER_CODE="MESSENGER_CODE",n.DISCOVER_TAB="DISCOVER_TAB",n.ADS="ADS",n.SHORTLINK="SHORTLINK",n.CUSTOMER_CHAT_PLUGIN="CUSTOMER_CHAT_PLUGIN",n))(B||{});function We(t){return t&&typeof t=="object"&&"message"in t}function Ie(t){return typeof t.text=="string"&&t.text.length>0}function x(t){return Array.isArray(t.attachments)&&t.attachments.length>0}function ee(t){return t.quick_reply!==void 0}function te(t){return t.reply_to!==void 0}function se(t){return t.referral!==void 0}function oe(t,e){return t.type===e}function Oe(t){let{message:e}=t;return {...R(t),messageId:e.mid,text:e.text,hasAttachments:x(e),isQuickReply:ee(e),isReply:te(e),hasReferral:se(e),quickReplyPayload:e.quick_reply?.payload,repliedToMessageId:e.reply_to?.mid}}function Ne(t,e){return x(t)?t.attachments.filter(s=>oe(s,e)):[]}function we(t){return x(t)?t.attachments.map(e=>e.payload.url):[]}var Ge={MAX_TEXT_LENGTH:2e3,MAX_QUICK_REPLY_PAYLOAD_LENGTH:1e3,MAX_REFERRAL_REF_LENGTH:250,EVENT_TYPE:"message"},De={image:["image/jpeg","image/png","image/gif","image/webp"],video:["video/mp4","video/avi","video/quicktime","video/webm"],audio:["audio/mpeg","audio/mp4","audio/wav","audio/ogg"],file:["application/pdf","application/msword","application/vnd.openxmlformats-officedocument.wordprocessingml.document","text/plain"]};function L(t){return !t||typeof t!="object"?null:"type"in t&&Object.values(A).includes(t.type)?t.type:"message"in t?"message":"message_edit"in t?"message_edit":"reaction"in t?"reaction":"read"in t?"read":"messaging_feedback"in t?"messaging_feedback":"postback"in t?"postback":null}function H(t){return Y(t)}function Ue(t){let e=L(t);return e?"type"in t?t:{...t,type:e}:null}async function ae(t,e){let s=H(t);for(let o of s){let a=Ue(o);if(!a){e.onUnknown&&await e.onUnknown(o);continue}switch(a.type){case "message":e.onMessage&&await e.onMessage(a);break;case "message_edit":e.onMessageEdit&&await e.onMessageEdit(a);break;case "reaction":e.onMessageReaction&&await e.onMessageReaction(a);break;case "read":e.onMessageRead&&await e.onMessageRead(a);break;case "messaging_feedback":e.onMessagingFeedback&&await e.onMessagingFeedback(a);break;case "postback":e.onMessagingPostback&&await e.onMessagingPostback(a);break;default:let n=a;e.onUnknown&&await e.onUnknown(n);break}}}function ne(t,e){return t["hub.mode"]==="subscribe"&&t["hub.verify_token"]===e?t["hub.challenge"]:null}
|
|
2
|
+
exports.ATTACHMENT_LIMITS=re;exports.ATTACHMENT_MIME_TYPES=De;exports.AttachmentsAPI=y;exports.CESDisplayOption=G;exports.COMMON_POSTBACK_PAYLOADS=ke;exports.CSATDisplayOption=N;exports.FeedbackType=O;exports.FollowUpType=D;exports.MESSAGE_CONSTANTS=Ge;exports.MESSAGE_EDIT_CONSTANTS=be;exports.MESSAGE_LIMITS=_;exports.MESSAGE_READS_CONSTANTS=ye;exports.MESSAGING_FEEDBACK_CONSTANTS=E;exports.MessageReactionAction=I;exports.MessageReactionType=W;exports.MessageReferralSource=B;exports.MessageReferralType=F;exports.MessageValidationError=u;exports.Messenger=v;exports.MessengerAPIError=l;exports.MessengerConfigError=m;exports.MessengerNetworkError=b;exports.MessengerTimeoutError=h;exports.ModerationAPI=T;exports.NPSDisplayOption=w;exports.POSTBACK_CONSTANTS=Se;exports.ProfileAPI=S;exports.SendAPI=f;exports.TEMPLATE_LIMITS=i;exports.TemplateValidationError=r;exports.TemplatesAPI=k;exports.WebhookAttachmentType=U;exports.WebhookEventType=A;exports.extractMessageContext=Oe;exports.extractMessageEditContext=Ee;exports.extractMessageReadsContext=ue;exports.extractMessagingFeedbackContext=_e;exports.extractPostbackContext=Me;exports.extractTextFeedback=Re;exports.extractWebhookEvents=H;exports.getAttachmentUrls=we;exports.getAttachmentsByType=Ne;exports.getFeedbackScoresByType=Pe;exports.getReadMessageCount=fe;exports.getReadMessages=z;exports.getWebhookEventType=L;exports.hasAttachments=x;exports.hasQuickReply=ee;exports.hasReferral=se;exports.hasReferralData=Z;exports.isAttachmentType=oe;exports.isIdentifiedSender=J;exports.isMessageEditEvent=le;exports.isMessageEvent=We;exports.isMessageRead=Q;exports.isMessageReadsEvent=he;exports.isMessagingFeedbackEvent=Ae;exports.isMessagingPostbackEvent=Te;exports.isReplyMessage=te;exports.isTextMessage=Ie;exports.isValidFeedbackScore=xe;exports.isValidQuestionId=Ce;exports.isValidTextFeedback=ve;exports.processWebhookEvents=ae;exports.verifyWebhookSubscription=ne;//# sourceMappingURL=index.cjs.map
|
|
3
3
|
//# sourceMappingURL=index.cjs.map
|