@ecodrix/erix-api 1.0.1 → 1.0.4
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/dist/cli.js +38 -0
- package/dist/index.d.cts +1979 -0
- package/dist/index.d.ts +1173 -313
- package/dist/ts/browser/index.global.js +14 -14
- package/dist/ts/browser/index.global.js.map +1 -1
- package/dist/ts/cjs/index.cjs +1 -1
- package/dist/ts/cjs/index.cjs.map +1 -1
- package/dist/ts/cjs/index.d.cts +1173 -313
- package/dist/ts/esm/index.d.ts +1173 -313
- package/dist/ts/esm/index.js +1 -1
- package/dist/ts/esm/index.js.map +1 -1
- package/package.json +18 -13
- package/src/cli.ts +305 -0
- package/src/core.ts +28 -12
- package/src/index.ts +22 -8
- package/src/resource.ts +21 -1
- package/src/resources/crm/activities.ts +89 -0
- package/src/resources/crm/analytics.ts +89 -0
- package/src/resources/crm/automationDashboard.ts +24 -0
- package/src/resources/crm/automations.ts +151 -0
- package/src/resources/crm/index.ts +25 -1
- package/src/resources/crm/leads.ts +178 -45
- package/src/resources/crm/payments.ts +16 -0
- package/src/resources/crm/pipelines.ts +119 -0
- package/src/resources/crm/scoring.ts +33 -0
- package/src/resources/crm/sequences.ts +28 -0
- package/src/resources/email.ts +2 -5
- package/src/resources/events.ts +52 -2
- package/src/resources/health.ts +63 -0
- package/src/resources/marketing.ts +111 -0
- package/src/resources/media.ts +1 -4
- package/src/resources/meet.ts +12 -2
- package/src/resources/notifications.ts +30 -0
- package/src/resources/queue.ts +39 -0
- package/src/resources/storage.ts +72 -0
- package/src/resources/webhooks.ts +3 -8
- package/src/resources/whatsapp/broadcasts.ts +31 -0
- package/src/resources/whatsapp/conversations.ts +39 -9
- package/src/resources/whatsapp/index.ts +20 -2
- package/src/resources/whatsapp/messages.ts +24 -0
- package/src/resources/whatsapp/templates.ts +109 -0
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { APIResource } from "../../resource";
|
|
2
|
+
|
|
3
|
+
export class Sequences extends APIResource {
|
|
4
|
+
/**
|
|
5
|
+
* Manually enroll a lead in a drip sequence (automation rule).
|
|
6
|
+
*/
|
|
7
|
+
async enroll<T = any>(payload: {
|
|
8
|
+
leadId: string;
|
|
9
|
+
ruleId: string;
|
|
10
|
+
variables?: Record<string, any>;
|
|
11
|
+
}) {
|
|
12
|
+
return this.post<T>("/api/saas/crm/sequences/enroll", payload);
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* Unenroll a lead from a running sequence.
|
|
17
|
+
*/
|
|
18
|
+
async unenroll<T = any>(enrollmentId: string) {
|
|
19
|
+
return this.deleteRequest<T>(`/api/saas/crm/sequences/unenroll/${enrollmentId}`);
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* List active sequence enrollments for a specific lead.
|
|
24
|
+
*/
|
|
25
|
+
async listForLead<T = any>(leadId: string) {
|
|
26
|
+
return this.get<T>(`/api/saas/crm/sequences/lead/${leadId}`);
|
|
27
|
+
}
|
|
28
|
+
}
|
package/src/resources/email.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { AxiosInstance } from "axios";
|
|
2
|
-
import { APIResource } from "../resource";
|
|
3
2
|
import { APIError } from "../error";
|
|
3
|
+
import { APIResource } from "../resource";
|
|
4
4
|
|
|
5
5
|
/**
|
|
6
6
|
* Payload to send a high-throughput email campaign.
|
|
@@ -14,7 +14,6 @@ export interface SendCampaignPayload {
|
|
|
14
14
|
html: string;
|
|
15
15
|
}
|
|
16
16
|
|
|
17
|
-
|
|
18
17
|
/**
|
|
19
18
|
* Interface representing the result of a campaign dispatch.
|
|
20
19
|
*/
|
|
@@ -31,9 +30,7 @@ export class EmailResource extends APIResource {
|
|
|
31
30
|
* @param payload - The campaign details (recipients, subject, html).
|
|
32
31
|
* @returns The dispatch result.
|
|
33
32
|
*/
|
|
34
|
-
async sendEmailCampaign(
|
|
35
|
-
payload: SendCampaignPayload,
|
|
36
|
-
): Promise<CampaignResult> {
|
|
33
|
+
async sendEmailCampaign(payload: SendCampaignPayload): Promise<CampaignResult> {
|
|
37
34
|
return this.post<CampaignResult>("/api/saas/emails/campaign", payload);
|
|
38
35
|
}
|
|
39
36
|
|
package/src/resources/events.ts
CHANGED
|
@@ -64,6 +64,17 @@ export interface TriggerPayload {
|
|
|
64
64
|
delayMinutes?: number;
|
|
65
65
|
/** Explicit ISO timestamp to trigger the workflow run */
|
|
66
66
|
runAt?: string;
|
|
67
|
+
/** Automatically generate a Google Meet appointment if matched actions require it */
|
|
68
|
+
requiresMeet?: boolean;
|
|
69
|
+
/** Configuration details for the generated Google Meet appointment */
|
|
70
|
+
meetConfig?: {
|
|
71
|
+
summary?: string;
|
|
72
|
+
description?: string;
|
|
73
|
+
startTime?: string;
|
|
74
|
+
duration?: number;
|
|
75
|
+
timezone?: string;
|
|
76
|
+
attendees?: string[];
|
|
77
|
+
};
|
|
67
78
|
}
|
|
68
79
|
|
|
69
80
|
/**
|
|
@@ -94,7 +105,10 @@ export class EventsResource extends APIResource {
|
|
|
94
105
|
* Useful when introducing new granular triggers.
|
|
95
106
|
*/
|
|
96
107
|
async assign(payload: AssignEventPayload): Promise<{ success: boolean; data: EventDefinition }> {
|
|
97
|
-
return this.post<{ success: boolean; data: EventDefinition }>(
|
|
108
|
+
return this.post<{ success: boolean; data: EventDefinition }>(
|
|
109
|
+
"/api/saas/events/assign",
|
|
110
|
+
payload,
|
|
111
|
+
);
|
|
98
112
|
}
|
|
99
113
|
|
|
100
114
|
/**
|
|
@@ -108,7 +122,9 @@ export class EventsResource extends APIResource {
|
|
|
108
122
|
* Deactivate multiple custom event assignments simultaneously.
|
|
109
123
|
*/
|
|
110
124
|
async unassignBulk(names: string[]): Promise<{ success: boolean; message: string }> {
|
|
111
|
-
return this.post<{ success: boolean; message: string }>("/api/saas/events/unassign/bulk", {
|
|
125
|
+
return this.post<{ success: boolean; message: string }>("/api/saas/events/unassign/bulk", {
|
|
126
|
+
names,
|
|
127
|
+
});
|
|
112
128
|
}
|
|
113
129
|
|
|
114
130
|
/**
|
|
@@ -118,4 +134,38 @@ export class EventsResource extends APIResource {
|
|
|
118
134
|
async trigger(payload: TriggerPayload): Promise<TriggerResponse> {
|
|
119
135
|
return this.post<TriggerResponse>("/api/saas/workflows/trigger", payload);
|
|
120
136
|
}
|
|
137
|
+
|
|
138
|
+
// --- CRM Custom Events ---
|
|
139
|
+
|
|
140
|
+
/**
|
|
141
|
+
* List all custom event definitions.
|
|
142
|
+
*/
|
|
143
|
+
async listCustomEvents<T = any>() {
|
|
144
|
+
return this.get<T>("/api/saas/crm/custom-events");
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
/**
|
|
148
|
+
* Create or upsert a custom event definition.
|
|
149
|
+
*/
|
|
150
|
+
async createCustomEvent<T = any>(payload: {
|
|
151
|
+
name: string;
|
|
152
|
+
displayName: string;
|
|
153
|
+
description?: string;
|
|
154
|
+
}) {
|
|
155
|
+
return this.post<T>("/api/saas/crm/custom-events", payload);
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
/**
|
|
159
|
+
* Delete a custom event definition.
|
|
160
|
+
*/
|
|
161
|
+
async deleteCustomEvent<T = any>(id: string) {
|
|
162
|
+
return this.deleteRequest<T>(`/api/saas/crm/custom-events/${id}`);
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
/**
|
|
166
|
+
* Manually emit a custom event to trigger workflows based on its definition.
|
|
167
|
+
*/
|
|
168
|
+
async emit<T = any>(payload: { eventName: string; leadId: string; data?: any }) {
|
|
169
|
+
return this.post<T>("/api/saas/crm/events/emit", payload);
|
|
170
|
+
}
|
|
121
171
|
}
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
import { APIResource } from "../resource";
|
|
2
|
+
|
|
3
|
+
export interface SystemHealth {
|
|
4
|
+
status: string;
|
|
5
|
+
version: string;
|
|
6
|
+
env: string;
|
|
7
|
+
uptime: number;
|
|
8
|
+
db: string;
|
|
9
|
+
queueDepth: number;
|
|
10
|
+
timestamp: string;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
export interface ClientHealth {
|
|
14
|
+
clientCode: string;
|
|
15
|
+
services: {
|
|
16
|
+
whatsapp: "connected" | "not_configured";
|
|
17
|
+
email: "configured" | "not_configured";
|
|
18
|
+
googleMeet: "configured" | "not_configured";
|
|
19
|
+
};
|
|
20
|
+
activeAutomations: number;
|
|
21
|
+
queueDepth: number;
|
|
22
|
+
timestamp: string;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
export interface JobStatus {
|
|
26
|
+
jobId: string;
|
|
27
|
+
status: string;
|
|
28
|
+
attempts: number;
|
|
29
|
+
maxAttempts: number;
|
|
30
|
+
lastError: any;
|
|
31
|
+
runAt: string;
|
|
32
|
+
completedAt: string | null;
|
|
33
|
+
failedAt: string | null;
|
|
34
|
+
createdAt: string;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
export class Health extends APIResource {
|
|
38
|
+
/**
|
|
39
|
+
* Global platform health check.
|
|
40
|
+
*/
|
|
41
|
+
async system(): Promise<SystemHealth> {
|
|
42
|
+
const res = await this.get<{ data: SystemHealth }>("/api/saas/health", {
|
|
43
|
+
headers: { accept: "application/json" },
|
|
44
|
+
});
|
|
45
|
+
return res.data;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
/**
|
|
49
|
+
* Tenant-specific health check. Identifies configured services.
|
|
50
|
+
*/
|
|
51
|
+
async clientHealth(): Promise<ClientHealth> {
|
|
52
|
+
const res = await this.get<{ data: ClientHealth }>("/api/saas/health/client");
|
|
53
|
+
return res.data;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
/**
|
|
57
|
+
* Job execution status lookup.
|
|
58
|
+
*/
|
|
59
|
+
async jobStatus(jobId: string): Promise<JobStatus> {
|
|
60
|
+
const res = await this.get<{ data: JobStatus }>(`/api/saas/jobs/status/${jobId}`);
|
|
61
|
+
return res.data;
|
|
62
|
+
}
|
|
63
|
+
}
|
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
import { APIResource } from "../resource";
|
|
2
|
+
|
|
3
|
+
export interface SendCampaignParams {
|
|
4
|
+
recipients: string[];
|
|
5
|
+
subject: string;
|
|
6
|
+
html: string;
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
export class Emails extends APIResource {
|
|
10
|
+
/**
|
|
11
|
+
* Dispatch a bulk email campaign.
|
|
12
|
+
*/
|
|
13
|
+
async sendCampaign<T = any>(params: SendCampaignParams) {
|
|
14
|
+
return this.post<T>("/api/saas/marketing/emails/campaign", params);
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* Send a test verification email (used to verify SMTP functionality).
|
|
19
|
+
*/
|
|
20
|
+
async sendTest<T = any>(to: string) {
|
|
21
|
+
return this.post<T>("/api/saas/marketing/emails/test", { to });
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
export class Campaigns extends APIResource {
|
|
25
|
+
/**
|
|
26
|
+
* List email and SMS marketing campaigns.
|
|
27
|
+
*/
|
|
28
|
+
async list<T = any>(params?: { status?: string; limit?: number }) {
|
|
29
|
+
return this.get<T>("/api/saas/marketing/campaigns", { params } as any);
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
* Create a new campaign.
|
|
34
|
+
*/
|
|
35
|
+
async create<T = any>(payload: {
|
|
36
|
+
name: string;
|
|
37
|
+
type: string;
|
|
38
|
+
subject?: string;
|
|
39
|
+
html?: string;
|
|
40
|
+
templateId?: string;
|
|
41
|
+
recipients?: string[];
|
|
42
|
+
}) {
|
|
43
|
+
return this.post<T>("/api/saas/marketing/campaigns", payload);
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
/**
|
|
47
|
+
* Retrieve campaign details.
|
|
48
|
+
*/
|
|
49
|
+
async retrieve<T = any>(campaignId: string) {
|
|
50
|
+
return this.get<T>(`/api/saas/marketing/campaigns/${campaignId}`);
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
/**
|
|
54
|
+
* Update a campaign.
|
|
55
|
+
*/
|
|
56
|
+
async update<T = any>(campaignId: string, payload: any) {
|
|
57
|
+
return this.patch<T>(`/api/saas/marketing/campaigns/${campaignId}`, payload);
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
/**
|
|
61
|
+
* Delete a campaign.
|
|
62
|
+
*/
|
|
63
|
+
async delete<T = any>(campaignId: string) {
|
|
64
|
+
return this.deleteRequest<T>(`/api/saas/marketing/campaigns/${campaignId}`);
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
/**
|
|
68
|
+
* Send or schedule a campaign.
|
|
69
|
+
*/
|
|
70
|
+
async send<T = any>(campaignId: string, payload?: { scheduledAt?: string }) {
|
|
71
|
+
return this.post<T>(`/api/saas/marketing/campaigns/${campaignId}/send`, payload || {});
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
/**
|
|
75
|
+
* Get campaign stats (opens, clicks, bounces).
|
|
76
|
+
*/
|
|
77
|
+
async stats<T = any>(campaignId: string) {
|
|
78
|
+
return this.get<T>(`/api/saas/marketing/campaigns/${campaignId}/stats`);
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
export class WhatsAppMarketing extends APIResource {
|
|
83
|
+
/**
|
|
84
|
+
* Dispatch a template-based WhatsApp message with CRM-integrated variable resolution.
|
|
85
|
+
*
|
|
86
|
+
* Unlike direct WhatsApp sending, this endpoint automatically pulls data from the CRM
|
|
87
|
+
* based on the provided variables mapping.
|
|
88
|
+
*/
|
|
89
|
+
async sendTemplate<T = any>(params: {
|
|
90
|
+
phone: string;
|
|
91
|
+
templateName: string;
|
|
92
|
+
languageCode?: string;
|
|
93
|
+
variables?: Record<string, string>;
|
|
94
|
+
resolvedVariables?: Record<string, string>;
|
|
95
|
+
}) {
|
|
96
|
+
return this.post<T>("/api/saas/marketing/whatsapp/send-template", params);
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
export class Marketing extends APIResource {
|
|
101
|
+
public emails: Emails;
|
|
102
|
+
public campaigns: Campaigns;
|
|
103
|
+
public whatsapp: WhatsAppMarketing;
|
|
104
|
+
|
|
105
|
+
constructor(client: any) {
|
|
106
|
+
super(client);
|
|
107
|
+
this.emails = new Emails(client);
|
|
108
|
+
this.campaigns = new Campaigns(client);
|
|
109
|
+
this.whatsapp = new WhatsAppMarketing(client);
|
|
110
|
+
}
|
|
111
|
+
}
|
package/src/resources/media.ts
CHANGED
|
@@ -155,10 +155,7 @@ export class MediaResource extends APIResource {
|
|
|
155
155
|
*/
|
|
156
156
|
async upload(file: any, options: UploadOptions): Promise<any> {
|
|
157
157
|
// Step 1: Get presigned URL
|
|
158
|
-
const { data: presignedData } = await this.client.post(
|
|
159
|
-
"/api/saas/storage/upload-url",
|
|
160
|
-
options,
|
|
161
|
-
);
|
|
158
|
+
const { data: presignedData } = await this.client.post("/api/saas/storage/upload-url", options);
|
|
162
159
|
const { uploadUrl, key } = presignedData;
|
|
163
160
|
|
|
164
161
|
// Step 2: Upload directly to R2 (bypasses the API server for performance)
|
package/src/resources/meet.ts
CHANGED
|
@@ -133,8 +133,18 @@ export class Meetings extends APIResource {
|
|
|
133
133
|
* });
|
|
134
134
|
* ```
|
|
135
135
|
*/
|
|
136
|
-
async update(meetingId: string, data: UpdateMeetingParams)
|
|
137
|
-
return this.
|
|
136
|
+
async update<T = any>(meetingId: string, data: UpdateMeetingParams) {
|
|
137
|
+
return this.patch<T>(`/api/saas/meet/${meetingId}`, data);
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
/**
|
|
141
|
+
* Reschedule an existing meeting. Provides explicit method for time modifications.
|
|
142
|
+
*/
|
|
143
|
+
async reschedule<T = any>(
|
|
144
|
+
meetingId: string,
|
|
145
|
+
params: { startTime: Date | string; endTime: Date | string; duration?: number },
|
|
146
|
+
) {
|
|
147
|
+
return this.patch<T>(`/api/saas/meet/${meetingId}`, params);
|
|
138
148
|
}
|
|
139
149
|
|
|
140
150
|
/**
|
|
@@ -120,4 +120,34 @@ export class Notifications extends APIResource {
|
|
|
120
120
|
async listCallbacks(params?: Omit<LogFilter, "trigger" | "phone">) {
|
|
121
121
|
return this.get("/api/saas/callbacks/logs", { params } as any);
|
|
122
122
|
}
|
|
123
|
+
|
|
124
|
+
// --- CRM Notifications (Alerts) ---
|
|
125
|
+
|
|
126
|
+
/**
|
|
127
|
+
* List active CRM notifications/alerts for the current agent.
|
|
128
|
+
*/
|
|
129
|
+
async listAlerts<T = any>(params?: { limit?: number; unreadOnly?: boolean }) {
|
|
130
|
+
return this.get<T>("/api/saas/crm/notifications", { params } as any);
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
/**
|
|
134
|
+
* Dismiss a specific notification alert.
|
|
135
|
+
*/
|
|
136
|
+
async dismissAlert<T = any>(notificationId: string) {
|
|
137
|
+
return this.patch<T>(`/api/saas/crm/notifications/${notificationId}/dismiss`);
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
/**
|
|
141
|
+
* Clear (dismiss) all notifications for the current agent.
|
|
142
|
+
*/
|
|
143
|
+
async clearAllAlerts<T = any>() {
|
|
144
|
+
return this.deleteRequest<T>("/api/saas/crm/notifications/clear-all");
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
/**
|
|
148
|
+
* Retry an action from a notification (e.g. failed send).
|
|
149
|
+
*/
|
|
150
|
+
async retryAction<T = any>(notificationId: string) {
|
|
151
|
+
return this.post<T>(`/api/saas/crm/notifications/${notificationId}/retry`, {});
|
|
152
|
+
}
|
|
123
153
|
}
|
|
@@ -0,0 +1,39 @@
|
|
|
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 failed jobs.
|
|
14
|
+
*/
|
|
15
|
+
async listFailed<T = any>() {
|
|
16
|
+
return this.get<T>("/api/saas/queue/failed");
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* Get queue health statistics.
|
|
21
|
+
*/
|
|
22
|
+
async getStats<T = JobStats>() {
|
|
23
|
+
return this.get<T>("/api/saas/queue/stats");
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* Retry a failed job.
|
|
28
|
+
*/
|
|
29
|
+
async retryJob<T = any>(jobId: string) {
|
|
30
|
+
return this.post<T>(`/api/saas/queue/${jobId}/retry`, {});
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* Remove a job from the queue.
|
|
35
|
+
*/
|
|
36
|
+
async deleteJob<T = any>(jobId: string) {
|
|
37
|
+
return this.deleteRequest<T>(`/api/saas/queue/${jobId}`);
|
|
38
|
+
}
|
|
39
|
+
}
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
import { APIResource } from "../resource";
|
|
2
|
+
|
|
3
|
+
export class Folders extends APIResource {
|
|
4
|
+
/**
|
|
5
|
+
* Create a new folder.
|
|
6
|
+
*/
|
|
7
|
+
async create<T = any>(name: string) {
|
|
8
|
+
return this.post<T>("/api/saas/storage/folders", { name });
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* Delete a folder and its contents.
|
|
13
|
+
*/
|
|
14
|
+
async delete<T = any>(folderPath: string) {
|
|
15
|
+
return this.deleteRequest<T>(`/api/saas/storage/folders/${encodeURIComponent(folderPath)}`);
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
export class Files extends APIResource {
|
|
20
|
+
/**
|
|
21
|
+
* List files in a folder.
|
|
22
|
+
*/
|
|
23
|
+
async list<T = any>(folder: string, params?: { year?: string; month?: string }) {
|
|
24
|
+
return this.get<T>(`/api/saas/storage/files/${folder}`, { params } as any);
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* Get a presigned upload URL for direct-to-cloud browser uploads.
|
|
29
|
+
*/
|
|
30
|
+
async getUploadUrl<T = any>(params: { folder: string; filename: string; contentType: string }) {
|
|
31
|
+
return this.post<T>("/api/saas/storage/upload-url", params);
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* Notify backend after a successful direct browser upload.
|
|
36
|
+
*/
|
|
37
|
+
async confirmUpload<T = any>(params: { key: string; sizeBytes: number }) {
|
|
38
|
+
return this.post<T>("/api/saas/storage/confirm-upload", params);
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
/**
|
|
42
|
+
* Get a presigned download URL for an R2 key.
|
|
43
|
+
*/
|
|
44
|
+
async getDownloadUrl<T = any>(key: string) {
|
|
45
|
+
return this.post<T>("/api/saas/storage/download-url", { key });
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
/**
|
|
49
|
+
* Delete a file by key.
|
|
50
|
+
*/
|
|
51
|
+
async delete(key: string) {
|
|
52
|
+
return this.deleteRequest("/api/saas/storage/files", { params: { key } } as any);
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
export class Storage extends APIResource {
|
|
57
|
+
public folders: Folders;
|
|
58
|
+
public files: Files;
|
|
59
|
+
|
|
60
|
+
constructor(client: any) {
|
|
61
|
+
super(client);
|
|
62
|
+
this.folders = new Folders(client);
|
|
63
|
+
this.files = new Files(client);
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
/**
|
|
67
|
+
* Get tenant storage usage and quota limitations.
|
|
68
|
+
*/
|
|
69
|
+
async usage<T = any>() {
|
|
70
|
+
return this.get<T>("/api/saas/storage/usage");
|
|
71
|
+
}
|
|
72
|
+
}
|
|
@@ -44,7 +44,7 @@ export class Webhooks {
|
|
|
44
44
|
public async constructEvent(
|
|
45
45
|
payload: string | Buffer,
|
|
46
46
|
signature: string | string[] | undefined,
|
|
47
|
-
secret: string
|
|
47
|
+
secret: string,
|
|
48
48
|
): Promise<any> {
|
|
49
49
|
if (!signature) {
|
|
50
50
|
throw new WebhookSignatureError("No webhook signature provided");
|
|
@@ -63,10 +63,7 @@ export class Webhooks {
|
|
|
63
63
|
const hmac = crypto.createHmac("sha256", secret);
|
|
64
64
|
const digest = hmac.update(payload).digest("hex");
|
|
65
65
|
|
|
66
|
-
const isValid = crypto.timingSafeEqual(
|
|
67
|
-
Buffer.from(digest),
|
|
68
|
-
Buffer.from(sig)
|
|
69
|
-
);
|
|
66
|
+
const isValid = crypto.timingSafeEqual(Buffer.from(digest), Buffer.from(sig));
|
|
70
67
|
|
|
71
68
|
if (!isValid) {
|
|
72
69
|
throw new WebhookSignatureError("Invalid webhook signature provided");
|
|
@@ -77,9 +74,7 @@ export class Webhooks {
|
|
|
77
74
|
if (error instanceof WebhookSignatureError) {
|
|
78
75
|
throw error;
|
|
79
76
|
}
|
|
80
|
-
throw new WebhookSignatureError(
|
|
81
|
-
`Webhook payload parsing failed: ${error.message}`
|
|
82
|
-
);
|
|
77
|
+
throw new WebhookSignatureError(`Webhook payload parsing failed: ${error.message}`);
|
|
83
78
|
}
|
|
84
79
|
}
|
|
85
80
|
}
|
|
@@ -0,0 +1,31 @@
|
|
|
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 broadcasts.
|
|
20
|
+
*/
|
|
21
|
+
async list<T = any>(params?: Record<string, any>) {
|
|
22
|
+
return this.get<T>("/api/saas/chat/broadcasts", { params } as any);
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* Create a new broadcast to send a template message to multiple recipients.
|
|
27
|
+
*/
|
|
28
|
+
async create<T = any>(params: CreateBroadcastParams) {
|
|
29
|
+
return this.post<T>("/api/saas/chat/broadcast", params);
|
|
30
|
+
}
|
|
31
|
+
}
|
|
@@ -3,41 +3,71 @@ import { APIResource } from "../../resource";
|
|
|
3
3
|
export interface ListParams {
|
|
4
4
|
limit?: number;
|
|
5
5
|
before?: string;
|
|
6
|
+
after?: string;
|
|
7
|
+
status?: string;
|
|
6
8
|
}
|
|
7
9
|
|
|
8
10
|
export class Conversations extends APIResource {
|
|
9
11
|
/**
|
|
10
12
|
* List conversations for the tenant.
|
|
11
13
|
*/
|
|
12
|
-
async list(params?: ListParams)
|
|
13
|
-
return this.get("/api/saas/chat/conversations", { params } as any);
|
|
14
|
+
async list<T = any>(params?: ListParams) {
|
|
15
|
+
return this.get<T>("/api/saas/chat/conversations", { params } as any);
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* Create a new conversation explicitly.
|
|
20
|
+
*
|
|
21
|
+
* @param params - Conversation details.
|
|
22
|
+
*/
|
|
23
|
+
async create<T = any>(params: { phone: string; name?: string }) {
|
|
24
|
+
return this.post<T>("/api/saas/chat/conversations", params);
|
|
14
25
|
}
|
|
15
26
|
|
|
16
27
|
/**
|
|
17
28
|
* Retrieve details of a specific conversation.
|
|
18
29
|
*/
|
|
19
|
-
async retrieve(conversationId: string)
|
|
20
|
-
return this.get(`/api/saas/chat/conversations/${conversationId}`);
|
|
30
|
+
async retrieve<T = any>(conversationId: string) {
|
|
31
|
+
return this.get<T>(`/api/saas/chat/conversations/${conversationId}`);
|
|
21
32
|
}
|
|
22
33
|
|
|
23
34
|
/**
|
|
24
35
|
* Get messages for a specific conversation.
|
|
25
36
|
*/
|
|
26
|
-
async messages(conversationId: string, params?: ListParams)
|
|
27
|
-
return this.get(`/api/saas/chat/conversations/${conversationId}/messages`, {
|
|
37
|
+
async messages<T = any>(conversationId: string, params?: ListParams) {
|
|
38
|
+
return this.get<T>(`/api/saas/chat/conversations/${conversationId}/messages`, {
|
|
39
|
+
params,
|
|
40
|
+
} as any);
|
|
28
41
|
}
|
|
29
42
|
|
|
30
43
|
/**
|
|
31
44
|
* Link a conversation to a lead.
|
|
32
45
|
*/
|
|
33
|
-
async linkLead(conversationId: string, leadId: string) {
|
|
34
|
-
return this.post(`/api/saas/chat/conversations/${conversationId}/link-lead`, {
|
|
46
|
+
async linkLead<T = any>(conversationId: string, leadId: string, leadData?: any) {
|
|
47
|
+
return this.post<T>(`/api/saas/chat/conversations/${conversationId}/link-lead`, {
|
|
48
|
+
leadId,
|
|
49
|
+
leadData,
|
|
50
|
+
});
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
/**
|
|
54
|
+
* Mark a conversation as read (clear unread count).
|
|
55
|
+
*/
|
|
56
|
+
async markRead<T = any>(conversationId: string) {
|
|
57
|
+
return this.post<T>(`/api/saas/chat/conversations/${conversationId}/read`, {});
|
|
35
58
|
}
|
|
36
59
|
|
|
37
60
|
/**
|
|
38
61
|
* Delete a conversation.
|
|
39
62
|
*/
|
|
40
|
-
async delete(conversationId: string)
|
|
63
|
+
async delete(conversationId: string) {
|
|
41
64
|
return this.deleteRequest(`/api/saas/chat/conversations/${conversationId}`);
|
|
42
65
|
}
|
|
66
|
+
|
|
67
|
+
/**
|
|
68
|
+
* Bulk delete conversations.
|
|
69
|
+
*/
|
|
70
|
+
async bulkDelete(ids: string[]) {
|
|
71
|
+
return this.post("/api/saas/chat/conversations/bulk-delete", { ids });
|
|
72
|
+
}
|
|
43
73
|
}
|
|
@@ -1,7 +1,9 @@
|
|
|
1
|
+
import type { AxiosInstance } from "axios";
|
|
1
2
|
import { APIResource } from "../../resource";
|
|
2
|
-
import {
|
|
3
|
+
import { Broadcasts } from "./broadcasts";
|
|
3
4
|
import { Conversations } from "./conversations";
|
|
4
|
-
import
|
|
5
|
+
import { Messages } from "./messages";
|
|
6
|
+
import { Templates } from "./templates";
|
|
5
7
|
|
|
6
8
|
export interface SendTemplatePayload {
|
|
7
9
|
/** Phone number in E.164 format. */
|
|
@@ -19,11 +21,27 @@ export interface SendTemplatePayload {
|
|
|
19
21
|
export class WhatsApp extends APIResource {
|
|
20
22
|
public messages: Messages;
|
|
21
23
|
public conversations: Conversations;
|
|
24
|
+
public broadcasts: Broadcasts;
|
|
25
|
+
public templates: Templates;
|
|
22
26
|
|
|
23
27
|
constructor(client: AxiosInstance) {
|
|
24
28
|
super(client);
|
|
25
29
|
this.messages = new Messages(client);
|
|
26
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/whatsapp/upload", form, {
|
|
42
|
+
headers:
|
|
43
|
+
typeof (form as any).getHeaders === "function" ? (form as any).getHeaders() : undefined,
|
|
44
|
+
});
|
|
27
45
|
}
|
|
28
46
|
|
|
29
47
|
/**
|