imessage-sdk 0.1.0-beta.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/LICENSE +21 -0
- package/README.md +465 -0
- package/dist/index.d.ts +105 -0
- package/dist/index.js +438 -0
- package/dist/index.js.map +1 -0
- package/dist/provider-CCW_6OWg.d.ts +265 -0
- package/dist/providers/blooio.d.ts +76 -0
- package/dist/providers/blooio.js +655 -0
- package/dist/providers/blooio.js.map +1 -0
- package/dist/providers/photon.d.ts +66 -0
- package/dist/providers/photon.js +958 -0
- package/dist/providers/photon.js.map +1 -0
- package/package.json +74 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 imessage-sdk contributors
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,465 @@
|
|
|
1
|
+
# imessage-sdk
|
|
2
|
+
|
|
3
|
+
A provider-neutral, type-safe TypeScript conversation layer for iMessage
|
|
4
|
+
infrastructure.
|
|
5
|
+
|
|
6
|
+
The normalized v0.1 client, Blooio v2 provider, and Photon Cloud provider are
|
|
7
|
+
implemented.
|
|
8
|
+
|
|
9
|
+
The package is ESM-only and ships JavaScript plus TypeScript declarations.
|
|
10
|
+
|
|
11
|
+
> This is a beta release. Install the prerelease with `pnpm add
|
|
12
|
+
> imessage-sdk@beta` while the public API is being validated.
|
|
13
|
+
|
|
14
|
+
## Install
|
|
15
|
+
|
|
16
|
+
```bash
|
|
17
|
+
pnpm add imessage-sdk@beta
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
## Creating a client
|
|
21
|
+
|
|
22
|
+
Provider factories consume provider configuration and return a complete,
|
|
23
|
+
concrete provider:
|
|
24
|
+
|
|
25
|
+
```ts
|
|
26
|
+
import { createIMessageClient } from "imessage-sdk";
|
|
27
|
+
import { blooio } from "imessage-sdk/providers/blooio";
|
|
28
|
+
|
|
29
|
+
const client = createIMessageClient({
|
|
30
|
+
provider: blooio(),
|
|
31
|
+
});
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
Provider options override environment defaults. `blooio()` reads
|
|
35
|
+
`BLOOIO_API_KEY`, `BLOOIO_FROM_NUMBER`, and `BLOOIO_WEBHOOK_SECRET`.
|
|
36
|
+
|
|
37
|
+
`connectionId` is optional and defaults to the literal `"default"`. Supply one
|
|
38
|
+
when the application has multiple connections or sender lines:
|
|
39
|
+
|
|
40
|
+
```ts
|
|
41
|
+
const namedClient = createIMessageClient({
|
|
42
|
+
connectionId: "main-line",
|
|
43
|
+
provider: blooio(),
|
|
44
|
+
});
|
|
45
|
+
|
|
46
|
+
namedClient.connectionId;
|
|
47
|
+
// ^? "main-line"
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
`blooio()` can be constructed without explicit options for dependency wiring
|
|
51
|
+
and type tests. If neither options nor environment credentials are available,
|
|
52
|
+
API operations throw a typed `AuthenticationError`.
|
|
53
|
+
|
|
54
|
+
```ts
|
|
55
|
+
const client = createIMessageClient({
|
|
56
|
+
provider: blooio(),
|
|
57
|
+
});
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
The provider and connection literals are inferred through the client and its
|
|
61
|
+
results:
|
|
62
|
+
|
|
63
|
+
```ts
|
|
64
|
+
client.provider;
|
|
65
|
+
// ^? "blooio"
|
|
66
|
+
|
|
67
|
+
client.connectionId;
|
|
68
|
+
// ^? "default"
|
|
69
|
+
|
|
70
|
+
client.providers.blooio.name;
|
|
71
|
+
// ^? "blooio"
|
|
72
|
+
|
|
73
|
+
// @ts-expect-error Only the configured provider exists.
|
|
74
|
+
client.providers.photon;
|
|
75
|
+
|
|
76
|
+
const sent = await client.messages.send({
|
|
77
|
+
to: { kind: "phone", value: "+15551234567" },
|
|
78
|
+
text: "Hello from imessage-sdk",
|
|
79
|
+
});
|
|
80
|
+
|
|
81
|
+
sent.provider;
|
|
82
|
+
// ^? "blooio"
|
|
83
|
+
|
|
84
|
+
sent.connectionId;
|
|
85
|
+
// ^? "default"
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
## Attachments and replies
|
|
89
|
+
|
|
90
|
+
Attachments declare what they contain independently from transport. The core
|
|
91
|
+
model accepts URLs, `Blob`, and `Uint8Array`; Blooio v2 currently accepts only
|
|
92
|
+
public URLs, while Photon uploads all three source types:
|
|
93
|
+
|
|
94
|
+
```ts
|
|
95
|
+
await client.messages.send({
|
|
96
|
+
conversationId: "provider-conversation-id",
|
|
97
|
+
text: "Three attachments",
|
|
98
|
+
attachments: [
|
|
99
|
+
{
|
|
100
|
+
kind: "image",
|
|
101
|
+
source: {
|
|
102
|
+
type: "url",
|
|
103
|
+
url: "https://example.com/photo.jpg",
|
|
104
|
+
},
|
|
105
|
+
contentType: "image/jpeg",
|
|
106
|
+
},
|
|
107
|
+
{
|
|
108
|
+
kind: "video",
|
|
109
|
+
source: { type: "url", url: "https://example.com/clip.mp4" },
|
|
110
|
+
filename: "clip.mp4",
|
|
111
|
+
},
|
|
112
|
+
{
|
|
113
|
+
kind: "file",
|
|
114
|
+
source: { type: "url", url: "https://example.com/document.pdf" },
|
|
115
|
+
filename: "document.pdf",
|
|
116
|
+
},
|
|
117
|
+
],
|
|
118
|
+
});
|
|
119
|
+
```
|
|
120
|
+
|
|
121
|
+
Replies use the provider-native message ID and optional message-part index:
|
|
122
|
+
|
|
123
|
+
```ts
|
|
124
|
+
await client.messages.send({
|
|
125
|
+
conversationId: "provider-conversation-id",
|
|
126
|
+
text: "Replying in this thread",
|
|
127
|
+
replyTo: {
|
|
128
|
+
messageId: "provider-message-id",
|
|
129
|
+
partIndex: 0,
|
|
130
|
+
},
|
|
131
|
+
});
|
|
132
|
+
```
|
|
133
|
+
|
|
134
|
+
## Provider encapsulation
|
|
135
|
+
|
|
136
|
+
Everything implemented by an adapter lives on its provider. The client exposes
|
|
137
|
+
the exact same instance under its typed provider namespace:
|
|
138
|
+
|
|
139
|
+
```ts
|
|
140
|
+
const provider = blooio();
|
|
141
|
+
const client = createIMessageClient({
|
|
142
|
+
connectionId: "main-line",
|
|
143
|
+
provider,
|
|
144
|
+
});
|
|
145
|
+
|
|
146
|
+
client.providers.blooio === provider; // true
|
|
147
|
+
|
|
148
|
+
await client.providers.blooio.messages.send({
|
|
149
|
+
to: { kind: "phone", value: "+15551234567" },
|
|
150
|
+
text: "Send directly through Blooio",
|
|
151
|
+
});
|
|
152
|
+
```
|
|
153
|
+
|
|
154
|
+
The normalized top-level methods remain available:
|
|
155
|
+
|
|
156
|
+
```ts
|
|
157
|
+
await client.messages.send({
|
|
158
|
+
to: { kind: "phone", value: "+15551234567" },
|
|
159
|
+
text: "Send through the normalized client",
|
|
160
|
+
});
|
|
161
|
+
```
|
|
162
|
+
|
|
163
|
+
They add the connection ID to results, decorate events, verify capability
|
|
164
|
+
support consistently, and produce normalized SDK errors.
|
|
165
|
+
|
|
166
|
+
Provider-specific methods are defined directly on the provider. Blooio exposes
|
|
167
|
+
its status endpoint without adding it to every adapter's normalized contract:
|
|
168
|
+
|
|
169
|
+
```ts
|
|
170
|
+
const status = await client.providers.blooio.messages.getStatus({
|
|
171
|
+
conversationId: sent.conversationId,
|
|
172
|
+
messageId: sent.providerMessageId,
|
|
173
|
+
});
|
|
174
|
+
|
|
175
|
+
const linkedNumbers = await client.providers.blooio.numbers.list();
|
|
176
|
+
```
|
|
177
|
+
|
|
178
|
+
There is no separate `extensions` object.
|
|
179
|
+
|
|
180
|
+
## Adapter implementation shape
|
|
181
|
+
|
|
182
|
+
`defineProvider()` is the generic adapter-authoring helper. It preserves the
|
|
183
|
+
literal name, capability values, and complete concrete provider type.
|
|
184
|
+
|
|
185
|
+
Conceptually, provider factories are structured like this:
|
|
186
|
+
|
|
187
|
+
```ts
|
|
188
|
+
import { defineProvider } from "imessage-sdk";
|
|
189
|
+
|
|
190
|
+
function blooio(options = {}) {
|
|
191
|
+
return defineProvider({
|
|
192
|
+
name: "blooio" as const,
|
|
193
|
+
capabilities: BLOOIO_CAPABILITIES,
|
|
194
|
+
messages: {
|
|
195
|
+
async send(input) {
|
|
196
|
+
return transport.send(options, input);
|
|
197
|
+
},
|
|
198
|
+
},
|
|
199
|
+
conversations: {
|
|
200
|
+
async open(input) {
|
|
201
|
+
return transport.openConversation(options, input);
|
|
202
|
+
},
|
|
203
|
+
},
|
|
204
|
+
reactions: {
|
|
205
|
+
async add(input) {
|
|
206
|
+
await transport.addReaction(options, input);
|
|
207
|
+
},
|
|
208
|
+
async remove(input) {
|
|
209
|
+
await transport.removeReaction(options, input);
|
|
210
|
+
},
|
|
211
|
+
},
|
|
212
|
+
typing: {
|
|
213
|
+
async start(conversationId) {
|
|
214
|
+
await transport.startTyping(options, conversationId);
|
|
215
|
+
},
|
|
216
|
+
},
|
|
217
|
+
webhooks: {
|
|
218
|
+
verify(request) {
|
|
219
|
+
return transport.verifyWebhook(options, request);
|
|
220
|
+
},
|
|
221
|
+
parse(request) {
|
|
222
|
+
return transport.parseWebhook(options, request);
|
|
223
|
+
},
|
|
224
|
+
},
|
|
225
|
+
});
|
|
226
|
+
}
|
|
227
|
+
```
|
|
228
|
+
|
|
229
|
+
Applications use `blooio(options)`. They do not supply message, conversation,
|
|
230
|
+
or webhook implementations themselves.
|
|
231
|
+
|
|
232
|
+
## Custom providers
|
|
233
|
+
|
|
234
|
+
Provider names are not restricted to the built-in adapters. `defineProvider()`
|
|
235
|
+
preserves a user-defined provider's literal name, capabilities, and concrete
|
|
236
|
+
methods:
|
|
237
|
+
|
|
238
|
+
```ts
|
|
239
|
+
const custom = defineProvider({
|
|
240
|
+
name: "my-provider" as const,
|
|
241
|
+
capabilities: MY_PROVIDER_CAPABILITIES,
|
|
242
|
+
messages: {
|
|
243
|
+
send: sendMessage,
|
|
244
|
+
get: getMessage,
|
|
245
|
+
edit: editMessage,
|
|
246
|
+
},
|
|
247
|
+
conversations: {
|
|
248
|
+
open: openConversation,
|
|
249
|
+
},
|
|
250
|
+
});
|
|
251
|
+
|
|
252
|
+
const customClient = createIMessageClient({ provider: custom });
|
|
253
|
+
|
|
254
|
+
customClient.provider;
|
|
255
|
+
// ^? "my-provider"
|
|
256
|
+
|
|
257
|
+
// Required because this concrete provider defines it as required.
|
|
258
|
+
await customClient.providers["my-provider"].messages.edit(
|
|
259
|
+
{ conversationId: "conversation-id", messageId: "message-id" },
|
|
260
|
+
{ text: "Corrected" },
|
|
261
|
+
);
|
|
262
|
+
```
|
|
263
|
+
|
|
264
|
+
## One provider per client
|
|
265
|
+
|
|
266
|
+
v0.1 accepts exactly one provider. When an application has multiple providers
|
|
267
|
+
or sender lines, it creates multiple clients and selects one explicitly:
|
|
268
|
+
|
|
269
|
+
```ts
|
|
270
|
+
const sales = createIMessageClient({
|
|
271
|
+
connectionId: "sales-line",
|
|
272
|
+
provider: blooio(salesOptions),
|
|
273
|
+
});
|
|
274
|
+
|
|
275
|
+
const support = createIMessageClient({
|
|
276
|
+
connectionId: "support-line",
|
|
277
|
+
provider: photon(supportOptions),
|
|
278
|
+
});
|
|
279
|
+
```
|
|
280
|
+
|
|
281
|
+
A multi-provider client would require explicit routing, sender ownership,
|
|
282
|
+
idempotency, failure, and fallback policies. If needed later, that should be a
|
|
283
|
+
separate router layered over multiple single-provider clients.
|
|
284
|
+
|
|
285
|
+
## Conversation IDs
|
|
286
|
+
|
|
287
|
+
Provider-native conversation IDs are required for provider operations and must
|
|
288
|
+
be treated as opaque values scoped by `provider` and `connectionId`.
|
|
289
|
+
|
|
290
|
+
If a provider message unexpectedly omits its native conversation ID, the SDK
|
|
291
|
+
creates a diagnostic fallback from the provider message ID and timestamp:
|
|
292
|
+
|
|
293
|
+
```text
|
|
294
|
+
imsg-sdk-v1-<base64url-json>
|
|
295
|
+
```
|
|
296
|
+
|
|
297
|
+
Fallback IDs keep normalized inbound messages structurally valid, but they are
|
|
298
|
+
not routable provider conversation handles. Passing one to send, lookup,
|
|
299
|
+
reaction, typing, or read operations throws a `ValidationError` with code
|
|
300
|
+
`non_routable_conversation_id`.
|
|
301
|
+
|
|
302
|
+
## Capabilities and lifecycle
|
|
303
|
+
|
|
304
|
+
The public client keeps a consistent normalized method set. Unsupported
|
|
305
|
+
operations throw `UnsupportedCapabilityError`, while capabilities allow runtime
|
|
306
|
+
feature checks:
|
|
307
|
+
|
|
308
|
+
```ts
|
|
309
|
+
if (client.capabilities.messages.edit) {
|
|
310
|
+
await client.messages.edit(
|
|
311
|
+
{
|
|
312
|
+
conversationId: "provider-conversation-id",
|
|
313
|
+
messageId: "provider-message-id",
|
|
314
|
+
},
|
|
315
|
+
{ text: "Corrected" },
|
|
316
|
+
);
|
|
317
|
+
}
|
|
318
|
+
```
|
|
319
|
+
|
|
320
|
+
Concrete capability values remain literal types. For example,
|
|
321
|
+
`client.capabilities.messages.edit` is typed as `false` for Blooio.
|
|
322
|
+
|
|
323
|
+
Providers do not have an `initialize()` hook. REST adapters are ready after
|
|
324
|
+
construction, while stream providers connect lazily when subscribed.
|
|
325
|
+
|
|
326
|
+
`client.close()` is always available and idempotent. It is a no-op when the
|
|
327
|
+
provider has no cleanup and releases resources for stream or local transports.
|
|
328
|
+
|
|
329
|
+
## Blooio operations
|
|
330
|
+
|
|
331
|
+
The v0.1 Blooio adapter supports text and public URL attachments, inline
|
|
332
|
+
replies, direct conversations, message lookup and status, reactions, typing
|
|
333
|
+
start/stop, marking chats as read, and signed webhooks. Group conversations are
|
|
334
|
+
experimental at the provider level and disabled in the normalized client.
|
|
335
|
+
|
|
336
|
+
```ts
|
|
337
|
+
const locator = {
|
|
338
|
+
conversationId: sent.conversationId,
|
|
339
|
+
messageId: sent.providerMessageId,
|
|
340
|
+
};
|
|
341
|
+
|
|
342
|
+
await client.messages.get(locator);
|
|
343
|
+
await client.reactions.add({ ...locator, reaction: "like" });
|
|
344
|
+
await client.typing.start(sent.conversationId);
|
|
345
|
+
await client.typing.stop(sent.conversationId);
|
|
346
|
+
await client.conversations.markRead(sent.conversationId);
|
|
347
|
+
```
|
|
348
|
+
|
|
349
|
+
Webhook handling verifies `X-Blooio-Signature` before parsing and returns an
|
|
350
|
+
array because one provider delivery can represent zero, one, or multiple
|
|
351
|
+
normalized events:
|
|
352
|
+
|
|
353
|
+
```ts
|
|
354
|
+
const events = await client.webhooks.handle(request);
|
|
355
|
+
```
|
|
356
|
+
|
|
357
|
+
### Live integration test
|
|
358
|
+
|
|
359
|
+
The live test sends real messages and is disabled during normal test runs.
|
|
360
|
+
Set these environment variables locally:
|
|
361
|
+
|
|
362
|
+
```bash
|
|
363
|
+
export BLOOIO_API_KEY="..."
|
|
364
|
+
export BLOOIO_TEST_RECIPIENT="+15551234567"
|
|
365
|
+
export BLOOIO_FROM_NUMBER="+15557654321" # optional
|
|
366
|
+
export BLOOIO_TEST_IMAGE_URL="https://..."
|
|
367
|
+
export BLOOIO_TEST_VIDEO_URL="https://..."
|
|
368
|
+
export BLOOIO_TEST_FILE_URL="https://..."
|
|
369
|
+
|
|
370
|
+
pnpm --filter imessage-sdk test:integration:blooio
|
|
371
|
+
```
|
|
372
|
+
|
|
373
|
+
It sends three messages and exercises lookup/status, reactions, typing, and
|
|
374
|
+
mark-read. Webhook verification and parsing are covered deterministically by
|
|
375
|
+
the mocked test suite; a real inbound webhook requires a public test endpoint.
|
|
376
|
+
|
|
377
|
+
## Photon Cloud operations
|
|
378
|
+
|
|
379
|
+
Photon authenticates with Spectrum Cloud lazily. A dedicated phone is optional
|
|
380
|
+
when the project owns exactly one line and required when it owns multiple:
|
|
381
|
+
|
|
382
|
+
```ts
|
|
383
|
+
import { createIMessageClient } from "imessage-sdk";
|
|
384
|
+
import { photon } from "imessage-sdk/providers/photon";
|
|
385
|
+
|
|
386
|
+
const client = createIMessageClient({
|
|
387
|
+
connectionId: "photon-main",
|
|
388
|
+
provider: photon(),
|
|
389
|
+
});
|
|
390
|
+
|
|
391
|
+
const line = await client.providers.photon.connection.getLine();
|
|
392
|
+
```
|
|
393
|
+
|
|
394
|
+
`photon()` reads `PHOTON_PROJECT_ID`, `PHOTON_PROJECT_SECRET`,
|
|
395
|
+
`PHOTON_PHONE_NUMBER`, and `PHOTON_WEBHOOK_SECRET`. Explicit options override
|
|
396
|
+
the environment.
|
|
397
|
+
|
|
398
|
+
The provider renews temporary line credentials internally and supports direct
|
|
399
|
+
chats, all attachment source types, replies, lookup, reactions, typing,
|
|
400
|
+
mark-read, and signed Spectrum webhooks. Normalized editing, deletion, group
|
|
401
|
+
conversations, and event streaming are conservatively disabled in v0.1. Their
|
|
402
|
+
capabilities are `false`, and normalized calls throw
|
|
403
|
+
`UnsupportedCapabilityError`.
|
|
404
|
+
|
|
405
|
+
Photon streaming remains available as an experimental provider-level API.
|
|
406
|
+
Cursors are durable numeric event sequences represented as strings:
|
|
407
|
+
|
|
408
|
+
```ts
|
|
409
|
+
for await (const event of client.providers.photon.events.subscribe({
|
|
410
|
+
cursor: "123",
|
|
411
|
+
})) {
|
|
412
|
+
console.log(event.providerEventId, event.type);
|
|
413
|
+
}
|
|
414
|
+
|
|
415
|
+
await client.close();
|
|
416
|
+
```
|
|
417
|
+
|
|
418
|
+
Group-conversation implementations also remain experimental at the provider
|
|
419
|
+
level. Normalized `client.conversations.open(...)` accepts one participant in
|
|
420
|
+
v0.1 and rejects multiple participants with `UnsupportedCapabilityError`.
|
|
421
|
+
|
|
422
|
+
### Photon live integration test
|
|
423
|
+
|
|
424
|
+
```bash
|
|
425
|
+
export PHOTON_PROJECT_ID="..."
|
|
426
|
+
export PHOTON_PROJECT_SECRET="..."
|
|
427
|
+
export PHOTON_PHONE_NUMBER="+15557654321" # optional with one line
|
|
428
|
+
export PHOTON_TEST_RECIPIENT="+15551234567"
|
|
429
|
+
export PHOTON_TEST_IMAGE_URL="https://..."
|
|
430
|
+
export PHOTON_TEST_VIDEO_URL="https://..."
|
|
431
|
+
export PHOTON_TEST_FILE_URL="https://..."
|
|
432
|
+
|
|
433
|
+
pnpm --filter imessage-sdk test:integration:photon
|
|
434
|
+
```
|
|
435
|
+
|
|
436
|
+
On Photon Free and Pro shared lines, add the recipient under the project's
|
|
437
|
+
**Users** tab first. New contacts have a temporary reply allowance until they
|
|
438
|
+
have sent enough inbound messages, so use an opted-in recipient and avoid
|
|
439
|
+
repeated live runs against a fresh contact.
|
|
440
|
+
|
|
441
|
+
The outbound test exercises line discovery, idempotency, attachments, replies,
|
|
442
|
+
lookup, reactions, typing, mark-read, and cleanup. To test the experimental
|
|
443
|
+
persistent stream, run the command below and send an iMessage to the line
|
|
444
|
+
within 60 seconds:
|
|
445
|
+
|
|
446
|
+
```bash
|
|
447
|
+
pnpm --filter imessage-sdk test:integration:photon-stream
|
|
448
|
+
```
|
|
449
|
+
|
|
450
|
+
## v0.1 beta boundary
|
|
451
|
+
|
|
452
|
+
The initial model includes text, URL/blob/byte attachments, thread replies,
|
|
453
|
+
direct conversations, statuses, reactions, typing, webhooks, typed
|
|
454
|
+
capabilities, and typed errors. Photon streams and both providers' group
|
|
455
|
+
implementations remain experimental provider-level APIs.
|
|
456
|
+
|
|
457
|
+
It intentionally excludes FaceTime, polls, location sharing, contacts, message
|
|
458
|
+
effects, scheduling, provisioning, and automatic provider fallback.
|
|
459
|
+
|
|
460
|
+
## License
|
|
461
|
+
|
|
462
|
+
MIT
|
|
463
|
+
|
|
464
|
+
Release history is tracked in the repository
|
|
465
|
+
[changelog](https://github.com/jmisilo/imessage-sdk/blob/main/CHANGELOG.md).
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
import { A as AnyIMessageProvider, S as SendMessageInput, a as SentMessage, M as MessageLocator, b as Message, E as EditMessageInput, O as OpenConversationInput, C as Conversation, c as AddReactionInput, R as RemoveReactionInput, I as IMessageEvent, d as SubscribeOptions } from './provider-CCW_6OWg.js';
|
|
2
|
+
export { e as IMessageAddress, f as IMessageAddressKind, g as IMessageAttachment, h as IMessageAttachmentInput, i as IMessageAttachmentKind, j as IMessageAttachmentSource, k as IMessageCapabilities, l as IMessageDeletedEvent, m as IMessageDirection, n as IMessageEventBase, o as IMessageMessageEvent, p as IMessageProvider, q as IMessageProviderName, r as IMessageReaction, s as IMessageReactionEvent, t as IMessageService, u as IMessageStatus, v as IMessageTypingEvent, w as MessageReplyReference, N as NonEmptyReadonlyArray, P as ProviderConversation, x as ProviderConversations, y as ProviderEvent, z as ProviderEventBase, B as ProviderEvents, D as ProviderMessage, F as ProviderMessageDeletedEvent, G as ProviderMessageEvent, H as ProviderMessageEventType, J as ProviderMessages, K as ProviderReactionEvent, L as ProviderReactionEventType, Q as ProviderReactions, T as ProviderSentMessage, U as ProviderTyping, V as ProviderTypingEvent, W as ProviderTypingEventType, X as ProviderWebhooks, Y as defineProvider } from './provider-CCW_6OWg.js';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Creates a diagnostic fallback when a provider message omits its native
|
|
6
|
+
* conversation ID. Fallback IDs are stable for the same message and timestamp,
|
|
7
|
+
* but are not provider-routable conversation handles.
|
|
8
|
+
*/
|
|
9
|
+
declare function createFallbackConversationId(message: string, timestamp: Date): string;
|
|
10
|
+
declare function isFallbackConversationId(value: string): boolean;
|
|
11
|
+
|
|
12
|
+
interface IMessageSDKErrorOptions {
|
|
13
|
+
readonly provider?: string;
|
|
14
|
+
readonly connectionId?: string;
|
|
15
|
+
readonly code?: string;
|
|
16
|
+
readonly statusCode?: number;
|
|
17
|
+
readonly retryable?: boolean;
|
|
18
|
+
readonly retryAfter?: number;
|
|
19
|
+
readonly traceId?: string;
|
|
20
|
+
readonly raw?: unknown;
|
|
21
|
+
}
|
|
22
|
+
declare class IMessageSDKError extends Error {
|
|
23
|
+
readonly provider: string | undefined;
|
|
24
|
+
readonly connectionId: string | undefined;
|
|
25
|
+
readonly code: string | undefined;
|
|
26
|
+
readonly statusCode: number | undefined;
|
|
27
|
+
readonly retryable: boolean;
|
|
28
|
+
readonly retryAfter: number | undefined;
|
|
29
|
+
readonly traceId: string | undefined;
|
|
30
|
+
readonly raw: unknown;
|
|
31
|
+
constructor(message: string, options?: IMessageSDKErrorOptions);
|
|
32
|
+
}
|
|
33
|
+
declare class ValidationError extends IMessageSDKError {
|
|
34
|
+
}
|
|
35
|
+
declare class AuthenticationError extends IMessageSDKError {
|
|
36
|
+
}
|
|
37
|
+
declare class NotFoundError extends IMessageSDKError {
|
|
38
|
+
}
|
|
39
|
+
declare class ConflictError extends IMessageSDKError {
|
|
40
|
+
}
|
|
41
|
+
declare class RateLimitError extends IMessageSDKError {
|
|
42
|
+
}
|
|
43
|
+
declare class ProviderUnavailableError extends IMessageSDKError {
|
|
44
|
+
}
|
|
45
|
+
/** A send may have reached the provider, so blindly retrying could duplicate it. */
|
|
46
|
+
declare class AmbiguousDeliveryError extends IMessageSDKError {
|
|
47
|
+
}
|
|
48
|
+
declare class UnsupportedCapabilityError extends IMessageSDKError {
|
|
49
|
+
readonly capability: string;
|
|
50
|
+
constructor(capability: string, options?: Pick<IMessageSDKErrorOptions, "provider" | "connectionId">);
|
|
51
|
+
}
|
|
52
|
+
declare class WebhookVerificationError extends IMessageSDKError {
|
|
53
|
+
constructor(options?: Pick<IMessageSDKErrorOptions, "provider" | "connectionId">);
|
|
54
|
+
}
|
|
55
|
+
declare class ClientClosedError extends IMessageSDKError {
|
|
56
|
+
constructor(options?: Pick<IMessageSDKErrorOptions, "provider" | "connectionId">);
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
type ProviderNameOf<TProvider extends AnyIMessageProvider> = TProvider["name"];
|
|
60
|
+
declare const DEFAULT_CONNECTION_ID: "default";
|
|
61
|
+
type ClientProvider<TProvider extends AnyIMessageProvider> = TProvider;
|
|
62
|
+
type ClientProviders<TProvider extends AnyIMessageProvider> = {
|
|
63
|
+
readonly [TName in TProvider["name"]]: ClientProvider<Extract<TProvider, {
|
|
64
|
+
readonly name: TName;
|
|
65
|
+
}>>;
|
|
66
|
+
};
|
|
67
|
+
interface IMessageClient<TProvider extends AnyIMessageProvider = AnyIMessageProvider, TConnectionId extends string = string> {
|
|
68
|
+
readonly provider: ProviderNameOf<TProvider>;
|
|
69
|
+
readonly connectionId: TConnectionId;
|
|
70
|
+
readonly capabilities: TProvider["capabilities"];
|
|
71
|
+
readonly providers: ClientProviders<TProvider>;
|
|
72
|
+
readonly messages: {
|
|
73
|
+
send(input: SendMessageInput): Promise<SentMessage<ProviderNameOf<TProvider>, TConnectionId>>;
|
|
74
|
+
get(message: MessageLocator): Promise<Message<ProviderNameOf<TProvider>, TConnectionId> | null>;
|
|
75
|
+
edit(message: MessageLocator, input: EditMessageInput): Promise<Message<ProviderNameOf<TProvider>, TConnectionId>>;
|
|
76
|
+
delete(message: MessageLocator): Promise<void>;
|
|
77
|
+
};
|
|
78
|
+
readonly conversations: {
|
|
79
|
+
open(input: OpenConversationInput): Promise<Conversation<ProviderNameOf<TProvider>, TConnectionId>>;
|
|
80
|
+
get(conversationId: string): Promise<Conversation<ProviderNameOf<TProvider>, TConnectionId> | null>;
|
|
81
|
+
markRead(conversationId: string): Promise<void>;
|
|
82
|
+
};
|
|
83
|
+
readonly reactions: {
|
|
84
|
+
add(input: AddReactionInput): Promise<void>;
|
|
85
|
+
remove(input: RemoveReactionInput): Promise<void>;
|
|
86
|
+
};
|
|
87
|
+
readonly typing: {
|
|
88
|
+
start(conversationId: string): Promise<void>;
|
|
89
|
+
stop(conversationId: string): Promise<void>;
|
|
90
|
+
};
|
|
91
|
+
readonly webhooks: {
|
|
92
|
+
handle(request: Request): Promise<readonly IMessageEvent<ProviderNameOf<TProvider>, TConnectionId>[]>;
|
|
93
|
+
};
|
|
94
|
+
readonly events: {
|
|
95
|
+
subscribe(options?: SubscribeOptions): AsyncIterable<IMessageEvent<ProviderNameOf<TProvider>, TConnectionId>>;
|
|
96
|
+
};
|
|
97
|
+
close(): Promise<void>;
|
|
98
|
+
}
|
|
99
|
+
interface CreateIMessageClientOptions<TProvider extends AnyIMessageProvider, TConnectionId extends string = typeof DEFAULT_CONNECTION_ID> {
|
|
100
|
+
readonly connectionId?: TConnectionId;
|
|
101
|
+
readonly provider: TProvider;
|
|
102
|
+
}
|
|
103
|
+
declare function createIMessageClient<const TProvider extends AnyIMessageProvider, const TConnectionId extends string = typeof DEFAULT_CONNECTION_ID>(options: CreateIMessageClientOptions<TProvider, TConnectionId>): IMessageClient<TProvider, TConnectionId>;
|
|
104
|
+
|
|
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 };
|