@ecodrix/erix-api 1.2.7 → 1.2.9

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,67 +0,0 @@
1
- import type { AxiosInstance } from "axios";
2
- import { APIResource } from "../../resource";
3
- import { Broadcasts } from "./broadcasts";
4
- import { Conversations } from "./conversations";
5
- import { Messages } from "./messages";
6
- import { Templates } from "./templates";
7
-
8
- export interface SendTemplatePayload {
9
- /** Phone number in E.164 format. */
10
- phone: string;
11
- /** Name of the pre-approved WhatsApp template. */
12
- templateName: string;
13
- /** Language code (defaults to "en"). */
14
- languageCode?: string;
15
- /** Key-value pairs matching variables in your template (e.g., {{1}}, {{2}}). */
16
- variables?: Record<string, string>;
17
- /** Explicitly resolved variables if bypassing the internal resolution engine. */
18
- resolvedVariables?: any[];
19
- }
20
-
21
- export class WhatsApp extends APIResource {
22
- public messages: Messages;
23
- public conversations: Conversations;
24
- public broadcasts: Broadcasts;
25
- public templates: Templates;
26
-
27
- constructor(client: AxiosInstance) {
28
- super(client);
29
- this.messages = new Messages(client);
30
- this.conversations = new Conversations(client);
31
- this.broadcasts = new Broadcasts(client);
32
- this.templates = new Templates(client);
33
- }
34
-
35
- /**
36
- * Upload an asset directly to chat storage.
37
- */
38
- async upload<T = any>(file: Blob | Buffer | File | any, filename: string) {
39
- const form = new FormData();
40
- form.append("file", file, filename);
41
- return this.post<T>("/api/saas/chat/upload", form, {
42
- headers:
43
- typeof (form as any).getHeaders === "function" ? (form as any).getHeaders() : undefined,
44
- });
45
- }
46
-
47
- /**
48
- * Dispatch a WhatsApp template message directly to a specific phone number.
49
- * Bypasses the automation queue for immediate high-priority delivery.
50
- *
51
- * @param payload - The template dispatch payload.
52
- * @returns Information about the dispatched message.
53
- */
54
- async sendTemplate(payload: SendTemplatePayload): Promise<{
55
- success: boolean;
56
- messageId?: string;
57
- templateName?: string;
58
- resolvedVariables?: any[];
59
- }> {
60
- return this.post<{
61
- success: boolean;
62
- messageId?: string;
63
- templateName?: string;
64
- resolvedVariables?: any[];
65
- }>("/api/saas/marketing/whatsapp/send-template", payload);
66
- }
67
- }
@@ -1,239 +0,0 @@
1
- import { APIResource } from "../../resource";
2
-
3
- /**
4
- * Parameters for sending a free-form WhatsApp message.
5
- */
6
- export interface SendMessageParams {
7
- /**
8
- * Recipient's phone number in E.164 format.
9
- * @example "+919876543210"
10
- */
11
- to?: string;
12
- /**
13
- * The unique ID of the conversation. If supplied, `to` is resolved automatically.
14
- */
15
- conversationId?: string;
16
- /** Plain text body of the message. */
17
- text?: string;
18
- /** Public URL of the media asset to send. */
19
- mediaUrl?: string;
20
- /** MIME category of the media. */
21
- mediaType?: "image" | "video" | "audio" | "document";
22
- /** The `messageId` of the message to reply to (quoted replies). */
23
- replyToId?: string;
24
- /** Filename shown to the recipient (required for `document` type). */
25
- filename?: string;
26
- /** Arbitrary metadata stored with the message record. */
27
- metadata?: Record<string, any>;
28
- /** Template name for template messages. */
29
- templateName?: string;
30
- /** Template language for template messages. */
31
- templateLanguage?: string;
32
- /** Alternative language parameter. */
33
- language?: string;
34
- /** Template variables. */
35
- variables?: string[];
36
- }
37
-
38
- /**
39
- * Parameters for sending a pre-approved WhatsApp Business template.
40
- */
41
- export interface SendTemplateParams {
42
- /**
43
- * Recipient's phone number in E.164 format.
44
- * @example "+919876543210"
45
- */
46
- to?: string;
47
- /**
48
- * The unique ID of the conversation.
49
- */
50
- conversationId?: string;
51
- /** The exact template name as approved in Meta Business Manager. */
52
- templateName: string;
53
- /**
54
- * BCP-47 language code for the template.
55
- * @default "en_US"
56
- */
57
- language?: string;
58
- /**
59
- * Ordered array of variable substitutions for template placeholders.
60
- * @example ["Alice", "10 April 2026", "10:00 AM"]
61
- */
62
- variables?: string[];
63
- /** Optional header media URL (for templates with media headers). */
64
- mediaUrl?: string;
65
- /** Media type for the header (e.g. "image", "document"). */
66
- mediaType?: string;
67
- /** User ID of the agent sending the message. */
68
- userId?: string;
69
- /** Optional filename for media headers. */
70
- filename?: string;
71
- /** Template language for template messages. */
72
- templateLanguage?: string;
73
- }
74
-
75
- /**
76
- * WhatsApp outbound messaging resource.
77
- *
78
- * Access via `ecod.whatsapp.messages`.
79
- *
80
- * @example
81
- * ```typescript
82
- * await ecod.whatsapp.messages.send({
83
- * to: "+919876543210",
84
- * text: "Your appointment is confirmed!",
85
- * });
86
- * ```
87
- */
88
- /**
89
- * Resolved media metadata returned by any upload endpoint.
90
- * `variants` is only present for raster images (JPEG, PNG, WebP, AVIF, GIF).
91
- */
92
- export interface ChatMediaMeta {
93
- /** Raw CDN URL — always present, all media types */
94
- url: string;
95
- /** Categorical type — "image" | "video" | "audio" | "document" */
96
- type: "image" | "video" | "audio" | "document";
97
- /** Cloudflare-optimised variant URLs. Only present for raster images. */
98
- variants?: {
99
- /** 150px WebP — use for list thumbnails and chat bubbles */
100
- thumb: string;
101
- /** 600px WebP — use for modal previews */
102
- medium: string;
103
- /** 1200px WebP — use for hero or full-screen views */
104
- full: string;
105
- /** Original CDN URL, no transformation */
106
- raw: string;
107
- };
108
- /** Storage key within the tenant bucket */
109
- key?: string;
110
- /** Original filename */
111
- fileName?: string;
112
- }
113
-
114
- export class Messages extends APIResource {
115
- /**
116
- * Send a free-text or media message to a WhatsApp number.
117
- *
118
- * For text-only messages, supply `text`. For media, supply `mediaUrl`
119
- * and `mediaType`. Both can be combined in a single message.
120
- *
121
- * @param params - Message parameters including recipient, text, and media.
122
- * @returns The created message record from the database.
123
- *
124
- * @example Send a simple text message
125
- * ```typescript
126
- * await erixClient.whatsapp.messages.send({
127
- * to: "+919876543210",
128
- * text: "Hello from Ecodrix!",
129
- * });
130
- * ```
131
- *
132
- * @example Send an image with a caption
133
- * ```typescript
134
- * await erixClient.whatsapp.messages.send({
135
- * to: "+919876543210",
136
- * text: "Check out this flyer",
137
- * mediaUrl: "https://example.com/flyer.jpg",
138
- * mediaType: "image",
139
- * });
140
- * ```
141
- */
142
- async send<T = any>(params: SendMessageParams) {
143
- return this.post<T>("/api/saas/chat/send", params);
144
- }
145
-
146
- /**
147
- * Send a pre-approved WhatsApp Business template message.
148
- *
149
- * Templates must be approved in Meta Business Manager before they can be sent.
150
- * Variable placeholders (e.g., {{1}}, {{2}}) are replaced with values from the
151
- * `variables` array in order.
152
- *
153
- * @param params - Template message configuration (name, language, variables).
154
- * @returns The created message record.
155
- *
156
- * @example
157
- * ```typescript
158
- * await erixClient.whatsapp.messages.sendTemplate({
159
- * to: "+919876543210",
160
- * templateName: "welcome_user",
161
- * language: "en_US",
162
- * variables: ["Alice"], // Replaces {{1}} in template
163
- * });
164
- * ```
165
- */
166
- async sendTemplate<T = any>(params: SendTemplateParams) {
167
- return this.post<T>("/api/saas/chat/send", {
168
- ...params,
169
- templateLanguage: params.language || params.templateLanguage || "en_US",
170
- });
171
- }
172
-
173
- /**
174
- * Star or unstar a message.
175
- *
176
- * @param messageId - The ID of the message.
177
- * @param isStarred - Boolean indicating whether to star or unstar.
178
- */
179
- async star<T = any>(messageId: string, isStarred: boolean) {
180
- return this.post<T>(`/api/saas/chat/messages/${messageId}/star`, {
181
- isStarred,
182
- });
183
- }
184
-
185
- /**
186
- * React to a message with an emoji.
187
- *
188
- * @param messageId - The ID of the message.
189
- * @param reaction - The emoji (e.g. "👍") to react with, or empty string to remove.
190
- */
191
- async react<T = any>(messageId: string, reaction: string) {
192
- return this.post<T>(`/api/saas/chat/messages/${messageId}/react`, {
193
- reaction,
194
- });
195
- }
196
-
197
- /**
198
- * Mark all messages in a conversation as read (double-tick).
199
- *
200
- * @param conversationId - The conversation to mark as read.
201
- *
202
- * @example
203
- * ```typescript
204
- * await ecod.whatsapp.messages.markRead("conv_64abc...");
205
- * ```
206
- */
207
- async markRead(conversationId: string) {
208
- return this.post(`/api/saas/chat/conversations/${conversationId}/read`);
209
- }
210
-
211
- /**
212
- * Upload a media file for WhatsApp chat.
213
- *
214
- * Works with any file type — image, video, audio, or document.
215
- * For raster images the response includes Cloudflare-optimised `variants`
216
- * (thumb 150px, medium 600px, full 1200px). Non-image types return only `url`.
217
- *
218
- * @param file - The file to upload (File, Blob, or Buffer).
219
- * @returns Full media metadata `{ url, type, variants?, key, fileName }`.
220
- *
221
- * @example
222
- * ```typescript
223
- * const file = input.files[0];
224
- * const { data } = await ecod.whatsapp.messages.upload(file);
225
- * // For images: data.variants.thumb → 150px WebP from Cloudflare
226
- * // For video/audio: use data.url directly in <video> or <audio>
227
- * ```
228
- */
229
- async upload(file: any): Promise<{ success: boolean; data: ChatMediaMeta }> {
230
- const formData = new FormData();
231
- formData.append("file", file);
232
-
233
- return this.post<{ success: boolean; data: ChatMediaMeta }>("/api/saas/chat/upload", formData, {
234
- headers: {
235
- "Content-Type": "multipart/form-data",
236
- },
237
- });
238
- }
239
- }
@@ -1,218 +0,0 @@
1
- import { APIResource } from "../../resource";
2
- import type { ResourceManifest } from "../../types/metadata";
3
-
4
- export interface TemplateMapping {
5
- mappings: any[];
6
- onEmptyVariable: string;
7
- }
8
-
9
- export class Templates extends APIResource {
10
- /**
11
- * List all WhatsApp message templates in the tenant database.
12
- *
13
- * @param params - Optional filter parameters (status, mappingStatus, channel).
14
- * @returns List of message templates.
15
- * @example
16
- * ```typescript
17
- * const templates = await erixClient.whatsapp.templates.list({ status: "APPROVED" });
18
- * ```
19
- */
20
- async list<T = any>(params?: {
21
- status?: string;
22
- mappingStatus?: string;
23
- channel?: string;
24
- }) {
25
- return this.get<T>("/api/saas/chat/templates", { params } as any);
26
- }
27
-
28
- /**
29
- * Synchronize templates from the Meta WhatsApp Business API.
30
- * This updates the local database with the latest template status and content from Meta.
31
- *
32
- * @returns Success status of the sync operation.
33
- * @example
34
- * ```typescript
35
- * await erixClient.whatsapp.templates.sync();
36
- * ```
37
- */
38
- async sync<T = any>() {
39
- return this.post<T>("/api/saas/chat/templates/sync", {});
40
- }
41
-
42
- /**
43
- * Retrieve details of a specific WhatsApp template.
44
- *
45
- * @param templateIdentifier - The name or ID of the template.
46
- * @returns Detailed template object including components and status.
47
- * @example
48
- * ```typescript
49
- * const template = await erixClient.whatsapp.templates.retrieve("welcome_message");
50
- * ```
51
- */
52
- async retrieve<T = any>(templateIdentifier: string) {
53
- return this.get<T>(`/api/saas/chat/templates/${encodeURIComponent(templateIdentifier)}`);
54
- }
55
-
56
- /**
57
- * Create a new WhatsApp template manually (Draft).
58
- *
59
- * @param payload - Template configuration (name, category, language, components).
60
- * @example
61
- * ```typescript
62
- * await erixClient.whatsapp.templates.create({
63
- * name: "new_promotion",
64
- * category: "MARKETING",
65
- * language: "en_US",
66
- * components: [...]
67
- * });
68
- * ```
69
- */
70
- async create<T = any>(payload: any) {
71
- return this.post<T>("/api/saas/chat/templates", payload);
72
- }
73
-
74
- /**
75
- * Update an existing WhatsApp template.
76
- *
77
- * @param templateId - The unique ID of the template.
78
- * @param payload - Updated template configuration.
79
- */
80
- async update<T = any>(templateId: string, payload: any) {
81
- return this.put<T>(`/api/saas/chat/templates/${templateId}`, payload);
82
- }
83
-
84
- /**
85
- * Delete a WhatsApp template from both the local database and Meta (if specified).
86
- *
87
- * @param templateName - The name of the template to delete.
88
- * @param force - If true, attempts to delete from Meta API as well.
89
- * @example
90
- * ```typescript
91
- * await erixClient.whatsapp.templates.deleteTemplate("old_template", true);
92
- * ```
93
- */
94
- async deleteTemplate<T = any>(templateName: string, force?: boolean) {
95
- return this.deleteRequest<T>(
96
- `/api/saas/chat/templates/${encodeURIComponent(templateName)}${force ? "?force=true" : ""}`,
97
- );
98
- }
99
-
100
- /**
101
- * List available configuration options for variable mapping.
102
- *
103
- * @example
104
- * ```typescript
105
- * const config = await erixClient.whatsapp.templates.mappingConfig();
106
- * ```
107
- */
108
- async mappingConfig<T = any>() {
109
- return this.get<T>("/api/saas/chat/templates/mapping/config");
110
- }
111
-
112
- /**
113
- * List CRM collections available for variable mapping (Leads, Deals, etc.).
114
- */
115
- async collections<T = any>() {
116
- return this.get<T>("/api/saas/chat/templates/collections");
117
- }
118
-
119
- /**
120
- * List fields for a specific CRM collection to be used in mapping.
121
- *
122
- * @param collectionName - The name of the CRM collection.
123
- */
124
- async collectionFields<T = any>(collectionName: string) {
125
- return this.get<T>(
126
- `/api/saas/chat/templates/collections/${encodeURIComponent(collectionName)}/fields`,
127
- );
128
- }
129
-
130
- /**
131
- * Update variable mappings for a template to automate personalization.
132
- *
133
- * @param templateName - Name of the template.
134
- * @param payload - Mapping definitions.
135
- */
136
- async updateMapping<T = any>(templateName: string, payload: TemplateMapping) {
137
- return this.put<T>(
138
- `/api/saas/chat/templates/${encodeURIComponent(templateName)}/mapping`,
139
- payload,
140
- );
141
- }
142
-
143
- /**
144
- * Validate if a template is ready for automated sending based on its mappings.
145
- */
146
- async validate<T = any>(templateName: string) {
147
- return this.get<T>(`/api/saas/chat/templates/${encodeURIComponent(templateName)}/validate`);
148
- }
149
-
150
- /**
151
- * Preview a template resolution with sample data.
152
- *
153
- * @param templateName - Name of the template.
154
- * @param context - Lead data or variable overrides for preview.
155
- * @example
156
- * ```typescript
157
- * const preview = await erixClient.whatsapp.templates.preview("welcome", {
158
- * lead: { firstName: "Alice" }
159
- * });
160
- * ```
161
- */
162
- async preview<T = any>(templateName: string, context: { lead?: any; vars?: any }) {
163
- return this.post<T>(`/api/saas/chat/templates/${encodeURIComponent(templateName)}/preview`, {
164
- context,
165
- });
166
- }
167
-
168
- /**
169
- * Introspect a template and provide a manifest of its required variables.
170
- *
171
- * This is used by Erix React to build dynamic "Mapping Forms" where users
172
- * can connect CRM fields to WhatsApp variables.
173
- *
174
- * @param templateIdentifier - The name or ID of the template.
175
- */
176
- async getVariableManifest(templateIdentifier: string): Promise<ResourceManifest> {
177
- const template: any = await this.retrieve(templateIdentifier);
178
- const components = Array.isArray(template.data?.components) ? template.data.components : [];
179
-
180
- const fields: any[] = [];
181
-
182
- for (const comp of components) {
183
- // Look for {{n}} pattern in text components
184
- if (comp.text) {
185
- const vars = comp.text.match(/{{(\d+)}}/g);
186
- if (vars) {
187
- for (const v of vars) {
188
- const index = v.replace(/{{|}}/g, "");
189
- fields.push({
190
- key: `var_${index}`,
191
- label: `${comp.type} Var {{${index}}}`,
192
- type: "string",
193
- required: true,
194
- group: comp.type,
195
- description: `Variable placeholder in template ${comp.type}`,
196
- });
197
- }
198
- }
199
- }
200
- }
201
-
202
- return {
203
- name: `Template variables: ${template.data?.name || templateIdentifier}`,
204
- fields,
205
- uiHints: {
206
- icon: "Variables",
207
- primaryColor: "#059669",
208
- },
209
- };
210
- }
211
-
212
- /**
213
- * Check which automations or sequences are currently using this template.
214
- */
215
- async checkUsage<T = any>(templateName: string) {
216
- return this.get<T>(`/api/saas/chat/templates/${encodeURIComponent(templateName)}/usage`);
217
- }
218
- }
@@ -1,71 +0,0 @@
1
- /**
2
- * The specific UI control type suggested for a field.
3
- */
4
- export type FieldType =
5
- | "string"
6
- | "number"
7
- | "boolean"
8
- | "date"
9
- | "datetime"
10
- | "select"
11
- | "multi-select"
12
- | "phone"
13
- | "email"
14
- | "currency"
15
- | "json"
16
- | "textarea"
17
- | "richtext"
18
- | "file"
19
- | "image";
20
-
21
- /**
22
- * Metadata defining a single field within a resource.
23
- * Used by UI kits to automatically generate forms and validation logic.
24
- */
25
- export interface FieldManifest {
26
- /** The technical key name used in API requests. */
27
- key: string;
28
- /** Human-readable label (localized if possible). */
29
- label: string;
30
- /** Suggested UI type. */
31
- type: FieldType;
32
- /** Short hint/placeholder text. */
33
- description?: string;
34
- /** Whether the field is required for creation. */
35
- required: boolean;
36
- /** Whether the field should be hidden from standard create/edit forms. */
37
- hidden?: boolean;
38
- /** If type is 'select', the available options. */
39
- options?: Array<{ label: string; value: string | number }>;
40
- /** Validation constraints. */
41
- validation?: {
42
- regex?: string;
43
- min?: number;
44
- max?: number;
45
- message?: string;
46
- };
47
- /** Whether the field is read-only. */
48
- readOnly?: boolean;
49
- /** UI grouping/category name. */
50
- group?: string;
51
- }
52
-
53
- /**
54
- * A logical grouping of fields and UI hints for a top-level resource.
55
- * Provides a 'blueprint' for erix-react components.
56
- */
57
- export interface ResourceManifest {
58
- /** The unique name of the resource (e.g., 'Lead', 'Template'). */
59
- name: string;
60
- /** All available fields for this resource. */
61
- fields: FieldManifest[];
62
- /** Suggested UI configurations. */
63
- uiHints?: {
64
- icon?: string;
65
- primaryColor?: string;
66
- /** Default sort order. */
67
- defaultSort?: { field: string; direction: "asc" | "desc" };
68
- /** Fields to show in a compact table view. */
69
- summaryFields?: string[];
70
- };
71
- }