@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,178 +0,0 @@
1
- import { APIResource } from "../resource";
2
-
3
- /**
4
- * Filters for querying event and automation execution logs.
5
- */
6
- export interface LogFilter {
7
- /** Page number for pagination (1-indexed). */
8
- page?: number;
9
- /** Maximum number of records to return per page. */
10
- limit?: number;
11
- /**
12
- * Filter by automation trigger name.
13
- * @example "lead_created" | "appointment_booked"
14
- */
15
- trigger?: string;
16
- /**
17
- * Filter by execution status.
18
- * @example "success" | "failed" | "pending"
19
- */
20
- status?: string;
21
- /** Filter logs associated with a specific phone number. */
22
- phone?: string;
23
- /** Start of the date range (inclusive). ISO 8601 or Date object. */
24
- startDate?: string | Date;
25
- /** End of the date range (inclusive). ISO 8601 or Date object. */
26
- endDate?: string | Date;
27
- }
28
-
29
- /**
30
- * Automation event log and provider callback resource.
31
- *
32
- * Access via `ecod.notifications`.
33
- *
34
- * This resource is **read-only**. It exposes platform audit trails — useful
35
- * for debugging automation failures, monitoring webhook callbacks, and
36
- * building internal ops dashboards.
37
- *
38
- * @example
39
- * ```typescript
40
- * // Find failed automations in April
41
- * const { data } = await ecod.notifications.listLogs({
42
- * status: "failed",
43
- * startDate: "2026-04-01",
44
- * endDate: "2026-04-30",
45
- * });
46
- * ```
47
- */
48
- export class Notifications extends APIResource {
49
- /**
50
- * List automation execution logs with optional filtering.
51
- *
52
- * Each log entry represents one automation run triggered by a platform event.
53
- * Filter by `status: "failed"` to build a failure alerting pipeline.
54
- *
55
- * @param params - Optional filter criteria.
56
- * @returns Paginated list of event log objects.
57
- *
58
- * @example
59
- * ```typescript
60
- * const { data: failed } = await ecod.notifications.listLogs({
61
- * status: "failed",
62
- * trigger: "lead_created",
63
- * limit: 50,
64
- * });
65
- * ```
66
- */
67
- async listLogs(params?: LogFilter) {
68
- return this.get("/api/saas/events/logs", { params } as any);
69
- }
70
-
71
- /**
72
- * Retrieve the full details for a single automation event log entry.
73
- *
74
- * @param logId - The unique log ID.
75
- * @returns A single event log document including the payload and error trace.
76
- *
77
- * @example
78
- * ```typescript
79
- * const { data } = await ecod.notifications.retrieveLog("log_64abc...");
80
- * console.log(data.error); // → "Provider timeout after 30s"
81
- * ```
82
- */
83
- async retrieveLog(logId: string) {
84
- return this.get(`/api/saas/events/logs/${logId}`);
85
- }
86
-
87
- /**
88
- * Get a summary statistics object for automation event execution.
89
- *
90
- * @param params - Optional date range for the summary window.
91
- * @returns `{ total, success, failed, pending }` counts.
92
- *
93
- * @example
94
- * ```typescript
95
- * const { data: stats } = await ecod.notifications.getStats({
96
- * startDate: "2026-04-01",
97
- * endDate: "2026-04-30",
98
- * });
99
- * console.log(`Failed: ${stats.failed} / ${stats.total}`);
100
- * ```
101
- */
102
- async getStats(params?: { startDate?: string; endDate?: string }) {
103
- return this.get("/api/saas/events/stats", { params } as any);
104
- }
105
-
106
- /**
107
- * List external provider webhook callback logs.
108
- *
109
- * These are inbound HTTP callbacks from third-party providers
110
- * (payment gateways, email services, etc.) stored for audit purposes.
111
- *
112
- * @param params - Pagination and date filter options.
113
- * @returns Paginated list of callback log records.
114
- *
115
- * @example
116
- * ```typescript
117
- * const { data } = await ecod.notifications.listCallbacks({ limit: 20 });
118
- * ```
119
- */
120
- async listCallbacks(params?: Omit<LogFilter, "trigger" | "phone">) {
121
- return this.get("/api/saas/callbacks/logs", { params } as any);
122
- }
123
-
124
- // --- CRM Notifications (Alerts) ---
125
- // Backend routes mounted at /api/crm — see crm.router.ts + notification.routes.ts
126
-
127
- /**
128
- * List unread CRM notifications and alerts (e.g., lead assignments, system alerts).
129
- *
130
- * @param params - Optional filters (limit, unreadOnly).
131
- * @returns Paginated list of notification objects.
132
- * @example
133
- * ```typescript
134
- * const alerts = await erixClient.notifications.listAlerts({ unreadOnly: true });
135
- * ```
136
- */
137
- async listAlerts<T = any>(params?: { limit?: number; unreadOnly?: boolean }) {
138
- return this.get<T>("/api/crm/notifications", { params } as any);
139
- }
140
-
141
- /**
142
- * Dismiss/mark a specific notification alert as read.
143
- *
144
- * @param notificationId - The unique ID of the notification.
145
- * @example
146
- * ```typescript
147
- * await erixClient.notifications.dismissAlert("alert_123");
148
- * ```
149
- */
150
- async dismissAlert<T = any>(notificationId: string) {
151
- return this.patch<T>(`/api/crm/notifications/${notificationId}/dismiss`);
152
- }
153
-
154
- /**
155
- * Clear all notifications for the current tenant immediately.
156
- *
157
- * @example
158
- * ```typescript
159
- * await erixClient.notifications.clearAllAlerts();
160
- * ```
161
- */
162
- async clearAllAlerts<T = any>() {
163
- return this.deleteRequest<T>("/api/crm/notifications/clear-all");
164
- }
165
-
166
- /**
167
- * Retry an action from a notification (e.g. failed automation send).
168
- *
169
- * @param notificationId - The unique ID of the notification.
170
- * @example
171
- * ```typescript
172
- * await erixClient.notifications.retryAction("alert_123");
173
- * ```
174
- */
175
- async retryAction<T = any>(notificationId: string) {
176
- return this.post<T>(`/api/crm/notifications/${notificationId}/retry`, {});
177
- }
178
- }
@@ -1,64 +0,0 @@
1
- import { APIResource } from "../resource";
2
-
3
- export interface JobStats {
4
- waiting: number;
5
- active: number;
6
- completed: number;
7
- failed: number;
8
- delayed: number;
9
- }
10
-
11
- export class Queue extends APIResource {
12
- /**
13
- * List all background jobs that have failed execution.
14
- *
15
- * @returns Array of failed job objects.
16
- * @example
17
- * ```typescript
18
- * const failed = await erixClient.queue.listFailed();
19
- * ```
20
- */
21
- async listFailed<T = any>() {
22
- return this.get<T>("/api/saas/admin/queue/failed");
23
- }
24
-
25
- /**
26
- * Get real-time health statistics for the background job queue (waiting, active, failed).
27
- *
28
- * @returns Queue statistics summary.
29
- * @example
30
- * ```typescript
31
- * const stats = await erixClient.queue.getStats();
32
- * console.log(`Active Jobs: ${stats.active}`);
33
- * ```
34
- */
35
- async getStats<T = JobStats>() {
36
- return this.get<T>("/api/saas/admin/queue/stats");
37
- }
38
-
39
- /**
40
- * Manually retry a failed background job.
41
- *
42
- * @param jobId - The unique ID of the failed job.
43
- * @example
44
- * ```typescript
45
- * await erixClient.queue.retryJob("job_123");
46
- * ```
47
- */
48
- async retryJob<T = any>(jobId: string) {
49
- return this.post<T>(`/api/saas/admin/queue/${jobId}/retry`, {});
50
- }
51
-
52
- /**
53
- * Remove a job from the queue.
54
- *
55
- * @param jobId - The unique ID of the job to delete.
56
- * @example
57
- * ```typescript
58
- * await erixClient.queue.deleteJob("job_123");
59
- * ```
60
- */
61
- async deleteJob<T = any>(jobId: string) {
62
- return this.deleteRequest<T>(`/api/saas/admin/queue/${jobId}`);
63
- }
64
- }
@@ -1,101 +0,0 @@
1
- import { APIResource } from "../resource";
2
-
3
- export class Folders extends APIResource {
4
- /**
5
- * Create a new folder in the tenant's cloud storage.
6
- *
7
- * @param name - The name of the folder to create.
8
- * @example
9
- * ```typescript
10
- * await erixClient.storage.folders.create("Invoices");
11
- * ```
12
- */
13
- async create<T = any>(name: string) {
14
- return this.post<T>("/api/saas/storage/folders", { name });
15
- }
16
-
17
- /**
18
- * Delete a folder and its contents.
19
- */
20
- async delete<T = any>(folderPath: string) {
21
- return this.deleteRequest<T>(`/api/saas/storage/folders/${encodeURIComponent(folderPath)}`);
22
- }
23
- }
24
-
25
- export class Files extends APIResource {
26
- /**
27
- * List files within a specific folder.
28
- *
29
- * @param folder - The folder name or path.
30
- * @param params - Optional year/month filters for organized storage.
31
- * @example
32
- * ```typescript
33
- * const files = await erixClient.storage.files.list("Invoices", { year: "2026" });
34
- * ```
35
- */
36
- async list<T = any>(folder: string, params?: { year?: string; month?: string }) {
37
- return this.get<T>(`/api/saas/storage/files/${folder}`, { params } as any);
38
- }
39
-
40
- /**
41
- * Get a presigned upload URL for direct-to-cloud browser uploads.
42
- * This allows the client to upload files directly to R2/S3 without hitting the backend.
43
- *
44
- * @param params - Upload parameters (folder, filename, contentType).
45
- * @example
46
- * ```typescript
47
- * const { data } = await erixClient.storage.files.getUploadUrl({
48
- * folder: "Invoices",
49
- * filename: "inv_1.pdf",
50
- * contentType: "application/pdf"
51
- * });
52
- * // Now use data.url with a PUT request
53
- * ```
54
- */
55
- async getUploadUrl<T = any>(params: {
56
- folder: string;
57
- filename: string;
58
- contentType: string;
59
- }) {
60
- return this.post<T>("/api/saas/storage/upload-url", params);
61
- }
62
-
63
- /**
64
- * Notify backend after a successful direct browser upload.
65
- */
66
- async confirmUpload<T = any>(params: { key: string; sizeBytes: number }) {
67
- return this.post<T>("/api/saas/storage/confirm-upload", params);
68
- }
69
-
70
- /**
71
- * Get a presigned download URL for an R2 key.
72
- */
73
- async getDownloadUrl<T = any>(key: string) {
74
- return this.post<T>("/api/saas/storage/download-url", { key });
75
- }
76
-
77
- /**
78
- * Delete a file by key.
79
- */
80
- async delete(key: string) {
81
- return this.deleteRequest("/api/saas/storage/files", { params: { key } } as any);
82
- }
83
- }
84
-
85
- export class Storage extends APIResource {
86
- public folders: Folders;
87
- public files: Files;
88
-
89
- constructor(client: any) {
90
- super(client);
91
- this.folders = new Folders(client);
92
- this.files = new Files(client);
93
- }
94
-
95
- /**
96
- * Get tenant storage usage and quota limitations.
97
- */
98
- async usage<T = any>() {
99
- return this.get<T>("/api/saas/storage/usage");
100
- }
101
- }
@@ -1,80 +0,0 @@
1
- import { APIError } from "../error";
2
-
3
- export class WebhookSignatureError extends APIError {
4
- constructor(message: string) {
5
- super(message, 400, "invalid_signature");
6
- this.name = "WebhookSignatureError";
7
- }
8
- }
9
-
10
- /**
11
- * Validates and constructs webhook events sent by the ECODrIx platform.
12
- * Ensures the payload has not been tampered with.
13
- *
14
- * @example
15
- * ```typescript
16
- * import { ecod } from "./services/ecodrix";
17
- *
18
- * app.post("/api/webhooks", async (req, res) => {
19
- * try {
20
- * const event = await ecod.webhooks.constructEvent(
21
- * req.rawBody,
22
- * req.headers["x-ecodrix-signature"],
23
- * process.env.ECOD_WEBHOOK_SECRET
24
- * );
25
- * console.log("Verified event:", event.type);
26
- * res.send({ received: true });
27
- * } catch (err) {
28
- * res.status(400).send(`Webhook Error: ${err.message}`);
29
- * }
30
- * });
31
- * ```
32
- */
33
- export class Webhooks {
34
- /**
35
- * Cryptographically validates a webhook payload.
36
- * Note: This method dynamically imports Node's `crypto` module, meaning it will only execute gracefully in a Server environment.
37
- *
38
- * @param payload - The raw request body as a string or Buffer.
39
- * @param signature - The `x-ecodrix-signature` header value.
40
- * @param secret - The webhook signing secret for your tenant.
41
- * @returns The parsed JSON object of the event if the signature is valid.
42
- * @throws WebhookSignatureError if the validation fails.
43
- */
44
- public async constructEvent(
45
- payload: string | Buffer,
46
- signature: string | string[] | undefined,
47
- secret: string,
48
- ): Promise<any> {
49
- if (!signature) {
50
- throw new WebhookSignatureError("No webhook signature provided");
51
- }
52
-
53
- let sig = Array.isArray(signature) ? signature[0] : signature;
54
- if (sig.startsWith("sha256=")) {
55
- sig = sig.slice(7);
56
- }
57
-
58
- try {
59
- // Dynamic import ensures Isomorphic bundles (like Vite UI) don't crash on import,
60
- // and only throw if someone incorrectly tries to verify a webhook in the browser.
61
- const crypto = await import("node:crypto");
62
-
63
- const hmac = crypto.createHmac("sha256", secret);
64
- const digest = hmac.update(payload).digest("hex");
65
-
66
- const isValid = crypto.timingSafeEqual(Buffer.from(digest), Buffer.from(sig));
67
-
68
- if (!isValid) {
69
- throw new WebhookSignatureError("Invalid webhook signature provided");
70
- }
71
-
72
- return JSON.parse(payload.toString("utf8"));
73
- } catch (error: any) {
74
- if (error instanceof WebhookSignatureError) {
75
- throw error;
76
- }
77
- throw new WebhookSignatureError(`Webhook payload parsing failed: ${error.message}`);
78
- }
79
- }
80
- }
@@ -1,94 +0,0 @@
1
- import { APIResource } from "../../resource";
2
-
3
- export interface CreateBroadcastParams {
4
- /** Optional name for the broadcast campaign */
5
- name?: string;
6
- /** Name of the Meta template to send */
7
- templateName: string;
8
- /** Language code (defaults to en_US) */
9
- templateLanguage?: string;
10
- /** List of recipients with their phone numbers and variable overrides */
11
- recipients: {
12
- phone: string;
13
- variables?: string[];
14
- }[];
15
- }
16
-
17
- export class Broadcasts extends APIResource {
18
- /**
19
- * List past and active WhatsApp broadcast campaigns.
20
- *
21
- * @param params - Optional filter parameters (page, limit, status).
22
- * @returns Paginated list of broadcast records.
23
- * @example
24
- * ```typescript
25
- * const broadcasts = await erixClient.whatsapp.broadcasts.list({ limit: 10 });
26
- * ```
27
- */
28
- async list<T = any>(params?: Record<string, any>) {
29
- return this.get<T>("/api/saas/chat/broadcasts", { params } as any);
30
- }
31
-
32
- /**
33
- * Retrieve full details and real-time stats for a specific broadcast campaign.
34
- *
35
- * @param id - The unique identifier of the broadcast.
36
- * @returns The broadcast record including sent/failed counts.
37
- * @example
38
- * ```typescript
39
- * const stats = await erixClient.whatsapp.broadcasts.retrieve("bc_123");
40
- * console.log(`Success Rate: ${(stats.sentCount / stats.totalRecipients) * 100}%`);
41
- * ```
42
- */
43
- async retrieve<T = any>(id: string) {
44
- return this.get<T>(`/api/saas/chat/broadcasts/${id}`);
45
- }
46
-
47
- /**
48
- * Create a new broadcast campaign to send template messages to multiple recipients.
49
- *
50
- * @param params - Broadcast configuration (name, templateName, recipients).
51
- * @returns The newly created broadcast record.
52
- * @example
53
- * ```typescript
54
- * await erixClient.whatsapp.broadcasts.create({
55
- * name: "Spring Sale",
56
- * templateName: "promo_code",
57
- * recipients: [
58
- * { phone: "+919876543210", variables: ["SAVE10"] }
59
- * ]
60
- * });
61
- * ```
62
- */
63
- async create<T = any>(params: CreateBroadcastParams) {
64
- return this.post<T>("/api/saas/chat/broadcast", params);
65
- }
66
-
67
- /**
68
- * Update broadcast metadata, such as its name or administrative status.
69
- *
70
- * @param id - The unique ID of the broadcast.
71
- * @param data - The fields to update (name, status).
72
- * @example
73
- * ```typescript
74
- * await erixClient.whatsapp.broadcasts.update("bc_123", { name: "Revised Spring Sale" });
75
- * ```
76
- */
77
- async update<T = any>(id: string, data: { name?: string; status?: string }) {
78
- return this.patch<T>(`/api/saas/chat/broadcasts/${id}`, data);
79
- }
80
-
81
- /**
82
- * Delete a broadcast campaign record.
83
- * Note: This does not cancel messages already in flight but removes the record from the dashboard.
84
- *
85
- * @param id - The unique ID of the broadcast.
86
- * @example
87
- * ```typescript
88
- * await erixClient.whatsapp.broadcasts.delete("bc_123");
89
- * ```
90
- */
91
- async delete<T = any>(id: string) {
92
- return this.deleteRequest<T>(`/api/saas/chat/broadcasts/${id}`);
93
- }
94
- }
@@ -1,128 +0,0 @@
1
- import { APIResource } from "../../resource";
2
-
3
- export interface ListParams {
4
- limit?: number;
5
- before?: string;
6
- after?: string;
7
- status?: string;
8
- }
9
-
10
- export class Conversations extends APIResource {
11
- /**
12
- * List conversations for the tenant.
13
- * @deprecated Use `list` method from `ErixClient` instead.
14
- * @param params - List parameters.
15
- * @returns List of conversations.
16
- * @example
17
- * ```typescript
18
- * import { ErixClient } from "erix-react";
19
- * const erixClient = new ErixClient({ apiKey: "YOUR_API_KEY" });
20
- * const conversations = await erixClient.whatsapp.conversations.list();
21
- * ```
22
- */
23
- async list<T = any>(params?: ListParams) {
24
- return this.get<T>("/api/saas/chat/conversations", { params } as any);
25
- }
26
-
27
- /**
28
- * Create a new conversation explicitly.
29
- *
30
- * @param params - Conversation details.
31
- * @example
32
- * ```typescript
33
- * const conversation = await erixClient.whatsapp.conversations.create({
34
- * phone: "+919876543210",
35
- * name: "John Doe"
36
- * });
37
- * ```
38
- */
39
- async create<T = any>(params: { phone: string; name?: string }) {
40
- return this.post<T>("/api/saas/chat/conversations", params);
41
- }
42
-
43
- /**
44
- * Retrieve details of a specific conversation.
45
- *
46
- * @param conversationId - The unique ID of the conversation.
47
- * @example
48
- * ```typescript
49
- * const conversation = await erixClient.whatsapp.conversations.retrieve("conv_123");
50
- * ```
51
- */
52
- async retrieve<T = any>(conversationId: string) {
53
- return this.get<T>(`/api/saas/chat/conversations/${conversationId}`);
54
- }
55
-
56
- /**
57
- * Get messages for a specific conversation.
58
- *
59
- * @param conversationId - The unique ID of the conversation.
60
- * @param params - Pagination and filter parameters.
61
- * @example
62
- * ```typescript
63
- * const messages = await erixClient.whatsapp.conversations.messages("conv_123", { limit: 50 });
64
- * ```
65
- */
66
- async messages<T = any>(conversationId: string, params?: ListParams) {
67
- return this.get<T>(`/api/saas/chat/conversations/${conversationId}/messages`, {
68
- params,
69
- } as any);
70
- }
71
-
72
- /**
73
- * Link a conversation to a lead in the CRM.
74
- *
75
- * @param conversationId - The unique ID of the conversation.
76
- * @param leadId - The unique ID of the lead to link.
77
- * @param leadData - Optional additional lead metadata.
78
- * @example
79
- * ```typescript
80
- * await erixClient.whatsapp.conversations.linkLead("conv_123", "lead_456");
81
- * ```
82
- */
83
- async linkLead<T = any>(conversationId: string, leadId: string, leadData?: any) {
84
- return this.post<T>(`/api/saas/chat/conversations/${conversationId}/link-lead`, {
85
- leadId,
86
- leadData,
87
- });
88
- }
89
-
90
- /**
91
- * Mark a conversation as read (clear unread count).
92
- *
93
- * @param conversationId - The unique ID of the conversation.
94
- * @example
95
- * ```typescript
96
- * await erixClient.whatsapp.conversations.markRead("conv_123");
97
- * ```
98
- */
99
- async markRead<T = any>(conversationId: string) {
100
- return this.post<T>(`/api/saas/chat/conversations/${conversationId}/read`, {});
101
- }
102
-
103
- /**
104
- * Delete a conversation.
105
- *
106
- * @param conversationId - The unique ID of the conversation.
107
- * @example
108
- * ```typescript
109
- * await erixClient.whatsapp.conversations.delete("conv_123");
110
- * ```
111
- */
112
- async delete(conversationId: string) {
113
- return this.deleteRequest(`/api/saas/chat/conversations/${conversationId}`);
114
- }
115
-
116
- /**
117
- * Bulk delete conversations.
118
- *
119
- * @param ids - Array of conversation IDs to delete.
120
- * @example
121
- * ```typescript
122
- * await erixClient.whatsapp.conversations.bulkDelete(["conv_1", "conv_2"]);
123
- * ```
124
- */
125
- async bulkDelete<T = any>(ids: string[]) {
126
- return this.post<T>("/api/saas/chat/conversations/bulk-delete", { ids });
127
- }
128
- }