zaileys 4.7.2 → 4.8.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 CHANGED
@@ -27,13 +27,14 @@
27
27
 
28
28
  <div align="center">
29
29
  <p>
30
- <b>Zaileys</b> is a type-safe wrapper around <a href="https://github.com/WhiskeySockets/Baileys">Baileys</a> that makes building WhatsApp bots feel effortless. Create a <code>Client</code>, listen for typed events, and send anything from plain text to interactive buttons and rich AI-style responses with a single chainable builder authentication, reconnection, and storage are handled for you.
30
+ <b>Zaileys</b> is a type-safe WhatsApp framework for Node.js &amp; TypeScript with <b>two providers behind one API</b>: the <b>unofficial</b> WhatsApp Web engine (<a href="https://github.com/WhiskeySockets/Baileys">Baileys</a>) and the <b>official Meta WhatsApp Cloud API</b>. Write your bot once against a single chainable builder and typed events then run it on either provider by flipping one option. Authentication, reconnection, and storage are handled for you.
31
31
  </p>
32
32
  </div>
33
33
 
34
34
  <div align="center">
35
35
 
36
36
  [Quick start](#quick-start) &nbsp;•&nbsp;
37
+ [Providers](#two-providers-one-api) &nbsp;•&nbsp;
37
38
  [Why Zaileys](#why-zaileys) &nbsp;•&nbsp;
38
39
  [Install](#install) &nbsp;•&nbsp;
39
40
  [What you can build](#what-you-can-build) &nbsp;•&nbsp;
@@ -77,6 +78,43 @@ Prefer a pairing code? Provide your number:
77
78
  const client = new Client({ authType: 'pairing', phoneNumber: '6281234567890' })
78
79
  ```
79
80
 
81
+ ## Two providers, one API
82
+
83
+ Zaileys runs on **either** the unofficial WhatsApp Web engine **or** the **official Meta WhatsApp Cloud API** — same `Client`, same `send(jid)…` builder, same typed events. Switch with one option; your handlers never change.
84
+
85
+ ```typescript
86
+ // 🔗 Unofficial (default) — WhatsApp Web via Baileys. QR/pairing login, groups, polls, channels.
87
+ const client = new Client()
88
+
89
+ // ☁️ Official — Meta Cloud API. Token auth, no ban risk, templates/OTP/campaigns, Flows, commerce.
90
+ const client = new Client({
91
+ provider: 'cloud',
92
+ cloud: {
93
+ accessToken: process.env.WA_TOKEN!,
94
+ phoneNumberId: process.env.WA_PHONE_ID!,
95
+ verifyToken: process.env.WA_VERIFY!,
96
+ appSecret: process.env.WA_APP_SECRET!,
97
+ },
98
+ })
99
+
100
+ client.on('text', (m) => m.reply(`echo: ${m.text}`))
101
+ await client.sendTemplate('628xxx', 'welcome', 'en_US') // cloud-only: reach users who never texted you
102
+
103
+ // inbound arrives via webhook (framework-agnostic) — mount on any server:
104
+ export const GET = client.webhook()
105
+ export const POST = client.webhook()
106
+ ```
107
+
108
+ | | 🔗 Unofficial (WhatsApp Web) | ☁️ Official (Meta Cloud API) |
109
+ | --- | --- | --- |
110
+ | Login | QR / pairing code, no approval | Permanent token |
111
+ | Ban risk | Exists | None (sanctioned) |
112
+ | Groups / channels / polls | ✅ | ❌ |
113
+ | Templates / OTP / marketing | ❌ | ✅ |
114
+ | Message users who never texted you | ✅ any number | ✅ via approved templates |
115
+
116
+ Pick your provider → **[Choose Your Provider](https://zeative.github.io/zaileys/providers)** · **[Official Cloud API guide](https://zeative.github.io/zaileys/official)**.
117
+
80
118
  ## Build with AI
81
119
 
82
120
  Zaileys ships an **official Agent Skill suite** so your AI assistant writes, reviews, and
@@ -96,6 +134,7 @@ The suite has an orchestrator that auto-routes plus focused scaffold, debug, and
96
134
 
97
135
  ## Why Zaileys
98
136
 
137
+ - **Two providers, one codebase** — the unofficial WhatsApp Web engine and the official Meta Cloud API behind the same `Client`. Switch with a single option; your handlers never change.
99
138
  - **Typed events** — `on('text' | 'image' | 'reaction' | 'button-click' | 'group-update' | …)` with fully-typed payloads and IntelliSense. No raw Baileys decoding, no `any`.
100
139
  - **One chainable builder** — `client.send(jid).text(…).reply(quoted).mentions([…])` resolves to the sent message key when awaited.
101
140
  - **Rich & interactive out of the box** — native buttons, lists, carousels, and Meta-AI-style rich responses written as plain markdown.
@@ -7,7 +7,9 @@ import type { MediaDownloadResult } from '../events/types.js';
7
7
  import type { AuthStoreBundle } from '../auth/types.js';
8
8
  import type { MessageStore } from '../store/types.js';
9
9
  import { TypedEventEmitter } from './event-emitter.js';
10
- import type { BaileysSocket, ClientEventMap, ClientOptions, ConnectionState } from './types.js';
10
+ import type { BaileysSocket, ClientEventMap, ClientOptions, ConnectionState, ProviderKind } from './types.js';
11
+ import { CloudModule } from '../cloud/module.js';
12
+ import { type WebhookHandler } from '../cloud/webhook.js';
11
13
  export declare class Client extends TypedEventEmitter<ClientEventMap> {
12
14
  readonly sessionId: string;
13
15
  auth: AuthStoreBundle;
@@ -67,13 +69,21 @@ export declare class Client extends TypedEventEmitter<ClientEventMap> {
67
69
  private pluginLoader;
68
70
  private waVersion?;
69
71
  private versionWarming?;
72
+ private readonly _provider;
73
+ private readonly cloudOptions;
74
+ private cloudTransport;
75
+ private cloudRuntimeReady;
76
+ private _cloudModule;
70
77
  constructor(options?: ClientOptions);
71
78
  private warmVersion;
72
79
  private emitAutoConnectError;
73
80
  private logStatus;
74
81
  private resolveMe;
82
+ get provider(): ProviderKind;
75
83
  get state(): ConnectionState;
76
84
  get socket(): BaileysSocket | undefined;
85
+ /** Web-only surfaces fail loud on the cloud provider instead of dying deeper with a vague error. */
86
+ private assertWebProvider;
77
87
  get group(): GroupModule;
78
88
  get privacy(): PrivacyModule;
79
89
  get newsletter(): NewsletterModule;
@@ -88,6 +98,16 @@ export declare class Client extends TypedEventEmitter<ClientEventMap> {
88
98
  private ensureScheduler;
89
99
  private dispatchSnapshot;
90
100
  connect(): Promise<void>;
101
+ /** Create the cloud transport + attach the inbound pipeline exactly once — independent of connect(). */
102
+ private ensureCloudRuntime;
103
+ private connectCloud;
104
+ private attachCloudPipeline;
105
+ /**
106
+ * Framework-agnostic Meta webhook endpoint (cloud provider only): handles the GET
107
+ * verification challenge and signed POST deliveries, then feeds events into the client.
108
+ */
109
+ webhook(): WebhookHandler;
110
+ private disconnectCloud;
91
111
  disconnect(): Promise<void>;
92
112
  logout(): Promise<void>;
93
113
  command(spec: string, handler: CommandHandler): this;
@@ -101,12 +121,22 @@ export declare class Client extends TypedEventEmitter<ClientEventMap> {
101
121
  edit(key: WAMessageKey): EditBuilder;
102
122
  delete(key: WAMessageKey, opts?: DeleteOptions): Promise<void>;
103
123
  react(key: WAMessageKey, emoji: string): Promise<WAMessageKey>;
124
+ /** Cloud provider only: management surface (templates, profile, flows, blocklist, qr, analytics, phone). */
125
+ get cloud(): CloudModule;
126
+ /** Cloud provider only: send an approved Meta message template by name + language. */
127
+ sendTemplate(to: string, name: string, languageCode: string, components?: Array<Record<string, unknown>>): Promise<WAMessageKey>;
128
+ /** Cloud provider only: mark an inbound message read (optionally showing a typing indicator). */
129
+ markRead(messageId: string, opts?: {
130
+ typing?: boolean;
131
+ }): Promise<void>;
104
132
  forward(key: WAMessageKey, to: string): Promise<WAMessageKey>;
105
133
  pin(key: WAMessageKey, opts?: PinOptions): Promise<WAMessageKey>;
106
134
  unpin(key: WAMessageKey): Promise<WAMessageKey>;
107
135
  setDisappearing(to: string, seconds: number): Promise<void>;
108
136
  private resolveRecipient;
109
137
  private requireSocket;
138
+ /** Messaging seam: baileys socket or the cloud transport, whichever the provider dictates. */
139
+ private requireBuilderSocket;
110
140
  private attachEmitterLogger;
111
141
  private wireSocket;
112
142
  private handleConnectionUpdate;
@@ -9,6 +9,9 @@ import type { CitationConfig } from '../events/context.js';
9
9
  import type { InboundEventMap } from '../events/types.js';
10
10
  import type { MessageStore } from '../store/types.js';
11
11
  import type { PluginsOptions } from '../plugin/types.js';
12
+ import type { CloudOptions } from '../cloud/types.js';
13
+ import type { CloudFlowResponseEvent, CloudOrderEvent, CloudStatusEvent, CloudTemplateStatusEvent } from '../cloud/translate/inbound.js';
14
+ export type ProviderKind = 'baileys' | 'cloud';
12
15
  export type ConnectionState = 'idle' | 'connecting' | 'qr-pending' | 'pairing-pending' | 'connected' | 'reconnecting' | 'disconnecting' | 'disconnected';
13
16
  export type ConnectionAuthType = 'qr' | 'pairing';
14
17
  export interface Logger {
@@ -28,6 +31,10 @@ export interface ReconnectOptions {
28
31
  rateLimitedDelayMs?: number;
29
32
  }
30
33
  export interface ClientOptions {
34
+ /** Message transport: baileys (WhatsApp Web, default) or the official Meta Cloud API. */
35
+ provider?: ProviderKind;
36
+ /** Cloud API credentials/config — required when `provider: 'cloud'`. */
37
+ cloud?: CloudOptions;
31
38
  sessionId?: string;
32
39
  auth?: AuthStoreBundle;
33
40
  store?: MessageStore;
@@ -96,6 +103,14 @@ export type ConnectionEventMap = {
96
103
  sessionId: string;
97
104
  error: Error;
98
105
  };
106
+ /** Cloud provider: delivery lifecycle of outbound messages (sent/delivered/read/failed). */
107
+ 'message-status': CloudStatusEvent;
108
+ /** Cloud provider: template review lifecycle (APPROVED/REJECTED/PAUSED...). */
109
+ 'template-status': CloudTemplateStatusEvent;
110
+ /** Cloud provider: WhatsApp Flow completion (nfm_reply) with parsed response payload. */
111
+ 'flow-response': CloudFlowResponseEvent;
112
+ /** Cloud provider: catalog order placed by the customer. */
113
+ order: CloudOrderEvent;
99
114
  };
100
115
  export type ConnectionEventName = keyof ConnectionEventMap;
101
116
  export type ConnectionEventHandler<E extends ConnectionEventName> = (payload: ConnectionEventMap[E]) => void;
@@ -0,0 +1,14 @@
1
+ export type CloudErrorCode = 'CONFIG' | 'AUTH' | 'REQUEST_FAILED' | 'RATE_LIMITED' | 'NOT_IMPLEMENTED';
2
+ /** Thrown when a WhatsApp-Web-only surface is used on the official Cloud API provider. */
3
+ export declare class ZaileysProviderError extends Error {
4
+ readonly code = "UNSUPPORTED_ON_CLOUD";
5
+ readonly feature: string;
6
+ constructor(feature: string);
7
+ }
8
+ export declare class ZaileysCloudError extends Error {
9
+ readonly code: CloudErrorCode;
10
+ readonly cause?: unknown;
11
+ constructor(code: CloudErrorCode, message: string, options?: {
12
+ cause?: unknown;
13
+ });
14
+ }
@@ -0,0 +1,15 @@
1
+ import type { CloudOptions } from './types.js';
2
+ /** Pinned default Graph API version — override via CloudOptions.apiVersion. */
3
+ export declare const DEFAULT_GRAPH_VERSION = "v23.0";
4
+ export declare const DEFAULT_GRAPH_BASE_URL = "https://graph.facebook.com";
5
+ export interface GraphClientDeps {
6
+ delay?: (ms: number) => Promise<void>;
7
+ }
8
+ export interface GraphClient {
9
+ get<T>(path: string): Promise<T>;
10
+ post<T>(path: string, body: unknown): Promise<T>;
11
+ postForm<T>(path: string, form: FormData): Promise<T>;
12
+ delete<T = unknown>(path: string, body?: unknown): Promise<T>;
13
+ url(path: string): string;
14
+ }
15
+ export declare function createGraphClient(options: CloudOptions, deps?: GraphClientDeps): GraphClient;
@@ -0,0 +1,6 @@
1
+ export { ZaileysCloudError, ZaileysProviderError, type CloudErrorCode } from './errors.js';
2
+ export { validateCloudOptions, type CloudOptions } from './types.js';
3
+ export { CloudTransport, DEFAULT_GRAPH_VERSION } from './transport.js';
4
+ export { CloudModule, type CloudTemplate, type CloudBusinessProfile, type FlowSendOptions } from './module.js';
5
+ export { createWebhookHandler, type WebhookHandler, type WebhookHandlerOptions } from './webhook.js';
6
+ export type { CloudFlowResponseEvent, CloudMessageStatus, CloudOrderEvent, CloudStatusEvent, CloudTemplateStatusEvent, } from './translate/inbound.js';
@@ -0,0 +1,15 @@
1
+ import type { AnyMessageContent } from 'baileys';
2
+ import type { GraphClient } from './graph-client.js';
3
+ export type CloudMediaKind = 'image' | 'video' | 'audio' | 'document' | 'sticker';
4
+ export interface OutboundMedia {
5
+ kind: CloudMediaKind;
6
+ buffer: Buffer;
7
+ caption?: string;
8
+ fileName?: string;
9
+ mimetype?: string;
10
+ }
11
+ /** Detect a builder media content (`{ image: Buffer, caption? }` etc.); null when not media. */
12
+ export declare function outboundMediaOf(content: AnyMessageContent): OutboundMedia | null;
13
+ /** Upload bytes to the Cloud media endpoint; returns the media id to reference in sends. */
14
+ export declare function uploadMedia(graph: GraphClient, phoneNumberId: string, media: OutboundMedia): Promise<string>;
15
+ export declare function mediaMessageBody(media: OutboundMedia, mediaId: string): Record<string, unknown>;
@@ -0,0 +1,147 @@
1
+ import type { WAMessageKey } from 'baileys';
2
+ import type { CloudTransport } from './transport.js';
3
+ import type { CloudOptions } from './types.js';
4
+ export interface FlowSendOptions {
5
+ flowId?: string;
6
+ flowName?: string;
7
+ cta: string;
8
+ bodyText: string;
9
+ headerText?: string;
10
+ footerText?: string;
11
+ screen: string;
12
+ flowToken?: string;
13
+ data?: Record<string, unknown>;
14
+ mode?: 'draft' | 'published';
15
+ action?: 'navigate' | 'data_exchange';
16
+ }
17
+ export interface CloudTemplate {
18
+ id: string;
19
+ name: string;
20
+ status: string;
21
+ category?: string;
22
+ language?: string;
23
+ components?: Array<Record<string, unknown>>;
24
+ }
25
+ export interface CloudBusinessProfile {
26
+ about?: string;
27
+ address?: string;
28
+ description?: string;
29
+ email?: string;
30
+ websites?: string[];
31
+ vertical?: string;
32
+ messaging_product?: string;
33
+ }
34
+ /** Cloud-only management surface: templates, profile, flows, commerce, blocklist, qr, analytics, phone. */
35
+ export declare class CloudModule {
36
+ private readonly graph;
37
+ private readonly options;
38
+ private readonly getTransport;
39
+ constructor(options: CloudOptions, getTransport: () => CloudTransport);
40
+ private requireWaba;
41
+ /** This sender's phone-number node: display number, verified name, quality rating, throughput. */
42
+ info(): Promise<Record<string, unknown>>;
43
+ /** All phone numbers registered under the WhatsApp Business Account. */
44
+ phoneNumbers(): Promise<Array<Record<string, unknown>>>;
45
+ /** Request the user's shipping address (interactive address_message; ID/BR only per Meta). */
46
+ sendAddressRequest(to: string, opts: {
47
+ bodyText: string;
48
+ countryIso: string;
49
+ values?: Record<string, unknown>;
50
+ }): Promise<WAMessageKey>;
51
+ readonly commerce: {
52
+ catalogs: () => Promise<Array<{
53
+ id: string;
54
+ name: string;
55
+ }>>;
56
+ products: (catalogId: string, limit?: number) => Promise<Array<{
57
+ id: string;
58
+ retailer_id: string;
59
+ name: string;
60
+ price?: string;
61
+ availability?: string;
62
+ }>>;
63
+ sendProduct: (to: string, opts: {
64
+ catalogId: string;
65
+ retailerId: string;
66
+ bodyText?: string;
67
+ footerText?: string;
68
+ }) => Promise<WAMessageKey>;
69
+ sendProductList: (to: string, opts: {
70
+ catalogId: string;
71
+ headerText: string;
72
+ bodyText: string;
73
+ footerText?: string;
74
+ sections: Array<{
75
+ title: string;
76
+ productIds: string[];
77
+ }>;
78
+ }) => Promise<WAMessageKey>;
79
+ };
80
+ readonly templates: {
81
+ list: (params?: {
82
+ status?: string;
83
+ limit?: number;
84
+ }) => Promise<CloudTemplate[]>;
85
+ get: (idOrName: string) => Promise<CloudTemplate | null>;
86
+ create: (template: {
87
+ name: string;
88
+ category: 'MARKETING' | 'UTILITY' | 'AUTHENTICATION';
89
+ language: string;
90
+ components: Array<Record<string, unknown>>;
91
+ }) => Promise<{
92
+ id: string;
93
+ status: string;
94
+ }>;
95
+ delete: (name: string, id?: string) => Promise<void>;
96
+ };
97
+ readonly profile: {
98
+ get: () => Promise<CloudBusinessProfile>;
99
+ update: (fields: CloudBusinessProfile) => Promise<void>;
100
+ };
101
+ readonly flows: {
102
+ list: () => Promise<Array<{
103
+ id: string;
104
+ name: string;
105
+ status: string;
106
+ }>>;
107
+ send: (to: string, opts: FlowSendOptions) => Promise<WAMessageKey>;
108
+ };
109
+ readonly blocklist: {
110
+ add: (numbers: string[]) => Promise<void>;
111
+ remove: (numbers: string[]) => Promise<void>;
112
+ list: () => Promise<Array<{
113
+ wa_id: string;
114
+ }>>;
115
+ };
116
+ readonly qr: {
117
+ create: (prefilledMessage: string, imageFormat?: 'SVG' | 'PNG') => Promise<{
118
+ code: string;
119
+ prefilled_message: string;
120
+ qr_image_url?: string;
121
+ }>;
122
+ list: () => Promise<Array<{
123
+ code: string;
124
+ prefilled_message: string;
125
+ }>>;
126
+ delete: (code: string) => Promise<void>;
127
+ };
128
+ readonly analytics: {
129
+ conversations: (params: {
130
+ start: number;
131
+ end: number;
132
+ granularity?: 'HALF_HOUR' | 'DAILY' | 'MONTHLY';
133
+ }) => Promise<unknown>;
134
+ messages: (params: {
135
+ start: number;
136
+ end: number;
137
+ granularity?: 'HALF_HOUR' | 'DAY' | 'MONTH';
138
+ }) => Promise<unknown>;
139
+ };
140
+ readonly phone: {
141
+ /** Registers the number for Cloud API messaging. Touches live registration — use with care. */
142
+ register: (pin: string) => Promise<void>;
143
+ deregister: () => Promise<void>;
144
+ requestCode: (method: 'SMS' | 'VOICE', language?: string) => Promise<void>;
145
+ verifyCode: (code: string) => Promise<void>;
146
+ };
147
+ }
@@ -0,0 +1,119 @@
1
+ import type { WAMessage } from 'baileys';
2
+ export interface CloudInboundMedia {
3
+ id?: string;
4
+ mime_type?: string;
5
+ sha256?: string;
6
+ caption?: string;
7
+ filename?: string;
8
+ voice?: boolean;
9
+ animated?: boolean;
10
+ }
11
+ export interface CloudWebhookMessage {
12
+ from?: string;
13
+ id?: string;
14
+ timestamp?: string;
15
+ type?: string;
16
+ text?: {
17
+ body?: string;
18
+ };
19
+ image?: CloudInboundMedia;
20
+ video?: CloudInboundMedia;
21
+ audio?: CloudInboundMedia;
22
+ document?: CloudInboundMedia;
23
+ sticker?: CloudInboundMedia;
24
+ [key: string]: unknown;
25
+ }
26
+ export interface CloudWebhookValue {
27
+ messaging_product?: string;
28
+ metadata?: {
29
+ display_phone_number?: string;
30
+ phone_number_id?: string;
31
+ };
32
+ contacts?: Array<{
33
+ profile?: {
34
+ name?: string;
35
+ };
36
+ wa_id?: string;
37
+ }>;
38
+ messages?: CloudWebhookMessage[];
39
+ statuses?: Array<Record<string, unknown>>;
40
+ }
41
+ export interface CloudWebhookPayload {
42
+ object?: string;
43
+ entry?: Array<{
44
+ id?: string;
45
+ changes?: Array<{
46
+ value?: CloudWebhookValue;
47
+ field?: string;
48
+ }>;
49
+ }>;
50
+ }
51
+ export interface CloudTemplateStatusEvent {
52
+ event: string;
53
+ id: string;
54
+ name: string;
55
+ language?: string;
56
+ reason?: string;
57
+ }
58
+ export type CloudMessageStatus = 'sent' | 'delivered' | 'read' | 'failed';
59
+ export interface CloudStatusEvent {
60
+ id: string;
61
+ status: CloudMessageStatus;
62
+ recipientId: string;
63
+ timestamp: number;
64
+ conversationId?: string;
65
+ error?: {
66
+ code?: number;
67
+ title?: string;
68
+ message?: string;
69
+ };
70
+ }
71
+ export interface CloudFlowResponseEvent {
72
+ id: string;
73
+ name: string;
74
+ body?: string;
75
+ response: Record<string, unknown>;
76
+ senderId: string;
77
+ senderName?: string;
78
+ timestamp: number;
79
+ }
80
+ export interface CloudOrderEvent {
81
+ id: string;
82
+ catalogId: string;
83
+ text?: string;
84
+ items: Array<{
85
+ productRetailerId: string;
86
+ quantity: number;
87
+ price: number;
88
+ currency: string;
89
+ }>;
90
+ senderId: string;
91
+ senderName?: string;
92
+ timestamp: number;
93
+ }
94
+ export interface CloudReactionItem {
95
+ key: {
96
+ id: string;
97
+ remoteJid: string;
98
+ fromMe: boolean;
99
+ };
100
+ reaction: {
101
+ key: {
102
+ id: string;
103
+ remoteJid: string;
104
+ fromMe: boolean;
105
+ };
106
+ text: string;
107
+ senderTimestampMs: number;
108
+ };
109
+ pushName?: string;
110
+ }
111
+ /** Flatten a Meta webhook delivery into baileys-shaped events the existing pipeline can decode. */
112
+ export declare function translateInbound(payload: CloudWebhookPayload): {
113
+ messages: WAMessage[];
114
+ reactions: CloudReactionItem[];
115
+ statuses: CloudStatusEvent[];
116
+ templateStatuses: CloudTemplateStatusEvent[];
117
+ flowResponses: CloudFlowResponseEvent[];
118
+ orders: CloudOrderEvent[];
119
+ };
@@ -0,0 +1,2 @@
1
+ /** Translate the builder's relay proto (interactiveMessage) into a Graph `interactive` object. */
2
+ export declare function translateInteractiveProto(message: Record<string, unknown>): Record<string, unknown> | null;
@@ -0,0 +1,21 @@
1
+ import type { AnyMessageContent, MiscMessageGenerationOptions, WAMessage } from 'baileys';
2
+ export interface GraphMessagePayload {
3
+ messaging_product: 'whatsapp';
4
+ recipient_type: 'individual';
5
+ to: string;
6
+ type: string;
7
+ context?: {
8
+ message_id: string;
9
+ };
10
+ [key: string]: unknown;
11
+ }
12
+ /** Graph `to` is a bare number — strip any jid server suffix. */
13
+ export declare const toGraphRecipient: (to: string) => string;
14
+ export declare const toJid: (recipient: string) => string;
15
+ export declare const basePayload: (to: string, type: string, options?: MiscMessageGenerationOptions) => GraphMessagePayload;
16
+ /** Translate baileys-style outbound content to a Graph payload; null = not translatable yet. */
17
+ export declare function translateOutbound(to: string, content: AnyMessageContent, options?: MiscMessageGenerationOptions): GraphMessagePayload | null;
18
+ /** Minimal vcard extraction (FN/N + TELs) — Graph requires formatted_name plus one name part. */
19
+ export declare function vcardToGraphContact(vcard: string): Record<string, unknown> | null;
20
+ /** Minimal baileys-shaped WAMessage so recordSent/store/reply keep working on cloud. */
21
+ export declare function synthesizeSentMessage(wamid: string, to: string, content: AnyMessageContent, timestampMs: number): WAMessage;
@@ -0,0 +1,51 @@
1
+ import { EventEmitter } from 'node:events';
2
+ import type { AnyMessageContent, MiscMessageGenerationOptions, WAMessage } from 'baileys';
3
+ import type { Transport } from '../transport/types.js';
4
+ import type { CloudOptions } from './types.js';
5
+ import { DEFAULT_GRAPH_BASE_URL, DEFAULT_GRAPH_VERSION } from './graph-client.js';
6
+ export { DEFAULT_GRAPH_BASE_URL, DEFAULT_GRAPH_VERSION };
7
+ export interface CloudMe {
8
+ id: string;
9
+ name?: string;
10
+ }
11
+ export declare class CloudTransport implements Transport {
12
+ readonly ev: EventEmitter<[never]>;
13
+ readonly user: {
14
+ id: string;
15
+ };
16
+ private readonly options;
17
+ private readonly graph;
18
+ constructor(options: CloudOptions);
19
+ get apiVersion(): string;
20
+ get baseUrl(): string;
21
+ url(path: string): string;
22
+ /** Health check: token+phoneNumberId must resolve the phone-number node. No retry — a bad token never heals. */
23
+ connect(): Promise<CloudMe>;
24
+ disconnect(): Promise<void>;
25
+ /**
26
+ * Relay seam used by the builder for interactive sends (buttons/list/cta). Translates the
27
+ * proto to a Graph interactive payload. Returns the builder's messageId per contract, but
28
+ * the store records the real wamid via the upsert emit.
29
+ */
30
+ relayMessage: (jid: string, message: unknown, options: {
31
+ messageId: string;
32
+ additionalNodes?: unknown[];
33
+ }) => Promise<string>;
34
+ /** Post a raw interactive object to /messages; shared by flows/commerce/address sends. */
35
+ sendInteractive(to: string, interactive: Record<string, unknown>): Promise<WAMessage>;
36
+ /** Send an approved Meta message template (Cloud-only; templates are managed in Business Manager). */
37
+ sendTemplate(to: string, name: string, languageCode: string, components?: Array<Record<string, unknown>>): Promise<WAMessage>;
38
+ /** Mark an inbound message read; optionally show a typing indicator alongside. */
39
+ markRead(messageId: string, opts?: {
40
+ typing?: boolean;
41
+ }): Promise<void>;
42
+ /** Resolve a Meta media id to bytes: GET /{mediaId} -> short-lived CDN url -> authorized fetch. */
43
+ downloadMedia(mediaId: string): Promise<{
44
+ buffer: Buffer;
45
+ mime: string;
46
+ size: number;
47
+ } | null>;
48
+ /** Feed a verified webhook payload into the shared event pipeline. */
49
+ ingest(payload: unknown): void;
50
+ sendMessage(jid: string, content: AnyMessageContent, options?: MiscMessageGenerationOptions): Promise<WAMessage | undefined>;
51
+ }
@@ -0,0 +1,17 @@
1
+ export interface CloudOptions {
2
+ /** Permanent or system-user access token for the WhatsApp Business app. */
3
+ accessToken: string;
4
+ /** Sender phone-number id (not the phone number itself). */
5
+ phoneNumberId: string;
6
+ /** WhatsApp Business Account id — optional, needed only for account-level ops. */
7
+ wabaId?: string;
8
+ /** Token echoed back on the webhook GET verification challenge. */
9
+ verifyToken?: string;
10
+ /** Meta app secret; enables X-Hub-Signature-256 verification of webhook POSTs. */
11
+ appSecret?: string;
12
+ /** Graph API version, e.g. 'v23.0'. Defaults to the pinned stable version. */
13
+ apiVersion?: string;
14
+ /** Override the Graph API origin (tests / proxies). */
15
+ baseUrl?: string;
16
+ }
17
+ export declare function validateCloudOptions(cloud: CloudOptions | undefined): CloudOptions;
@@ -0,0 +1,11 @@
1
+ export type WebhookHandler = (req: Request) => Promise<Response>;
2
+ export interface WebhookHandlerOptions {
3
+ verifyToken?: string;
4
+ appSecret?: string;
5
+ onPayload: (payload: unknown) => void;
6
+ }
7
+ /**
8
+ * Framework-agnostic Meta webhook endpoint: handles the GET verification challenge and
9
+ * signed POST deliveries. Mount it on any server that speaks Web Request/Response.
10
+ */
11
+ export declare function createWebhookHandler(options: WebhookHandlerOptions): WebhookHandler;