imessage-sdk 0.1.0-beta.0 → 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +56 -51
- package/dist/index.d.ts +278 -9
- package/dist/index.js +17 -69
- package/dist/index.js.map +1 -1
- package/package.json +7 -28
- package/dist/provider-CCW_6OWg.d.ts +0 -265
- package/dist/providers/blooio.d.ts +0 -76
- package/dist/providers/blooio.js +0 -655
- package/dist/providers/blooio.js.map +0 -1
- package/dist/providers/photon.d.ts +0 -66
- package/dist/providers/photon.js +0 -958
- package/dist/providers/photon.js.map +0 -1
package/README.md
CHANGED
|
@@ -3,18 +3,19 @@
|
|
|
3
3
|
A provider-neutral, type-safe TypeScript conversation layer for iMessage
|
|
4
4
|
infrastructure.
|
|
5
5
|
|
|
6
|
-
The normalized v0.1 client
|
|
7
|
-
|
|
6
|
+
The normalized v0.1 client is implemented here. Blooio v2 and Photon Cloud are
|
|
7
|
+
published as separate provider packages so applications install only the
|
|
8
|
+
provider dependencies they use.
|
|
8
9
|
|
|
9
10
|
The package is ESM-only and ships JavaScript plus TypeScript declarations.
|
|
10
11
|
|
|
11
12
|
> This is a beta release. Install the prerelease with `pnpm add
|
|
12
|
-
|
|
13
|
+
imessage-sdk@beta` while the public API is being validated.
|
|
13
14
|
|
|
14
15
|
## Install
|
|
15
16
|
|
|
16
17
|
```bash
|
|
17
|
-
pnpm add imessage-sdk@beta
|
|
18
|
+
pnpm add imessage-sdk@beta @imessage-sdk/blooio@beta
|
|
18
19
|
```
|
|
19
20
|
|
|
20
21
|
## Creating a client
|
|
@@ -23,8 +24,8 @@ Provider factories consume provider configuration and return a complete,
|
|
|
23
24
|
concrete provider:
|
|
24
25
|
|
|
25
26
|
```ts
|
|
26
|
-
import {
|
|
27
|
-
import {
|
|
27
|
+
import { blooio } from '@imessage-sdk/blooio';
|
|
28
|
+
import { createIMessageClient } from 'imessage-sdk';
|
|
28
29
|
|
|
29
30
|
const client = createIMessageClient({
|
|
30
31
|
provider: blooio(),
|
|
@@ -39,7 +40,7 @@ when the application has multiple connections or sender lines:
|
|
|
39
40
|
|
|
40
41
|
```ts
|
|
41
42
|
const namedClient = createIMessageClient({
|
|
42
|
-
connectionId:
|
|
43
|
+
connectionId: 'main-line',
|
|
43
44
|
provider: blooio(),
|
|
44
45
|
});
|
|
45
46
|
|
|
@@ -74,8 +75,8 @@ client.providers.blooio.name;
|
|
|
74
75
|
client.providers.photon;
|
|
75
76
|
|
|
76
77
|
const sent = await client.messages.send({
|
|
77
|
-
to: { kind:
|
|
78
|
-
text:
|
|
78
|
+
to: { kind: 'phone', value: '+15551234567' },
|
|
79
|
+
text: 'Hello from imessage-sdk',
|
|
79
80
|
});
|
|
80
81
|
|
|
81
82
|
sent.provider;
|
|
@@ -93,26 +94,26 @@ public URLs, while Photon uploads all three source types:
|
|
|
93
94
|
|
|
94
95
|
```ts
|
|
95
96
|
await client.messages.send({
|
|
96
|
-
conversationId:
|
|
97
|
-
text:
|
|
97
|
+
conversationId: 'provider-conversation-id',
|
|
98
|
+
text: 'Three attachments',
|
|
98
99
|
attachments: [
|
|
99
100
|
{
|
|
100
|
-
kind:
|
|
101
|
+
kind: 'image',
|
|
101
102
|
source: {
|
|
102
|
-
type:
|
|
103
|
-
url:
|
|
103
|
+
type: 'url',
|
|
104
|
+
url: 'https://example.com/photo.jpg',
|
|
104
105
|
},
|
|
105
|
-
contentType:
|
|
106
|
+
contentType: 'image/jpeg',
|
|
106
107
|
},
|
|
107
108
|
{
|
|
108
|
-
kind:
|
|
109
|
-
source: { type:
|
|
110
|
-
filename:
|
|
109
|
+
kind: 'video',
|
|
110
|
+
source: { type: 'url', url: 'https://example.com/clip.mp4' },
|
|
111
|
+
filename: 'clip.mp4',
|
|
111
112
|
},
|
|
112
113
|
{
|
|
113
|
-
kind:
|
|
114
|
-
source: { type:
|
|
115
|
-
filename:
|
|
114
|
+
kind: 'file',
|
|
115
|
+
source: { type: 'url', url: 'https://example.com/document.pdf' },
|
|
116
|
+
filename: 'document.pdf',
|
|
116
117
|
},
|
|
117
118
|
],
|
|
118
119
|
});
|
|
@@ -122,10 +123,10 @@ Replies use the provider-native message ID and optional message-part index:
|
|
|
122
123
|
|
|
123
124
|
```ts
|
|
124
125
|
await client.messages.send({
|
|
125
|
-
conversationId:
|
|
126
|
-
text:
|
|
126
|
+
conversationId: 'provider-conversation-id',
|
|
127
|
+
text: 'Replying in this thread',
|
|
127
128
|
replyTo: {
|
|
128
|
-
messageId:
|
|
129
|
+
messageId: 'provider-message-id',
|
|
129
130
|
partIndex: 0,
|
|
130
131
|
},
|
|
131
132
|
});
|
|
@@ -139,15 +140,15 @@ the exact same instance under its typed provider namespace:
|
|
|
139
140
|
```ts
|
|
140
141
|
const provider = blooio();
|
|
141
142
|
const client = createIMessageClient({
|
|
142
|
-
connectionId:
|
|
143
|
+
connectionId: 'main-line',
|
|
143
144
|
provider,
|
|
144
145
|
});
|
|
145
146
|
|
|
146
147
|
client.providers.blooio === provider; // true
|
|
147
148
|
|
|
148
149
|
await client.providers.blooio.messages.send({
|
|
149
|
-
to: { kind:
|
|
150
|
-
text:
|
|
150
|
+
to: { kind: 'phone', value: '+15551234567' },
|
|
151
|
+
text: 'Send directly through Blooio',
|
|
151
152
|
});
|
|
152
153
|
```
|
|
153
154
|
|
|
@@ -155,8 +156,8 @@ The normalized top-level methods remain available:
|
|
|
155
156
|
|
|
156
157
|
```ts
|
|
157
158
|
await client.messages.send({
|
|
158
|
-
to: { kind:
|
|
159
|
-
text:
|
|
159
|
+
to: { kind: 'phone', value: '+15551234567' },
|
|
160
|
+
text: 'Send through the normalized client',
|
|
160
161
|
});
|
|
161
162
|
```
|
|
162
163
|
|
|
@@ -185,11 +186,11 @@ literal name, capability values, and complete concrete provider type.
|
|
|
185
186
|
Conceptually, provider factories are structured like this:
|
|
186
187
|
|
|
187
188
|
```ts
|
|
188
|
-
import { defineProvider } from
|
|
189
|
+
import { defineProvider } from 'imessage-sdk';
|
|
189
190
|
|
|
190
191
|
function blooio(options = {}) {
|
|
191
192
|
return defineProvider({
|
|
192
|
-
name:
|
|
193
|
+
name: 'blooio' as const,
|
|
193
194
|
capabilities: BLOOIO_CAPABILITIES,
|
|
194
195
|
messages: {
|
|
195
196
|
async send(input) {
|
|
@@ -237,7 +238,7 @@ methods:
|
|
|
237
238
|
|
|
238
239
|
```ts
|
|
239
240
|
const custom = defineProvider({
|
|
240
|
-
name:
|
|
241
|
+
name: 'my-provider' as const,
|
|
241
242
|
capabilities: MY_PROVIDER_CAPABILITIES,
|
|
242
243
|
messages: {
|
|
243
244
|
send: sendMessage,
|
|
@@ -255,9 +256,9 @@ customClient.provider;
|
|
|
255
256
|
// ^? "my-provider"
|
|
256
257
|
|
|
257
258
|
// Required because this concrete provider defines it as required.
|
|
258
|
-
await customClient.providers[
|
|
259
|
-
{ conversationId:
|
|
260
|
-
{ text:
|
|
259
|
+
await customClient.providers['my-provider'].messages.edit(
|
|
260
|
+
{ conversationId: 'conversation-id', messageId: 'message-id' },
|
|
261
|
+
{ text: 'Corrected' },
|
|
261
262
|
);
|
|
262
263
|
```
|
|
263
264
|
|
|
@@ -268,12 +269,12 @@ or sender lines, it creates multiple clients and selects one explicitly:
|
|
|
268
269
|
|
|
269
270
|
```ts
|
|
270
271
|
const sales = createIMessageClient({
|
|
271
|
-
connectionId:
|
|
272
|
+
connectionId: 'sales-line',
|
|
272
273
|
provider: blooio(salesOptions),
|
|
273
274
|
});
|
|
274
275
|
|
|
275
276
|
const support = createIMessageClient({
|
|
276
|
-
connectionId:
|
|
277
|
+
connectionId: 'support-line',
|
|
277
278
|
provider: photon(supportOptions),
|
|
278
279
|
});
|
|
279
280
|
```
|
|
@@ -309,10 +310,10 @@ feature checks:
|
|
|
309
310
|
if (client.capabilities.messages.edit) {
|
|
310
311
|
await client.messages.edit(
|
|
311
312
|
{
|
|
312
|
-
conversationId:
|
|
313
|
-
messageId:
|
|
313
|
+
conversationId: 'provider-conversation-id',
|
|
314
|
+
messageId: 'provider-message-id',
|
|
314
315
|
},
|
|
315
|
-
{ text:
|
|
316
|
+
{ text: 'Corrected' },
|
|
316
317
|
);
|
|
317
318
|
}
|
|
318
319
|
```
|
|
@@ -326,6 +327,10 @@ construction, while stream providers connect lazily when subscribed.
|
|
|
326
327
|
`client.close()` is always available and idempotent. It is a no-op when the
|
|
327
328
|
provider has no cleanup and releases resources for stream or local transports.
|
|
328
329
|
|
|
330
|
+
All available normalized v0.1 operations are stable except webhook handling.
|
|
331
|
+
`client.webhooks`, `ProviderWebhooks`, and webhook event normalization are
|
|
332
|
+
marked experimental and may change incompatibly during the 0.1 release line.
|
|
333
|
+
|
|
329
334
|
## Blooio operations
|
|
330
335
|
|
|
331
336
|
The v0.1 Blooio adapter supports text and public URL attachments, inline
|
|
@@ -340,15 +345,15 @@ const locator = {
|
|
|
340
345
|
};
|
|
341
346
|
|
|
342
347
|
await client.messages.get(locator);
|
|
343
|
-
await client.reactions.add({ ...locator, reaction:
|
|
348
|
+
await client.reactions.add({ ...locator, reaction: 'like' });
|
|
344
349
|
await client.typing.start(sent.conversationId);
|
|
345
350
|
await client.typing.stop(sent.conversationId);
|
|
346
351
|
await client.conversations.markRead(sent.conversationId);
|
|
347
352
|
```
|
|
348
353
|
|
|
349
|
-
|
|
350
|
-
array because one provider delivery can represent zero, one, or
|
|
351
|
-
normalized events:
|
|
354
|
+
Experimental webhook handling verifies `X-Blooio-Signature` before parsing and
|
|
355
|
+
returns an array because one provider delivery can represent zero, one, or
|
|
356
|
+
multiple normalized events:
|
|
352
357
|
|
|
353
358
|
```ts
|
|
354
359
|
const events = await client.webhooks.handle(request);
|
|
@@ -367,7 +372,7 @@ export BLOOIO_TEST_IMAGE_URL="https://..."
|
|
|
367
372
|
export BLOOIO_TEST_VIDEO_URL="https://..."
|
|
368
373
|
export BLOOIO_TEST_FILE_URL="https://..."
|
|
369
374
|
|
|
370
|
-
pnpm --filter imessage-sdk test:integration
|
|
375
|
+
pnpm --filter @imessage-sdk/blooio test:integration
|
|
371
376
|
```
|
|
372
377
|
|
|
373
378
|
It sends three messages and exercises lookup/status, reactions, typing, and
|
|
@@ -380,11 +385,11 @@ Photon authenticates with Spectrum Cloud lazily. A dedicated phone is optional
|
|
|
380
385
|
when the project owns exactly one line and required when it owns multiple:
|
|
381
386
|
|
|
382
387
|
```ts
|
|
383
|
-
import {
|
|
384
|
-
import {
|
|
388
|
+
import { photon } from '@imessage-sdk/photon';
|
|
389
|
+
import { createIMessageClient } from 'imessage-sdk';
|
|
385
390
|
|
|
386
391
|
const client = createIMessageClient({
|
|
387
|
-
connectionId:
|
|
392
|
+
connectionId: 'photon-main',
|
|
388
393
|
provider: photon(),
|
|
389
394
|
});
|
|
390
395
|
|
|
@@ -407,7 +412,7 @@ Cursors are durable numeric event sequences represented as strings:
|
|
|
407
412
|
|
|
408
413
|
```ts
|
|
409
414
|
for await (const event of client.providers.photon.events.subscribe({
|
|
410
|
-
cursor:
|
|
415
|
+
cursor: '123',
|
|
411
416
|
})) {
|
|
412
417
|
console.log(event.providerEventId, event.type);
|
|
413
418
|
}
|
|
@@ -430,7 +435,7 @@ export PHOTON_TEST_IMAGE_URL="https://..."
|
|
|
430
435
|
export PHOTON_TEST_VIDEO_URL="https://..."
|
|
431
436
|
export PHOTON_TEST_FILE_URL="https://..."
|
|
432
437
|
|
|
433
|
-
pnpm --filter imessage-sdk test:integration
|
|
438
|
+
pnpm --filter @imessage-sdk/photon test:integration
|
|
434
439
|
```
|
|
435
440
|
|
|
436
441
|
On Photon Free and Pro shared lines, add the recipient under the project's
|
|
@@ -444,7 +449,7 @@ persistent stream, run the command below and send an iMessage to the line
|
|
|
444
449
|
within 60 seconds:
|
|
445
450
|
|
|
446
451
|
```bash
|
|
447
|
-
pnpm --filter imessage-sdk test:integration:
|
|
452
|
+
pnpm --filter @imessage-sdk/photon test:integration:stream
|
|
448
453
|
```
|
|
449
454
|
|
|
450
455
|
## v0.1 beta boundary
|
package/dist/index.d.ts
CHANGED
|
@@ -1,5 +1,31 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
1
|
+
/** Runtime feature declaration for one configured provider connection. */
|
|
2
|
+
interface IMessageCapabilities {
|
|
3
|
+
readonly messages: {
|
|
4
|
+
readonly text: boolean;
|
|
5
|
+
readonly attachments: boolean;
|
|
6
|
+
readonly replies: boolean;
|
|
7
|
+
readonly get: boolean;
|
|
8
|
+
readonly edit: boolean;
|
|
9
|
+
readonly delete: boolean;
|
|
10
|
+
};
|
|
11
|
+
readonly conversations: {
|
|
12
|
+
readonly direct: boolean;
|
|
13
|
+
readonly groups: boolean;
|
|
14
|
+
readonly get: boolean;
|
|
15
|
+
readonly markRead: boolean;
|
|
16
|
+
};
|
|
17
|
+
readonly interactions: {
|
|
18
|
+
readonly reactions: boolean;
|
|
19
|
+
readonly typingStart: boolean;
|
|
20
|
+
readonly typingStop: boolean;
|
|
21
|
+
readonly readReceipts: boolean;
|
|
22
|
+
};
|
|
23
|
+
readonly events: {
|
|
24
|
+
/** @experimental Webhook normalization may change before a future stable release. */
|
|
25
|
+
readonly webhooks: boolean;
|
|
26
|
+
readonly stream: boolean;
|
|
27
|
+
};
|
|
28
|
+
}
|
|
3
29
|
|
|
4
30
|
/**
|
|
5
31
|
* Creates a diagnostic fallback when a provider message omits its native
|
|
@@ -47,27 +73,269 @@ declare class AmbiguousDeliveryError extends IMessageSDKError {
|
|
|
47
73
|
}
|
|
48
74
|
declare class UnsupportedCapabilityError extends IMessageSDKError {
|
|
49
75
|
readonly capability: string;
|
|
50
|
-
constructor(capability: string, options?: Pick<IMessageSDKErrorOptions,
|
|
76
|
+
constructor(capability: string, options?: Pick<IMessageSDKErrorOptions, 'provider' | 'connectionId'>);
|
|
51
77
|
}
|
|
52
78
|
declare class WebhookVerificationError extends IMessageSDKError {
|
|
53
|
-
constructor(options?: Pick<IMessageSDKErrorOptions,
|
|
79
|
+
constructor(options?: Pick<IMessageSDKErrorOptions, 'provider' | 'connectionId'>);
|
|
54
80
|
}
|
|
55
81
|
declare class ClientClosedError extends IMessageSDKError {
|
|
56
|
-
constructor(options?: Pick<IMessageSDKErrorOptions,
|
|
82
|
+
constructor(options?: Pick<IMessageSDKErrorOptions, 'provider' | 'connectionId'>);
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
/** Provider names stay literal through generics but are open to custom adapters. */
|
|
86
|
+
type IMessageProviderName = string;
|
|
87
|
+
type IMessageAddressKind = 'phone' | 'email';
|
|
88
|
+
interface IMessageAddress {
|
|
89
|
+
readonly kind: IMessageAddressKind;
|
|
90
|
+
readonly value: string;
|
|
91
|
+
}
|
|
92
|
+
type NonEmptyReadonlyArray<T> = readonly [T, ...T[]];
|
|
93
|
+
type IMessageAttachmentKind = 'image' | 'video' | 'file';
|
|
94
|
+
type IMessageAttachmentSource = {
|
|
95
|
+
readonly type: 'url';
|
|
96
|
+
/** A URL that the selected provider can fetch. */
|
|
97
|
+
readonly url: string;
|
|
98
|
+
} | {
|
|
99
|
+
readonly type: 'blob';
|
|
100
|
+
readonly data: Blob;
|
|
101
|
+
} | {
|
|
102
|
+
readonly type: 'bytes';
|
|
103
|
+
readonly data: Uint8Array;
|
|
104
|
+
};
|
|
105
|
+
interface IMessageAttachmentInput {
|
|
106
|
+
readonly kind: IMessageAttachmentKind;
|
|
107
|
+
readonly source: IMessageAttachmentSource;
|
|
108
|
+
readonly filename?: string;
|
|
109
|
+
readonly contentType?: string;
|
|
110
|
+
}
|
|
111
|
+
interface IMessageAttachment {
|
|
112
|
+
readonly kind: IMessageAttachmentKind;
|
|
113
|
+
readonly id?: string;
|
|
114
|
+
readonly url?: string;
|
|
115
|
+
readonly filename?: string;
|
|
116
|
+
readonly contentType?: string;
|
|
117
|
+
readonly size?: number;
|
|
118
|
+
readonly raw: unknown;
|
|
119
|
+
}
|
|
120
|
+
interface MessageReplyReference {
|
|
121
|
+
/** Provider-native message identifier. */
|
|
122
|
+
readonly messageId: string;
|
|
123
|
+
readonly partIndex?: number;
|
|
124
|
+
}
|
|
125
|
+
/** Identifies a provider message within its native conversation. */
|
|
126
|
+
interface MessageLocator {
|
|
127
|
+
readonly conversationId: string;
|
|
128
|
+
readonly messageId: string;
|
|
129
|
+
}
|
|
130
|
+
type SendDestination = {
|
|
131
|
+
readonly conversationId: string;
|
|
132
|
+
readonly to?: never;
|
|
133
|
+
} | {
|
|
134
|
+
readonly conversationId?: never;
|
|
135
|
+
readonly to: IMessageAddress | NonEmptyReadonlyArray<IMessageAddress>;
|
|
136
|
+
};
|
|
137
|
+
type SendContent = {
|
|
138
|
+
readonly text: string;
|
|
139
|
+
readonly attachments?: readonly IMessageAttachmentInput[];
|
|
140
|
+
} | {
|
|
141
|
+
readonly text?: string;
|
|
142
|
+
readonly attachments: NonEmptyReadonlyArray<IMessageAttachmentInput>;
|
|
143
|
+
};
|
|
144
|
+
type SendMessageInput = SendDestination & SendContent & {
|
|
145
|
+
readonly replyTo?: MessageReplyReference;
|
|
146
|
+
readonly idempotencyKey?: string;
|
|
147
|
+
readonly metadata?: Readonly<Record<string, string>>;
|
|
148
|
+
};
|
|
149
|
+
interface EditMessageInput {
|
|
150
|
+
readonly text: string;
|
|
151
|
+
}
|
|
152
|
+
type IMessageDirection = 'inbound' | 'outbound';
|
|
153
|
+
type IMessageService = 'imessage' | 'sms' | 'rcs' | 'unknown';
|
|
154
|
+
type IMessageStatus = 'pending' | 'accepted' | 'sent' | 'delivered' | 'read' | 'failed';
|
|
155
|
+
/**
|
|
156
|
+
* A provider-normalized message before the client adds connection identity.
|
|
157
|
+
* Provider adapters return this shape.
|
|
158
|
+
*/
|
|
159
|
+
interface ProviderMessage {
|
|
160
|
+
readonly providerMessageId: string;
|
|
161
|
+
/** Opaque provider-native ID, scoped to one provider connection. */
|
|
162
|
+
readonly conversationId?: string;
|
|
163
|
+
readonly direction: IMessageDirection;
|
|
164
|
+
readonly sender: IMessageAddress;
|
|
165
|
+
readonly recipients: readonly IMessageAddress[];
|
|
166
|
+
readonly text: string;
|
|
167
|
+
readonly attachments: readonly IMessageAttachment[];
|
|
168
|
+
readonly replyTo?: MessageReplyReference;
|
|
169
|
+
readonly service: IMessageService;
|
|
170
|
+
readonly status: IMessageStatus;
|
|
171
|
+
readonly providerStatus?: string;
|
|
172
|
+
readonly createdAt: Date;
|
|
173
|
+
readonly sentAt?: Date;
|
|
174
|
+
readonly deliveredAt?: Date;
|
|
175
|
+
readonly readAt?: Date;
|
|
176
|
+
readonly raw: unknown;
|
|
177
|
+
}
|
|
178
|
+
type ProviderSentMessage = ProviderMessage & {
|
|
179
|
+
readonly direction: 'outbound';
|
|
180
|
+
};
|
|
181
|
+
/** A message returned by a client bound to one provider connection. */
|
|
182
|
+
type Message<TProvider extends IMessageProviderName = IMessageProviderName, TConnectionId extends string = string> = Omit<ProviderMessage, 'conversationId'> & {
|
|
183
|
+
/** Equal to providerMessageId in v0.1. */
|
|
184
|
+
readonly id: string;
|
|
185
|
+
/** Provider-native when available; otherwise a non-routable imsg-sdk-v1 fallback. */
|
|
186
|
+
readonly conversationId: string;
|
|
187
|
+
readonly provider: TProvider;
|
|
188
|
+
readonly connectionId: TConnectionId;
|
|
189
|
+
};
|
|
190
|
+
type SentMessage<TProvider extends IMessageProviderName = IMessageProviderName, TConnectionId extends string = string> = Message<TProvider, TConnectionId> & {
|
|
191
|
+
readonly direction: 'outbound';
|
|
192
|
+
};
|
|
193
|
+
interface OpenConversationInput {
|
|
194
|
+
readonly participants: NonEmptyReadonlyArray<IMessageAddress>;
|
|
195
|
+
}
|
|
196
|
+
interface ProviderConversation {
|
|
197
|
+
/** Opaque provider-native ID, scoped to one provider connection. */
|
|
198
|
+
readonly providerConversationId: string;
|
|
199
|
+
readonly participants: readonly IMessageAddress[];
|
|
200
|
+
readonly createdAt?: Date;
|
|
201
|
+
readonly raw: unknown;
|
|
202
|
+
}
|
|
203
|
+
type Conversation<TProvider extends IMessageProviderName = IMessageProviderName, TConnectionId extends string = string> = ProviderConversation & {
|
|
204
|
+
/** Equal to providerConversationId in v0.1; scope with provider and connectionId. */
|
|
205
|
+
readonly id: string;
|
|
206
|
+
readonly provider: TProvider;
|
|
207
|
+
readonly connectionId: TConnectionId;
|
|
208
|
+
};
|
|
209
|
+
type IMessageReaction = 'love' | 'like' | 'dislike' | 'laugh' | 'emphasize' | 'question';
|
|
210
|
+
interface AddReactionInput extends MessageLocator {
|
|
211
|
+
readonly reaction: IMessageReaction;
|
|
212
|
+
readonly partIndex?: number;
|
|
213
|
+
}
|
|
214
|
+
type RemoveReactionInput = AddReactionInput;
|
|
215
|
+
interface SubscribeOptions {
|
|
216
|
+
readonly cursor?: string;
|
|
217
|
+
readonly signal?: AbortSignal;
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
interface ProviderEventBase<TType extends string> {
|
|
221
|
+
readonly id: string;
|
|
222
|
+
readonly providerEventId?: string;
|
|
223
|
+
readonly type: TType;
|
|
224
|
+
readonly timestamp: Date;
|
|
225
|
+
readonly raw: unknown;
|
|
226
|
+
}
|
|
227
|
+
type ProviderMessageEventType = 'message.received' | 'message.sent' | 'message.delivered' | 'message.read' | 'message.failed' | 'message.edited';
|
|
228
|
+
interface ProviderMessageEvent<TType extends ProviderMessageEventType = ProviderMessageEventType> extends ProviderEventBase<TType> {
|
|
229
|
+
readonly message: ProviderMessage;
|
|
230
|
+
}
|
|
231
|
+
interface ProviderMessageDeletedEvent extends ProviderEventBase<'message.deleted'> {
|
|
232
|
+
readonly conversationId: string;
|
|
233
|
+
readonly messageId: string;
|
|
234
|
+
}
|
|
235
|
+
type ProviderReactionEventType = 'reaction.added' | 'reaction.removed';
|
|
236
|
+
interface ProviderReactionEvent<TType extends ProviderReactionEventType = ProviderReactionEventType> extends ProviderEventBase<TType> {
|
|
237
|
+
readonly conversationId: string;
|
|
238
|
+
readonly messageId: string;
|
|
239
|
+
readonly actor: IMessageAddress;
|
|
240
|
+
readonly reaction: IMessageReaction;
|
|
241
|
+
readonly partIndex?: number;
|
|
242
|
+
}
|
|
243
|
+
type ProviderTypingEventType = 'typing.started' | 'typing.stopped';
|
|
244
|
+
interface ProviderTypingEvent<TType extends ProviderTypingEventType = ProviderTypingEventType> extends ProviderEventBase<TType> {
|
|
245
|
+
readonly conversationId: string;
|
|
246
|
+
/** Some group transports do not identify which participant is typing. */
|
|
247
|
+
readonly actor?: IMessageAddress;
|
|
248
|
+
}
|
|
249
|
+
type ProviderEvent = ProviderMessageEvent | ProviderMessageDeletedEvent | ProviderReactionEvent | ProviderTypingEvent;
|
|
250
|
+
interface IMessageEventBase<TProvider extends IMessageProviderName, TConnectionId extends string, TType extends string> extends ProviderEventBase<TType> {
|
|
251
|
+
readonly provider: TProvider;
|
|
252
|
+
readonly connectionId: TConnectionId;
|
|
253
|
+
}
|
|
254
|
+
interface IMessageMessageEvent<TProvider extends IMessageProviderName, TConnectionId extends string, TType extends ProviderMessageEventType = ProviderMessageEventType> extends IMessageEventBase<TProvider, TConnectionId, TType> {
|
|
255
|
+
readonly message: Message<TProvider, TConnectionId>;
|
|
256
|
+
}
|
|
257
|
+
interface IMessageDeletedEvent<TProvider extends IMessageProviderName, TConnectionId extends string> extends IMessageEventBase<TProvider, TConnectionId, 'message.deleted'> {
|
|
258
|
+
readonly conversationId: string;
|
|
259
|
+
readonly messageId: string;
|
|
260
|
+
}
|
|
261
|
+
interface IMessageReactionEvent<TProvider extends IMessageProviderName, TConnectionId extends string, TType extends ProviderReactionEventType = ProviderReactionEventType> extends IMessageEventBase<TProvider, TConnectionId, TType> {
|
|
262
|
+
readonly conversationId: string;
|
|
263
|
+
readonly messageId: string;
|
|
264
|
+
readonly actor: IMessageAddress;
|
|
265
|
+
readonly reaction: IMessageReaction;
|
|
266
|
+
readonly partIndex?: number;
|
|
267
|
+
}
|
|
268
|
+
interface IMessageTypingEvent<TProvider extends IMessageProviderName, TConnectionId extends string, TType extends ProviderTypingEventType = ProviderTypingEventType> extends IMessageEventBase<TProvider, TConnectionId, TType> {
|
|
269
|
+
readonly conversationId: string;
|
|
270
|
+
readonly actor?: IMessageAddress;
|
|
271
|
+
}
|
|
272
|
+
type IMessageEvent<TProvider extends IMessageProviderName = IMessageProviderName, TConnectionId extends string = string> = IMessageMessageEvent<TProvider, TConnectionId> | IMessageDeletedEvent<TProvider, TConnectionId> | IMessageReactionEvent<TProvider, TConnectionId> | IMessageTypingEvent<TProvider, TConnectionId>;
|
|
273
|
+
|
|
274
|
+
interface ProviderMessages {
|
|
275
|
+
send(input: SendMessageInput): Promise<ProviderSentMessage>;
|
|
276
|
+
get?(message: MessageLocator): Promise<ProviderMessage | null>;
|
|
277
|
+
edit?(message: MessageLocator, input: EditMessageInput): Promise<ProviderMessage>;
|
|
278
|
+
delete?(message: MessageLocator): Promise<void>;
|
|
279
|
+
}
|
|
280
|
+
interface ProviderConversations {
|
|
281
|
+
open(input: OpenConversationInput): Promise<ProviderConversation>;
|
|
282
|
+
get?(conversationId: string): Promise<ProviderConversation | null>;
|
|
283
|
+
markRead?(conversationId: string): Promise<void>;
|
|
284
|
+
}
|
|
285
|
+
interface ProviderReactions {
|
|
286
|
+
add(input: AddReactionInput): Promise<void>;
|
|
287
|
+
remove(input: RemoveReactionInput): Promise<void>;
|
|
288
|
+
}
|
|
289
|
+
interface ProviderTyping {
|
|
290
|
+
start(conversationId: string): Promise<void>;
|
|
291
|
+
stop?(conversationId: string): Promise<void>;
|
|
292
|
+
}
|
|
293
|
+
/**
|
|
294
|
+
* Provider webhook verification and normalization contract.
|
|
295
|
+
*
|
|
296
|
+
* @experimental Webhook normalization may change before a future stable release.
|
|
297
|
+
*/
|
|
298
|
+
interface ProviderWebhooks {
|
|
299
|
+
verify(request: Request): Promise<boolean>;
|
|
300
|
+
parse(request: Request): Promise<readonly ProviderEvent[]>;
|
|
301
|
+
}
|
|
302
|
+
interface ProviderEvents {
|
|
303
|
+
subscribe(options?: SubscribeOptions): AsyncIterable<ProviderEvent>;
|
|
304
|
+
}
|
|
305
|
+
/**
|
|
306
|
+
* Contract implemented by a provider adapter.
|
|
307
|
+
*
|
|
308
|
+
* The complete adapter is exposed at `client.providers.<name>`, so
|
|
309
|
+
* provider-specific APIs should be defined directly on the concrete provider.
|
|
310
|
+
*/
|
|
311
|
+
interface IMessageProvider<TName extends IMessageProviderName = IMessageProviderName, TCapabilities extends IMessageCapabilities = IMessageCapabilities> {
|
|
312
|
+
readonly name: TName;
|
|
313
|
+
readonly capabilities: TCapabilities;
|
|
314
|
+
readonly messages: ProviderMessages;
|
|
315
|
+
readonly conversations: ProviderConversations;
|
|
316
|
+
readonly reactions?: ProviderReactions;
|
|
317
|
+
readonly typing?: ProviderTyping;
|
|
318
|
+
/** @experimental Webhook normalization may change before a future stable release. */
|
|
319
|
+
readonly webhooks?: ProviderWebhooks;
|
|
320
|
+
readonly events?: ProviderEvents;
|
|
321
|
+
close?(): Promise<void>;
|
|
57
322
|
}
|
|
323
|
+
type AnyIMessageProvider = IMessageProvider<IMessageProviderName, IMessageCapabilities>;
|
|
324
|
+
/** Preserves the concrete name, capabilities, and methods of an adapter. */
|
|
325
|
+
declare function defineProvider<const TProvider extends AnyIMessageProvider>(provider: TProvider): TProvider;
|
|
58
326
|
|
|
59
|
-
type ProviderNameOf<TProvider extends AnyIMessageProvider> = TProvider[
|
|
327
|
+
type ProviderNameOf<TProvider extends AnyIMessageProvider> = TProvider['name'];
|
|
60
328
|
declare const DEFAULT_CONNECTION_ID: "default";
|
|
61
329
|
type ClientProvider<TProvider extends AnyIMessageProvider> = TProvider;
|
|
62
330
|
type ClientProviders<TProvider extends AnyIMessageProvider> = {
|
|
63
|
-
readonly [TName in TProvider[
|
|
331
|
+
readonly [TName in TProvider['name']]: ClientProvider<Extract<TProvider, {
|
|
64
332
|
readonly name: TName;
|
|
65
333
|
}>>;
|
|
66
334
|
};
|
|
67
335
|
interface IMessageClient<TProvider extends AnyIMessageProvider = AnyIMessageProvider, TConnectionId extends string = string> {
|
|
68
336
|
readonly provider: ProviderNameOf<TProvider>;
|
|
69
337
|
readonly connectionId: TConnectionId;
|
|
70
|
-
readonly capabilities: TProvider[
|
|
338
|
+
readonly capabilities: TProvider['capabilities'];
|
|
71
339
|
readonly providers: ClientProviders<TProvider>;
|
|
72
340
|
readonly messages: {
|
|
73
341
|
send(input: SendMessageInput): Promise<SentMessage<ProviderNameOf<TProvider>, TConnectionId>>;
|
|
@@ -88,6 +356,7 @@ interface IMessageClient<TProvider extends AnyIMessageProvider = AnyIMessageProv
|
|
|
88
356
|
start(conversationId: string): Promise<void>;
|
|
89
357
|
stop(conversationId: string): Promise<void>;
|
|
90
358
|
};
|
|
359
|
+
/** @experimental Webhook normalization may change before a future stable release. */
|
|
91
360
|
readonly webhooks: {
|
|
92
361
|
handle(request: Request): Promise<readonly IMessageEvent<ProviderNameOf<TProvider>, TConnectionId>[]>;
|
|
93
362
|
};
|
|
@@ -102,4 +371,4 @@ interface CreateIMessageClientOptions<TProvider extends AnyIMessageProvider, TCo
|
|
|
102
371
|
}
|
|
103
372
|
declare function createIMessageClient<const TProvider extends AnyIMessageProvider, const TConnectionId extends string = typeof DEFAULT_CONNECTION_ID>(options: CreateIMessageClientOptions<TProvider, TConnectionId>): IMessageClient<TProvider, TConnectionId>;
|
|
104
373
|
|
|
105
|
-
export { AddReactionInput, AmbiguousDeliveryError, AnyIMessageProvider, AuthenticationError, ClientClosedError, type ClientProvider, type ClientProviders, ConflictError, Conversation, type CreateIMessageClientOptions, DEFAULT_CONNECTION_ID, EditMessageInput, type IMessageClient, IMessageEvent, IMessageSDKError, type IMessageSDKErrorOptions, Message, MessageLocator, NotFoundError, OpenConversationInput, ProviderUnavailableError, RateLimitError, RemoveReactionInput, SendMessageInput, SentMessage, SubscribeOptions, UnsupportedCapabilityError, ValidationError, WebhookVerificationError, createFallbackConversationId, createIMessageClient, isFallbackConversationId };
|
|
374
|
+
export { type AddReactionInput, AmbiguousDeliveryError, type AnyIMessageProvider, AuthenticationError, ClientClosedError, type ClientProvider, type ClientProviders, ConflictError, type Conversation, type CreateIMessageClientOptions, DEFAULT_CONNECTION_ID, type EditMessageInput, type IMessageAddress, type IMessageAddressKind, type IMessageAttachment, type IMessageAttachmentInput, type IMessageAttachmentKind, type IMessageAttachmentSource, type IMessageCapabilities, type IMessageClient, type IMessageDeletedEvent, type IMessageDirection, type IMessageEvent, type IMessageEventBase, type IMessageMessageEvent, type IMessageProvider, type IMessageProviderName, type IMessageReaction, type IMessageReactionEvent, IMessageSDKError, type IMessageSDKErrorOptions, type IMessageService, type IMessageStatus, type IMessageTypingEvent, type Message, type MessageLocator, type MessageReplyReference, type NonEmptyReadonlyArray, NotFoundError, type OpenConversationInput, type ProviderConversation, type ProviderConversations, type ProviderEvent, type ProviderEventBase, type ProviderEvents, type ProviderMessage, type ProviderMessageDeletedEvent, type ProviderMessageEvent, type ProviderMessageEventType, type ProviderMessages, type ProviderReactionEvent, type ProviderReactionEventType, type ProviderReactions, type ProviderSentMessage, type ProviderTyping, type ProviderTypingEvent, type ProviderTypingEventType, ProviderUnavailableError, type ProviderWebhooks, RateLimitError, type RemoveReactionInput, type SendMessageInput, type SentMessage, type SubscribeOptions, UnsupportedCapabilityError, ValidationError, WebhookVerificationError, createFallbackConversationId, createIMessageClient, defineProvider, isFallbackConversationId };
|