@agentuity/core 1.0.21 → 1.0.23
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/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +3 -0
- package/dist/index.js.map +1 -1
- package/dist/services/email.d.ts +296 -0
- package/dist/services/email.d.ts.map +1 -0
- package/dist/services/email.js +308 -0
- package/dist/services/email.js.map +1 -0
- package/dist/services/index.d.ts +3 -0
- package/dist/services/index.d.ts.map +1 -1
- package/dist/services/index.js +3 -0
- package/dist/services/index.js.map +1 -1
- package/dist/services/schedule.d.ts +88 -0
- package/dist/services/schedule.d.ts.map +1 -0
- package/dist/services/schedule.js +206 -0
- package/dist/services/schedule.js.map +1 -0
- package/dist/services/task.d.ts +100 -0
- package/dist/services/task.d.ts.map +1 -0
- package/dist/services/task.js +208 -0
- package/dist/services/task.js.map +1 -0
- package/package.json +2 -2
- package/src/index.ts +37 -0
- package/src/services/email.ts +663 -0
- package/src/services/index.ts +3 -0
- package/src/services/schedule.ts +332 -0
- package/src/services/task.ts +366 -0
|
@@ -0,0 +1,663 @@
|
|
|
1
|
+
import { FetchAdapter } from './adapter.ts';
|
|
2
|
+
import { buildUrl, toServiceException } from './_util.ts';
|
|
3
|
+
import { safeStringify } from '../json.ts';
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* An email address registered with the Agentuity email service
|
|
7
|
+
*/
|
|
8
|
+
export interface EmailAddress {
|
|
9
|
+
id: string;
|
|
10
|
+
email: string;
|
|
11
|
+
project_id?: string;
|
|
12
|
+
provider?: string;
|
|
13
|
+
config?: Record<string, unknown>;
|
|
14
|
+
created_by?: string;
|
|
15
|
+
created_at: string;
|
|
16
|
+
updated_at?: string;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* A destination configuration for an email address
|
|
21
|
+
*/
|
|
22
|
+
export interface EmailDestination {
|
|
23
|
+
id: string;
|
|
24
|
+
type: string;
|
|
25
|
+
config?: Record<string, unknown>;
|
|
26
|
+
created_at: string;
|
|
27
|
+
updated_at?: string;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* An inbound email message
|
|
32
|
+
*/
|
|
33
|
+
export interface EmailInbound {
|
|
34
|
+
id: string;
|
|
35
|
+
from: string;
|
|
36
|
+
to: string;
|
|
37
|
+
subject?: string;
|
|
38
|
+
text?: string;
|
|
39
|
+
status?: string;
|
|
40
|
+
received_at?: string;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
/**
|
|
44
|
+
* An outbound email message
|
|
45
|
+
*/
|
|
46
|
+
export interface EmailOutbound {
|
|
47
|
+
id: string;
|
|
48
|
+
from: string;
|
|
49
|
+
to: string;
|
|
50
|
+
subject?: string;
|
|
51
|
+
text?: string;
|
|
52
|
+
html?: string;
|
|
53
|
+
status?: string;
|
|
54
|
+
error?: string;
|
|
55
|
+
sent_at?: string;
|
|
56
|
+
created_at?: string;
|
|
57
|
+
updated_at?: string;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
/**
|
|
61
|
+
* An email attachment
|
|
62
|
+
*/
|
|
63
|
+
export interface EmailAttachment {
|
|
64
|
+
/**
|
|
65
|
+
* The filename for the attachment
|
|
66
|
+
*/
|
|
67
|
+
filename: string;
|
|
68
|
+
|
|
69
|
+
/**
|
|
70
|
+
* The base64-encoded content of the attachment
|
|
71
|
+
*/
|
|
72
|
+
content: string;
|
|
73
|
+
|
|
74
|
+
/**
|
|
75
|
+
* The MIME content type of the attachment
|
|
76
|
+
*/
|
|
77
|
+
contentType?: string;
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
/**
|
|
81
|
+
* Parameters for sending an email
|
|
82
|
+
*/
|
|
83
|
+
export interface EmailSendParams {
|
|
84
|
+
/**
|
|
85
|
+
* The sender email address (must be owned by the organization)
|
|
86
|
+
*/
|
|
87
|
+
from: string;
|
|
88
|
+
|
|
89
|
+
/**
|
|
90
|
+
* The recipient email addresses
|
|
91
|
+
*/
|
|
92
|
+
to: string[];
|
|
93
|
+
|
|
94
|
+
/**
|
|
95
|
+
* The email subject
|
|
96
|
+
*/
|
|
97
|
+
subject: string;
|
|
98
|
+
|
|
99
|
+
/**
|
|
100
|
+
* Plain text email body
|
|
101
|
+
*/
|
|
102
|
+
text?: string;
|
|
103
|
+
|
|
104
|
+
/**
|
|
105
|
+
* HTML email body
|
|
106
|
+
*/
|
|
107
|
+
html?: string;
|
|
108
|
+
|
|
109
|
+
/**
|
|
110
|
+
* File attachments
|
|
111
|
+
*/
|
|
112
|
+
attachments?: EmailAttachment[];
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
/**
|
|
116
|
+
* Email service for managing email addresses, destinations, and sending/receiving emails
|
|
117
|
+
*/
|
|
118
|
+
export interface EmailService {
|
|
119
|
+
/**
|
|
120
|
+
* Create a new email address
|
|
121
|
+
*
|
|
122
|
+
* @param localPart - the local part of the email address (before the @)
|
|
123
|
+
* @returns the created email address
|
|
124
|
+
*
|
|
125
|
+
* @example
|
|
126
|
+
* ```typescript
|
|
127
|
+
* const address = await email.createAddress('support');
|
|
128
|
+
* console.log('Created:', address.email);
|
|
129
|
+
* ```
|
|
130
|
+
*/
|
|
131
|
+
createAddress(localPart: string): Promise<EmailAddress>;
|
|
132
|
+
|
|
133
|
+
/**
|
|
134
|
+
* List all email addresses
|
|
135
|
+
*
|
|
136
|
+
* @returns array of email addresses
|
|
137
|
+
*
|
|
138
|
+
* @example
|
|
139
|
+
* ```typescript
|
|
140
|
+
* const addresses = await email.listAddresses();
|
|
141
|
+
* for (const addr of addresses) {
|
|
142
|
+
* console.log(addr.email);
|
|
143
|
+
* }
|
|
144
|
+
* ```
|
|
145
|
+
*/
|
|
146
|
+
listAddresses(): Promise<EmailAddress[]>;
|
|
147
|
+
|
|
148
|
+
/**
|
|
149
|
+
* Get an email address by ID
|
|
150
|
+
*
|
|
151
|
+
* @param id - the email address ID
|
|
152
|
+
* @returns the email address or null if not found
|
|
153
|
+
*
|
|
154
|
+
* @example
|
|
155
|
+
* ```typescript
|
|
156
|
+
* const address = await email.getAddress('addr_123');
|
|
157
|
+
* if (address) {
|
|
158
|
+
* console.log('Found:', address.email);
|
|
159
|
+
* }
|
|
160
|
+
* ```
|
|
161
|
+
*/
|
|
162
|
+
getAddress(id: string): Promise<EmailAddress | null>;
|
|
163
|
+
|
|
164
|
+
/**
|
|
165
|
+
* Delete an email address
|
|
166
|
+
*
|
|
167
|
+
* @param id - the email address ID
|
|
168
|
+
*
|
|
169
|
+
* @example
|
|
170
|
+
* ```typescript
|
|
171
|
+
* await email.deleteAddress('addr_123');
|
|
172
|
+
* ```
|
|
173
|
+
*/
|
|
174
|
+
deleteAddress(id: string): Promise<void>;
|
|
175
|
+
|
|
176
|
+
/**
|
|
177
|
+
* Create a destination for an email address
|
|
178
|
+
*
|
|
179
|
+
* @param addressId - the email address ID
|
|
180
|
+
* @param type - the destination type (e.g., 'url', 'agent')
|
|
181
|
+
* @param config - the destination configuration
|
|
182
|
+
* @returns the created destination
|
|
183
|
+
*
|
|
184
|
+
* @example
|
|
185
|
+
* ```typescript
|
|
186
|
+
* const dest = await email.createDestination('addr_123', 'url', {
|
|
187
|
+
* url: 'https://example.com/webhook',
|
|
188
|
+
* });
|
|
189
|
+
* console.log('Created destination:', dest.id);
|
|
190
|
+
* ```
|
|
191
|
+
*/
|
|
192
|
+
createDestination(
|
|
193
|
+
addressId: string,
|
|
194
|
+
type: string,
|
|
195
|
+
config: Record<string, unknown>
|
|
196
|
+
): Promise<EmailDestination>;
|
|
197
|
+
|
|
198
|
+
/**
|
|
199
|
+
* List destinations for an email address
|
|
200
|
+
*
|
|
201
|
+
* @param addressId - the email address ID
|
|
202
|
+
* @returns array of destinations
|
|
203
|
+
*
|
|
204
|
+
* @example
|
|
205
|
+
* ```typescript
|
|
206
|
+
* const destinations = await email.listDestinations('addr_123');
|
|
207
|
+
* for (const dest of destinations) {
|
|
208
|
+
* console.log(`${dest.type}: ${dest.id}`);
|
|
209
|
+
* }
|
|
210
|
+
* ```
|
|
211
|
+
*/
|
|
212
|
+
listDestinations(addressId: string): Promise<EmailDestination[]>;
|
|
213
|
+
|
|
214
|
+
/**
|
|
215
|
+
* Delete a destination from an email address
|
|
216
|
+
*
|
|
217
|
+
* @param addressId - the email address ID
|
|
218
|
+
* @param destinationId - the destination ID
|
|
219
|
+
*
|
|
220
|
+
* @example
|
|
221
|
+
* ```typescript
|
|
222
|
+
* await email.deleteDestination('addr_123', 'dest_456');
|
|
223
|
+
* ```
|
|
224
|
+
*/
|
|
225
|
+
deleteDestination(addressId: string, destinationId: string): Promise<void>;
|
|
226
|
+
|
|
227
|
+
/**
|
|
228
|
+
* Send an email
|
|
229
|
+
*
|
|
230
|
+
* @param params - the send parameters
|
|
231
|
+
* @returns the outbound email record
|
|
232
|
+
*
|
|
233
|
+
* @example
|
|
234
|
+
* ```typescript
|
|
235
|
+
* const result = await email.send({
|
|
236
|
+
* from: 'support@myapp.agentuity.email',
|
|
237
|
+
* to: ['user@example.com'],
|
|
238
|
+
* subject: 'Welcome!',
|
|
239
|
+
* text: 'Welcome to our platform.',
|
|
240
|
+
* html: '<h1>Welcome!</h1><p>Welcome to our platform.</p>',
|
|
241
|
+
* });
|
|
242
|
+
* console.log('Sent:', result.id, 'Status:', result.status);
|
|
243
|
+
* ```
|
|
244
|
+
*/
|
|
245
|
+
send(params: EmailSendParams): Promise<EmailOutbound>;
|
|
246
|
+
|
|
247
|
+
/**
|
|
248
|
+
* List inbound emails
|
|
249
|
+
*
|
|
250
|
+
* @param addressId - optional email address ID to filter by
|
|
251
|
+
* @returns array of inbound emails
|
|
252
|
+
*
|
|
253
|
+
* @example
|
|
254
|
+
* ```typescript
|
|
255
|
+
* const inbound = await email.listInbound('addr_123');
|
|
256
|
+
* for (const msg of inbound) {
|
|
257
|
+
* console.log(`From: ${msg.from}, Subject: ${msg.subject}`);
|
|
258
|
+
* }
|
|
259
|
+
* ```
|
|
260
|
+
*/
|
|
261
|
+
listInbound(addressId?: string): Promise<EmailInbound[]>;
|
|
262
|
+
|
|
263
|
+
/**
|
|
264
|
+
* Get an inbound email by ID
|
|
265
|
+
*
|
|
266
|
+
* @param id - the inbound email ID
|
|
267
|
+
* @returns the inbound email or null if not found
|
|
268
|
+
*
|
|
269
|
+
* @example
|
|
270
|
+
* ```typescript
|
|
271
|
+
* const msg = await email.getInbound('inb_123');
|
|
272
|
+
* if (msg) {
|
|
273
|
+
* console.log('Subject:', msg.subject);
|
|
274
|
+
* }
|
|
275
|
+
* ```
|
|
276
|
+
*/
|
|
277
|
+
getInbound(id: string): Promise<EmailInbound | null>;
|
|
278
|
+
|
|
279
|
+
/**
|
|
280
|
+
* List outbound emails
|
|
281
|
+
*
|
|
282
|
+
* @param addressId - optional email address ID to filter by
|
|
283
|
+
* @returns array of outbound emails
|
|
284
|
+
*
|
|
285
|
+
* @example
|
|
286
|
+
* ```typescript
|
|
287
|
+
* const outbound = await email.listOutbound('addr_123');
|
|
288
|
+
* for (const msg of outbound) {
|
|
289
|
+
* console.log(`To: ${msg.to}, Status: ${msg.status}`);
|
|
290
|
+
* }
|
|
291
|
+
* ```
|
|
292
|
+
*/
|
|
293
|
+
listOutbound(addressId?: string): Promise<EmailOutbound[]>;
|
|
294
|
+
|
|
295
|
+
/**
|
|
296
|
+
* Get an outbound email by ID
|
|
297
|
+
*
|
|
298
|
+
* @param id - the outbound email ID
|
|
299
|
+
* @returns the outbound email or null if not found
|
|
300
|
+
*
|
|
301
|
+
* @example
|
|
302
|
+
* ```typescript
|
|
303
|
+
* const msg = await email.getOutbound('out_123');
|
|
304
|
+
* if (msg) {
|
|
305
|
+
* console.log('Status:', msg.status);
|
|
306
|
+
* }
|
|
307
|
+
* ```
|
|
308
|
+
*/
|
|
309
|
+
getOutbound(id: string): Promise<EmailOutbound | null>;
|
|
310
|
+
}
|
|
311
|
+
|
|
312
|
+
/**
|
|
313
|
+
* Unwrap a Catalyst API response payload.
|
|
314
|
+
* Handles both `{ key: data }` and `{ data: { key: data } }` response formats.
|
|
315
|
+
*/
|
|
316
|
+
function unwrap<T>(payload: unknown, key: string): T {
|
|
317
|
+
if (typeof payload === 'object' && payload !== null) {
|
|
318
|
+
const obj = payload as Record<string, unknown>;
|
|
319
|
+
if (key in obj) {
|
|
320
|
+
return obj[key] as T;
|
|
321
|
+
}
|
|
322
|
+
if ('data' in obj && typeof obj.data === 'object' && obj.data !== null) {
|
|
323
|
+
const data = obj.data as Record<string, unknown>;
|
|
324
|
+
if (key in data) {
|
|
325
|
+
return data[key] as T;
|
|
326
|
+
}
|
|
327
|
+
return data as T;
|
|
328
|
+
}
|
|
329
|
+
}
|
|
330
|
+
return payload as T;
|
|
331
|
+
}
|
|
332
|
+
|
|
333
|
+
export class EmailStorageService implements EmailService {
|
|
334
|
+
#adapter: FetchAdapter;
|
|
335
|
+
#baseUrl: string;
|
|
336
|
+
|
|
337
|
+
constructor(baseUrl: string, adapter: FetchAdapter) {
|
|
338
|
+
this.#adapter = adapter;
|
|
339
|
+
this.#baseUrl = baseUrl;
|
|
340
|
+
}
|
|
341
|
+
|
|
342
|
+
async createAddress(localPart: string): Promise<EmailAddress> {
|
|
343
|
+
const url = buildUrl(this.#baseUrl, '/email/2025-03-17/addresses');
|
|
344
|
+
const signal = AbortSignal.timeout(30_000);
|
|
345
|
+
const res = await this.#adapter.invoke<unknown>(url, {
|
|
346
|
+
method: 'POST',
|
|
347
|
+
body: safeStringify({ local_part: localPart }),
|
|
348
|
+
contentType: 'application/json',
|
|
349
|
+
signal,
|
|
350
|
+
telemetry: {
|
|
351
|
+
name: 'agentuity.email.createAddress',
|
|
352
|
+
attributes: {
|
|
353
|
+
localPart,
|
|
354
|
+
},
|
|
355
|
+
},
|
|
356
|
+
});
|
|
357
|
+
if (res.ok) {
|
|
358
|
+
return unwrap<EmailAddress>(res.data, 'address');
|
|
359
|
+
}
|
|
360
|
+
throw await toServiceException('POST', url, res.response);
|
|
361
|
+
}
|
|
362
|
+
|
|
363
|
+
async listAddresses(): Promise<EmailAddress[]> {
|
|
364
|
+
const url = buildUrl(this.#baseUrl, '/email/2025-03-17/addresses');
|
|
365
|
+
const signal = AbortSignal.timeout(30_000);
|
|
366
|
+
const res = await this.#adapter.invoke<unknown>(url, {
|
|
367
|
+
method: 'GET',
|
|
368
|
+
signal,
|
|
369
|
+
telemetry: {
|
|
370
|
+
name: 'agentuity.email.listAddresses',
|
|
371
|
+
attributes: {},
|
|
372
|
+
},
|
|
373
|
+
});
|
|
374
|
+
if (res.response.status === 404) {
|
|
375
|
+
return [];
|
|
376
|
+
}
|
|
377
|
+
if (res.ok) {
|
|
378
|
+
const items = unwrap<unknown>(res.data, 'addresses');
|
|
379
|
+
return Array.isArray(items) ? (items as EmailAddress[]) : [];
|
|
380
|
+
}
|
|
381
|
+
throw await toServiceException('GET', url, res.response);
|
|
382
|
+
}
|
|
383
|
+
|
|
384
|
+
async getAddress(id: string): Promise<EmailAddress | null> {
|
|
385
|
+
const url = buildUrl(
|
|
386
|
+
this.#baseUrl,
|
|
387
|
+
`/email/2025-03-17/addresses/${encodeURIComponent(id)}`
|
|
388
|
+
);
|
|
389
|
+
const signal = AbortSignal.timeout(30_000);
|
|
390
|
+
const res = await this.#adapter.invoke<unknown>(url, {
|
|
391
|
+
method: 'GET',
|
|
392
|
+
signal,
|
|
393
|
+
telemetry: {
|
|
394
|
+
name: 'agentuity.email.getAddress',
|
|
395
|
+
attributes: {
|
|
396
|
+
id,
|
|
397
|
+
},
|
|
398
|
+
},
|
|
399
|
+
});
|
|
400
|
+
if (res.response.status === 404) {
|
|
401
|
+
return null;
|
|
402
|
+
}
|
|
403
|
+
if (res.ok) {
|
|
404
|
+
return unwrap<EmailAddress>(res.data, 'address');
|
|
405
|
+
}
|
|
406
|
+
throw await toServiceException('GET', url, res.response);
|
|
407
|
+
}
|
|
408
|
+
|
|
409
|
+
async deleteAddress(id: string): Promise<void> {
|
|
410
|
+
const url = buildUrl(
|
|
411
|
+
this.#baseUrl,
|
|
412
|
+
`/email/2025-03-17/addresses/${encodeURIComponent(id)}`
|
|
413
|
+
);
|
|
414
|
+
const signal = AbortSignal.timeout(30_000);
|
|
415
|
+
const res = await this.#adapter.invoke<unknown>(url, {
|
|
416
|
+
method: 'DELETE',
|
|
417
|
+
signal,
|
|
418
|
+
telemetry: {
|
|
419
|
+
name: 'agentuity.email.deleteAddress',
|
|
420
|
+
attributes: {
|
|
421
|
+
id,
|
|
422
|
+
},
|
|
423
|
+
},
|
|
424
|
+
});
|
|
425
|
+
if (res.ok || res.response.status === 404) {
|
|
426
|
+
return;
|
|
427
|
+
}
|
|
428
|
+
throw await toServiceException('DELETE', url, res.response);
|
|
429
|
+
}
|
|
430
|
+
|
|
431
|
+
async createDestination(
|
|
432
|
+
addressId: string,
|
|
433
|
+
type: string,
|
|
434
|
+
config: Record<string, unknown>
|
|
435
|
+
): Promise<EmailDestination> {
|
|
436
|
+
const url = buildUrl(
|
|
437
|
+
this.#baseUrl,
|
|
438
|
+
`/email/2025-03-17/addresses/${encodeURIComponent(addressId)}/destinations`
|
|
439
|
+
);
|
|
440
|
+
const signal = AbortSignal.timeout(30_000);
|
|
441
|
+
const res = await this.#adapter.invoke<unknown>(url, {
|
|
442
|
+
method: 'POST',
|
|
443
|
+
body: safeStringify({ type, config }),
|
|
444
|
+
contentType: 'application/json',
|
|
445
|
+
signal,
|
|
446
|
+
telemetry: {
|
|
447
|
+
name: 'agentuity.email.createDestination',
|
|
448
|
+
attributes: {
|
|
449
|
+
addressId,
|
|
450
|
+
type,
|
|
451
|
+
},
|
|
452
|
+
},
|
|
453
|
+
});
|
|
454
|
+
if (res.ok) {
|
|
455
|
+
return unwrap<EmailDestination>(res.data, 'destination');
|
|
456
|
+
}
|
|
457
|
+
throw await toServiceException('POST', url, res.response);
|
|
458
|
+
}
|
|
459
|
+
|
|
460
|
+
async listDestinations(addressId: string): Promise<EmailDestination[]> {
|
|
461
|
+
const url = buildUrl(
|
|
462
|
+
this.#baseUrl,
|
|
463
|
+
`/email/2025-03-17/addresses/${encodeURIComponent(addressId)}/destinations`
|
|
464
|
+
);
|
|
465
|
+
const signal = AbortSignal.timeout(30_000);
|
|
466
|
+
const res = await this.#adapter.invoke<unknown>(url, {
|
|
467
|
+
method: 'GET',
|
|
468
|
+
signal,
|
|
469
|
+
telemetry: {
|
|
470
|
+
name: 'agentuity.email.listDestinations',
|
|
471
|
+
attributes: {
|
|
472
|
+
addressId,
|
|
473
|
+
},
|
|
474
|
+
},
|
|
475
|
+
});
|
|
476
|
+
if (res.response.status === 404) {
|
|
477
|
+
return [];
|
|
478
|
+
}
|
|
479
|
+
if (res.ok) {
|
|
480
|
+
const items = unwrap<unknown>(res.data, 'destinations');
|
|
481
|
+
return Array.isArray(items) ? (items as EmailDestination[]) : [];
|
|
482
|
+
}
|
|
483
|
+
throw await toServiceException('GET', url, res.response);
|
|
484
|
+
}
|
|
485
|
+
|
|
486
|
+
async deleteDestination(addressId: string, destinationId: string): Promise<void> {
|
|
487
|
+
const url = buildUrl(
|
|
488
|
+
this.#baseUrl,
|
|
489
|
+
`/email/2025-03-17/addresses/${encodeURIComponent(addressId)}/destinations/${encodeURIComponent(destinationId)}`
|
|
490
|
+
);
|
|
491
|
+
const signal = AbortSignal.timeout(30_000);
|
|
492
|
+
const res = await this.#adapter.invoke<unknown>(url, {
|
|
493
|
+
method: 'DELETE',
|
|
494
|
+
signal,
|
|
495
|
+
telemetry: {
|
|
496
|
+
name: 'agentuity.email.deleteDestination',
|
|
497
|
+
attributes: {
|
|
498
|
+
addressId,
|
|
499
|
+
destinationId,
|
|
500
|
+
},
|
|
501
|
+
},
|
|
502
|
+
});
|
|
503
|
+
if (res.ok || res.response.status === 404) {
|
|
504
|
+
return;
|
|
505
|
+
}
|
|
506
|
+
throw await toServiceException('DELETE', url, res.response);
|
|
507
|
+
}
|
|
508
|
+
|
|
509
|
+
async send(params: EmailSendParams): Promise<EmailOutbound> {
|
|
510
|
+
const url = buildUrl(this.#baseUrl, '/email/2025-03-17/outbound/send');
|
|
511
|
+
const signal = AbortSignal.timeout(30_000);
|
|
512
|
+
|
|
513
|
+
// Transform attachments to API format (snake_case)
|
|
514
|
+
const body: Record<string, unknown> = {
|
|
515
|
+
from: params.from,
|
|
516
|
+
to: params.to,
|
|
517
|
+
subject: params.subject,
|
|
518
|
+
};
|
|
519
|
+
if (params.text !== undefined) {
|
|
520
|
+
body.text = params.text;
|
|
521
|
+
}
|
|
522
|
+
if (params.html !== undefined) {
|
|
523
|
+
body.html = params.html;
|
|
524
|
+
}
|
|
525
|
+
if (params.attachments && params.attachments.length > 0) {
|
|
526
|
+
body.attachments = params.attachments.map((a) => ({
|
|
527
|
+
filename: a.filename,
|
|
528
|
+
content_base64: a.content,
|
|
529
|
+
...(a.contentType && { content_type: a.contentType }),
|
|
530
|
+
}));
|
|
531
|
+
}
|
|
532
|
+
|
|
533
|
+
const res = await this.#adapter.invoke<unknown>(url, {
|
|
534
|
+
method: 'POST',
|
|
535
|
+
body: safeStringify(body),
|
|
536
|
+
contentType: 'application/json',
|
|
537
|
+
signal,
|
|
538
|
+
telemetry: {
|
|
539
|
+
name: 'agentuity.email.send',
|
|
540
|
+
attributes: {
|
|
541
|
+
from: params.from,
|
|
542
|
+
toCount: String(params.to.length),
|
|
543
|
+
},
|
|
544
|
+
},
|
|
545
|
+
});
|
|
546
|
+
if (res.ok) {
|
|
547
|
+
return unwrap<EmailOutbound>(res.data, 'outbound');
|
|
548
|
+
}
|
|
549
|
+
throw await toServiceException('POST', url, res.response);
|
|
550
|
+
}
|
|
551
|
+
|
|
552
|
+
async listInbound(addressId?: string): Promise<EmailInbound[]> {
|
|
553
|
+
const queryParams = new URLSearchParams();
|
|
554
|
+
if (addressId) {
|
|
555
|
+
queryParams.set('address_id', addressId);
|
|
556
|
+
}
|
|
557
|
+
const queryString = queryParams.toString();
|
|
558
|
+
const url = buildUrl(
|
|
559
|
+
this.#baseUrl,
|
|
560
|
+
`/email/2025-03-17/inbound${queryString ? `?${queryString}` : ''}`
|
|
561
|
+
);
|
|
562
|
+
const signal = AbortSignal.timeout(30_000);
|
|
563
|
+
const res = await this.#adapter.invoke<unknown>(url, {
|
|
564
|
+
method: 'GET',
|
|
565
|
+
signal,
|
|
566
|
+
telemetry: {
|
|
567
|
+
name: 'agentuity.email.listInbound',
|
|
568
|
+
attributes: {
|
|
569
|
+
...(addressId && { addressId }),
|
|
570
|
+
},
|
|
571
|
+
},
|
|
572
|
+
});
|
|
573
|
+
if (res.response.status === 404) {
|
|
574
|
+
return [];
|
|
575
|
+
}
|
|
576
|
+
if (res.ok) {
|
|
577
|
+
const items = unwrap<unknown>(res.data, 'inbound');
|
|
578
|
+
return Array.isArray(items) ? (items as EmailInbound[]) : [];
|
|
579
|
+
}
|
|
580
|
+
throw await toServiceException('GET', url, res.response);
|
|
581
|
+
}
|
|
582
|
+
|
|
583
|
+
async getInbound(id: string): Promise<EmailInbound | null> {
|
|
584
|
+
const url = buildUrl(
|
|
585
|
+
this.#baseUrl,
|
|
586
|
+
`/email/2025-03-17/inbound/${encodeURIComponent(id)}`
|
|
587
|
+
);
|
|
588
|
+
const signal = AbortSignal.timeout(30_000);
|
|
589
|
+
const res = await this.#adapter.invoke<unknown>(url, {
|
|
590
|
+
method: 'GET',
|
|
591
|
+
signal,
|
|
592
|
+
telemetry: {
|
|
593
|
+
name: 'agentuity.email.getInbound',
|
|
594
|
+
attributes: {
|
|
595
|
+
id,
|
|
596
|
+
},
|
|
597
|
+
},
|
|
598
|
+
});
|
|
599
|
+
if (res.response.status === 404) {
|
|
600
|
+
return null;
|
|
601
|
+
}
|
|
602
|
+
if (res.ok) {
|
|
603
|
+
return unwrap<EmailInbound>(res.data, 'inbound');
|
|
604
|
+
}
|
|
605
|
+
throw await toServiceException('GET', url, res.response);
|
|
606
|
+
}
|
|
607
|
+
|
|
608
|
+
async listOutbound(addressId?: string): Promise<EmailOutbound[]> {
|
|
609
|
+
const queryParams = new URLSearchParams();
|
|
610
|
+
if (addressId) {
|
|
611
|
+
queryParams.set('address_id', addressId);
|
|
612
|
+
}
|
|
613
|
+
const queryString = queryParams.toString();
|
|
614
|
+
const url = buildUrl(
|
|
615
|
+
this.#baseUrl,
|
|
616
|
+
`/email/2025-03-17/outbound${queryString ? `?${queryString}` : ''}`
|
|
617
|
+
);
|
|
618
|
+
const signal = AbortSignal.timeout(30_000);
|
|
619
|
+
const res = await this.#adapter.invoke<unknown>(url, {
|
|
620
|
+
method: 'GET',
|
|
621
|
+
signal,
|
|
622
|
+
telemetry: {
|
|
623
|
+
name: 'agentuity.email.listOutbound',
|
|
624
|
+
attributes: {
|
|
625
|
+
...(addressId && { addressId }),
|
|
626
|
+
},
|
|
627
|
+
},
|
|
628
|
+
});
|
|
629
|
+
if (res.response.status === 404) {
|
|
630
|
+
return [];
|
|
631
|
+
}
|
|
632
|
+
if (res.ok) {
|
|
633
|
+
const items = unwrap<unknown>(res.data, 'outbound');
|
|
634
|
+
return Array.isArray(items) ? (items as EmailOutbound[]) : [];
|
|
635
|
+
}
|
|
636
|
+
throw await toServiceException('GET', url, res.response);
|
|
637
|
+
}
|
|
638
|
+
|
|
639
|
+
async getOutbound(id: string): Promise<EmailOutbound | null> {
|
|
640
|
+
const url = buildUrl(
|
|
641
|
+
this.#baseUrl,
|
|
642
|
+
`/email/2025-03-17/outbound/${encodeURIComponent(id)}`
|
|
643
|
+
);
|
|
644
|
+
const signal = AbortSignal.timeout(30_000);
|
|
645
|
+
const res = await this.#adapter.invoke<unknown>(url, {
|
|
646
|
+
method: 'GET',
|
|
647
|
+
signal,
|
|
648
|
+
telemetry: {
|
|
649
|
+
name: 'agentuity.email.getOutbound',
|
|
650
|
+
attributes: {
|
|
651
|
+
id,
|
|
652
|
+
},
|
|
653
|
+
},
|
|
654
|
+
});
|
|
655
|
+
if (res.response.status === 404) {
|
|
656
|
+
return null;
|
|
657
|
+
}
|
|
658
|
+
if (res.ok) {
|
|
659
|
+
return unwrap<EmailOutbound>(res.data, 'outbound');
|
|
660
|
+
}
|
|
661
|
+
throw await toServiceException('GET', url, res.response);
|
|
662
|
+
}
|
|
663
|
+
}
|
package/src/services/index.ts
CHANGED
|
@@ -4,7 +4,10 @@ export * from './exception.ts';
|
|
|
4
4
|
export * from './keyvalue.ts';
|
|
5
5
|
export * from './pagination.ts';
|
|
6
6
|
export * from './sandbox.ts';
|
|
7
|
+
export * from './schedule.ts';
|
|
7
8
|
export * from './session.ts';
|
|
8
9
|
export * from './stream.ts';
|
|
10
|
+
export * from './task.ts';
|
|
9
11
|
export * from './vector.ts';
|
|
12
|
+
export * from './email.ts';
|
|
10
13
|
export { buildUrl, toServiceException, toPayload, fromResponse } from './_util.ts';
|