@spectrum-ts/imessage 9.0.0 → 9.3.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/dist/index.d.ts +53 -1
- package/dist/index.js +66 -14
- package/package.json +2 -2
package/dist/index.d.ts
CHANGED
|
@@ -141,6 +141,7 @@ declare const customizedMiniAppSchema: z.ZodObject<{
|
|
|
141
141
|
imageSubtitle: z.ZodOptional<z.ZodString>;
|
|
142
142
|
summary: z.ZodOptional<z.ZodString>;
|
|
143
143
|
}, z.core.$strip>;
|
|
144
|
+
live: z.ZodOptional<z.ZodBoolean>;
|
|
144
145
|
teamId: z.ZodString;
|
|
145
146
|
url: z.ZodURL;
|
|
146
147
|
}, z.core.$strip>;
|
|
@@ -155,7 +156,8 @@ type CustomizedMiniAppInput = Omit<CustomizedMiniApp, "type" | "__platform">;
|
|
|
155
156
|
* the recipient taps the card; the server constructs the matching
|
|
156
157
|
* `MSMessageExtensionBalloonPlugin` plugin id from these values. `appStoreId`
|
|
157
158
|
* is optional and only points recipients without the extension at its App
|
|
158
|
-
* Store entry.
|
|
159
|
+
* Store entry. `live` is optional; when omitted, the remote server keeps the
|
|
160
|
+
* static layout preview visible.
|
|
159
161
|
*
|
|
160
162
|
* `space.send(customizedMiniApp(...))` is the canonical form.
|
|
161
163
|
*
|
|
@@ -193,8 +195,25 @@ declare const spaceSchema: z.ZodObject<{
|
|
|
193
195
|
}>;
|
|
194
196
|
phone: z.ZodString;
|
|
195
197
|
}, z.core.$strip>;
|
|
198
|
+
declare const miniAppCardSessionSchema: z.ZodObject<{
|
|
199
|
+
chatGuid: z.ZodString;
|
|
200
|
+
messageGuid: z.ZodString;
|
|
201
|
+
sessionId: z.ZodString;
|
|
202
|
+
targetMessageGuid: z.ZodString;
|
|
203
|
+
}, z.core.$strip>;
|
|
204
|
+
/**
|
|
205
|
+
* iMessage-specific per-message metadata surfaced on `IMessageMessage`.
|
|
206
|
+
* - `partIndex`: ordered part index within a multi-part message. Text and
|
|
207
|
+
* attachment parts both consume an index (0 for bare or single-part
|
|
208
|
+
* messages; 0..N-1 for a group's sub-items).
|
|
209
|
+
* - `parentId`: guid of the parent message for a group sub-item. Undefined
|
|
210
|
+
* when the message itself is the parent.
|
|
211
|
+
* - `miniAppCardSession`: stable handle returned by mini-app card sends and
|
|
212
|
+
* updates. It is required to update the card in place later.
|
|
213
|
+
*/
|
|
196
214
|
type IMessageMessage = SchemaMessage<typeof userSchema, typeof spaceSchema> & {
|
|
197
215
|
direction?: "inbound" | "outbound";
|
|
216
|
+
miniAppCardSession?: z.infer<typeof miniAppCardSessionSchema>;
|
|
198
217
|
partIndex?: number;
|
|
199
218
|
parentId?: string;
|
|
200
219
|
};
|
|
@@ -238,6 +257,12 @@ declare const imessage: import("@spectrum-ts/core").Platform<import("@spectrum-t
|
|
|
238
257
|
type: "dm" | "group";
|
|
239
258
|
phone: string;
|
|
240
259
|
}, import("zod").ZodObject<{
|
|
260
|
+
miniAppCardSession: import("zod").ZodOptional<import("zod").ZodObject<{
|
|
261
|
+
chatGuid: import("zod").ZodString;
|
|
262
|
+
messageGuid: import("zod").ZodString;
|
|
263
|
+
sessionId: import("zod").ZodString;
|
|
264
|
+
targetMessageGuid: import("zod").ZodString;
|
|
265
|
+
}, import("zod/v4/core").$strip>>;
|
|
241
266
|
partIndex: import("zod").ZodOptional<import("zod").ZodNumber>;
|
|
242
267
|
parentId: import("zod").ZodOptional<import("zod").ZodString>;
|
|
243
268
|
}, import("zod/v4/core").$strip>, IMessageMessage, undefined, {
|
|
@@ -327,6 +352,33 @@ declare const imessage: import("@spectrum-ts/core").Platform<import("@spectrum-t
|
|
|
327
352
|
id: string;
|
|
328
353
|
__platform: string;
|
|
329
354
|
}) => Promise<import("@spectrum-ts/core").AvatarData | undefined>;
|
|
355
|
+
getDisplayName: ({
|
|
356
|
+
client
|
|
357
|
+
}: {
|
|
358
|
+
client: IMessageClient;
|
|
359
|
+
config: {
|
|
360
|
+
local: true;
|
|
361
|
+
} | {
|
|
362
|
+
local: false;
|
|
363
|
+
clients?: {
|
|
364
|
+
address: string;
|
|
365
|
+
token: string;
|
|
366
|
+
phone: string;
|
|
367
|
+
} | {
|
|
368
|
+
address: string;
|
|
369
|
+
token: string;
|
|
370
|
+
phone: string;
|
|
371
|
+
}[] | undefined;
|
|
372
|
+
};
|
|
373
|
+
store: import("@spectrum-ts/core").Store;
|
|
374
|
+
}, space: {
|
|
375
|
+
id: string;
|
|
376
|
+
type: "dm" | "group";
|
|
377
|
+
phone: string;
|
|
378
|
+
} & {
|
|
379
|
+
id: string;
|
|
380
|
+
__platform: string;
|
|
381
|
+
}) => Promise<string | undefined>;
|
|
330
382
|
getAttachment: ({
|
|
331
383
|
client
|
|
332
384
|
}: {
|
package/dist/index.js
CHANGED
|
@@ -124,6 +124,7 @@ const customizedMiniAppSchema = z.object({
|
|
|
124
124
|
appStoreId: z.number().int().positive().optional(),
|
|
125
125
|
extensionBundleId: z.string().nonempty(),
|
|
126
126
|
layout: layoutSchema,
|
|
127
|
+
live: z.boolean().optional(),
|
|
127
128
|
teamId: z.string(),
|
|
128
129
|
url: z.url()
|
|
129
130
|
});
|
|
@@ -141,7 +142,8 @@ const asCustomizedMiniApp = (input) => customizedMiniAppSchema.parse({
|
|
|
141
142
|
* the recipient taps the card; the server constructs the matching
|
|
142
143
|
* `MSMessageExtensionBalloonPlugin` plugin id from these values. `appStoreId`
|
|
143
144
|
* is optional and only points recipients without the extension at its App
|
|
144
|
-
* Store entry.
|
|
145
|
+
* Store entry. `live` is optional; when omitted, the remote server keeps the
|
|
146
|
+
* static layout preview visible.
|
|
145
147
|
*
|
|
146
148
|
* `space.send(customizedMiniApp(...))` is the canonical form.
|
|
147
149
|
*
|
|
@@ -202,6 +204,12 @@ const spaceSchema = z.object({
|
|
|
202
204
|
phone: z.string()
|
|
203
205
|
});
|
|
204
206
|
const spaceParamsSchema = z.object({ phone: z.string().optional() });
|
|
207
|
+
const miniAppCardSessionSchema = z.object({
|
|
208
|
+
chatGuid: z.string(),
|
|
209
|
+
messageGuid: z.string(),
|
|
210
|
+
sessionId: z.string(),
|
|
211
|
+
targetMessageGuid: z.string()
|
|
212
|
+
});
|
|
205
213
|
/**
|
|
206
214
|
* iMessage-specific per-message metadata surfaced on `IMessageMessage`.
|
|
207
215
|
* - `partIndex`: ordered part index within a multi-part message. Text and
|
|
@@ -209,8 +217,11 @@ const spaceParamsSchema = z.object({ phone: z.string().optional() });
|
|
|
209
217
|
* messages; 0..N-1 for a group's sub-items).
|
|
210
218
|
* - `parentId`: guid of the parent message for a group sub-item. Undefined
|
|
211
219
|
* when the message itself is the parent.
|
|
220
|
+
* - `miniAppCardSession`: stable handle returned by mini-app card sends and
|
|
221
|
+
* updates. It is required to update the card in place later.
|
|
212
222
|
*/
|
|
213
223
|
const messageSchema = z.object({
|
|
224
|
+
miniAppCardSession: miniAppCardSessionSchema.optional(),
|
|
214
225
|
partIndex: z.number().int().nonnegative().optional(),
|
|
215
226
|
parentId: z.string().optional()
|
|
216
227
|
});
|
|
@@ -789,6 +800,14 @@ const shareContactCard$1 = async (remote, spaceId) => {
|
|
|
789
800
|
};
|
|
790
801
|
//#endregion
|
|
791
802
|
//#region src/remote/customized-mini-app.ts
|
|
803
|
+
const toProviderRecord = (result, content, spaceId) => ({
|
|
804
|
+
id: result.guid,
|
|
805
|
+
content,
|
|
806
|
+
direction: "outbound",
|
|
807
|
+
miniAppCardSession: result.miniAppCardSession,
|
|
808
|
+
space: { id: spaceId },
|
|
809
|
+
timestamp: result.dateCreated
|
|
810
|
+
});
|
|
792
811
|
/**
|
|
793
812
|
* Send a `CustomizedMiniApp` card to a remote iMessage chat.
|
|
794
813
|
*
|
|
@@ -800,14 +819,10 @@ const shareContactCard$1 = async (remote, spaceId) => {
|
|
|
800
819
|
*/
|
|
801
820
|
const sendCustomizedMiniApp$1 = async (remote, spaceId, content) => {
|
|
802
821
|
const chat = toChatGuid(spaceId);
|
|
803
|
-
|
|
804
|
-
|
|
805
|
-
|
|
806
|
-
|
|
807
|
-
direction: "outbound",
|
|
808
|
-
space: { id: spaceId },
|
|
809
|
-
timestamp: message.dateCreated
|
|
810
|
-
};
|
|
822
|
+
return toProviderRecord(await remote.messages.sendCustomizedMiniApp(chat, content), content, spaceId);
|
|
823
|
+
};
|
|
824
|
+
const updateCustomizedMiniApp$1 = async (remote, spaceId, session, content) => {
|
|
825
|
+
return toProviderRecord(await remote.messages.updateCustomizedMiniApp(session, content), content, spaceId);
|
|
811
826
|
};
|
|
812
827
|
//#endregion
|
|
813
828
|
//#region src/remote/attachments.ts
|
|
@@ -1248,6 +1263,15 @@ const markRead$1 = async (remote, spaceId) => {
|
|
|
1248
1263
|
const setDisplayName$1 = async (remote, spaceId, content) => {
|
|
1249
1264
|
await remote.groups.setDisplayName(toChatGuid(spaceId), content.displayName);
|
|
1250
1265
|
};
|
|
1266
|
+
/**
|
|
1267
|
+
* Read a remote iMessage group chat's title. The SDK returns an empty
|
|
1268
|
+
* `Chat.displayName` for an unnamed group; normalized to `undefined`. The
|
|
1269
|
+
* group-only guard lives at the action layer (see `remoteGroupClient`).
|
|
1270
|
+
*/
|
|
1271
|
+
const getDisplayName$1 = async (remote, spaceId) => {
|
|
1272
|
+
const { displayName } = await remote.chats.get(toChatGuid(spaceId));
|
|
1273
|
+
return displayName || void 0;
|
|
1274
|
+
};
|
|
1251
1275
|
//#endregion
|
|
1252
1276
|
//#region src/remote/markdown.ts
|
|
1253
1277
|
const markdownLexer = new Marked();
|
|
@@ -2154,7 +2178,9 @@ const stopTyping$1 = async (remote, spaceId) => {
|
|
|
2154
2178
|
const messages = (clients, projectConfig) => messages$1(clients, projectConfig);
|
|
2155
2179
|
const setBackground = async (remote, spaceId, content) => setBackground$1(remote, spaceId, content);
|
|
2156
2180
|
const sendCustomizedMiniApp = async (remote, spaceId, content) => sendCustomizedMiniApp$1(remote, spaceId, content);
|
|
2181
|
+
const updateCustomizedMiniApp = async (remote, spaceId, session, content) => updateCustomizedMiniApp$1(remote, spaceId, session, content);
|
|
2157
2182
|
const setDisplayName = async (remote, spaceId, content) => setDisplayName$1(remote, spaceId, content);
|
|
2183
|
+
const getDisplayName = async (remote, spaceId) => getDisplayName$1(remote, spaceId);
|
|
2158
2184
|
const addParticipants = async (remote, spaceId, content) => addParticipants$1(remote, spaceId, content);
|
|
2159
2185
|
const removeParticipants = async (remote, spaceId, content) => removeParticipants$1(remote, spaceId, content);
|
|
2160
2186
|
const leaveGroup = async (remote, spaceId) => leaveGroup$1(remote, spaceId);
|
|
@@ -2198,13 +2224,14 @@ const SPECTRUM_MINI_APP = {
|
|
|
2198
2224
|
};
|
|
2199
2225
|
/**
|
|
2200
2226
|
* Build the iMessage mini-app card for an `app` content: Spectrum's fixed
|
|
2201
|
-
* identity plus the per-message `url
|
|
2202
|
-
* URL's link metadata.
|
|
2227
|
+
* identity plus the per-message `url`, optional live-rendering hint, and the
|
|
2228
|
+
* `layout` already derived from the URL's link metadata.
|
|
2203
2229
|
*/
|
|
2204
|
-
const toSpectrumMiniApp = (url, layout) => asCustomizedMiniApp({
|
|
2230
|
+
const toSpectrumMiniApp = (url, layout, live) => asCustomizedMiniApp({
|
|
2205
2231
|
...SPECTRUM_MINI_APP,
|
|
2206
2232
|
url,
|
|
2207
|
-
layout
|
|
2233
|
+
layout,
|
|
2234
|
+
...live === void 0 ? {} : { live }
|
|
2208
2235
|
});
|
|
2209
2236
|
//#endregion
|
|
2210
2237
|
//#region src/remote/client.ts
|
|
@@ -2249,6 +2276,25 @@ const cacheRemoteOutbound = (remote, space, record) => {
|
|
|
2249
2276
|
};
|
|
2250
2277
|
const handleEdit = async (client, space, content) => {
|
|
2251
2278
|
if (isLocal(client)) throw UnsupportedError.action("edit", "iMessage (local mode)");
|
|
2279
|
+
const miniAppCardSession = content.target.miniAppCardSession;
|
|
2280
|
+
const updateMiniAppCardSession = (record) => {
|
|
2281
|
+
const nextSession = record?.miniAppCardSession;
|
|
2282
|
+
if (nextSession) content.target.miniAppCardSession = nextSession;
|
|
2283
|
+
};
|
|
2284
|
+
if (content.content.type === "app") {
|
|
2285
|
+
if (!miniAppCardSession) throw UnsupportedError.content("edit", "iMessage", "mini app card edits require a miniAppCardSession from the original send");
|
|
2286
|
+
const url = await content.content.url();
|
|
2287
|
+
const layout = await content.content.layout();
|
|
2288
|
+
const remote = clientForPhone(client, space.phone);
|
|
2289
|
+
updateMiniAppCardSession(cacheRemoteOutbound(remote, space, await updateCustomizedMiniApp(remote, space.id, miniAppCardSession, toSpectrumMiniApp(url, layout, content.content.live))));
|
|
2290
|
+
return;
|
|
2291
|
+
}
|
|
2292
|
+
if (isCustomizedMiniApp(content.content)) {
|
|
2293
|
+
if (!miniAppCardSession) throw UnsupportedError.content("edit", "iMessage", "customized mini app card edits require a miniAppCardSession from the original send");
|
|
2294
|
+
const remote = clientForPhone(client, space.phone);
|
|
2295
|
+
updateMiniAppCardSession(cacheRemoteOutbound(remote, space, await updateCustomizedMiniApp(remote, space.id, miniAppCardSession, content.content)));
|
|
2296
|
+
return;
|
|
2297
|
+
}
|
|
2252
2298
|
if (content.content.type !== "text") throw UnsupportedError.content("edit", "iMessage", `only text content can be edited (got "${content.content.type}")`);
|
|
2253
2299
|
await editMessage(clientForPhone(client, space.phone), space.id, content.target.id, content.content);
|
|
2254
2300
|
};
|
|
@@ -2288,7 +2334,7 @@ const handleApp = async (client, space, content) => {
|
|
|
2288
2334
|
if (isLocal(client)) return await send$2(client, space.id, await text(url).build());
|
|
2289
2335
|
const layout = await content.layout();
|
|
2290
2336
|
const remote = clientForPhone(client, space.phone);
|
|
2291
|
-
return cacheRemoteOutbound(remote, space, await sendCustomizedMiniApp(remote, space.id, toSpectrumMiniApp(url, layout)));
|
|
2337
|
+
return cacheRemoteOutbound(remote, space, await sendCustomizedMiniApp(remote, space.id, toSpectrumMiniApp(url, layout, content.live)));
|
|
2292
2338
|
};
|
|
2293
2339
|
const handleRead = async (client, space) => {
|
|
2294
2340
|
if (isLocal(client)) throw UnsupportedError.action("read", "iMessage (local mode)", "marking chats as read requires remote iMessage");
|
|
@@ -2530,6 +2576,12 @@ const imessage = definePlatform("iMessage", {
|
|
|
2530
2576
|
local: "fetching group avatars requires remote iMessage"
|
|
2531
2577
|
}), space.id);
|
|
2532
2578
|
},
|
|
2579
|
+
getDisplayName: async ({ client }, space) => {
|
|
2580
|
+
return await getDisplayName(remoteGroupClient(client, space, "getDisplayName", {
|
|
2581
|
+
dm: "only group chats have display names (this space is a DM)",
|
|
2582
|
+
local: "reading chat display names requires remote iMessage"
|
|
2583
|
+
}), space.id);
|
|
2584
|
+
},
|
|
2533
2585
|
getAttachment: async ({ client }, guid, phone) => {
|
|
2534
2586
|
if (isLocal(client)) throw UnsupportedError.action("getAttachment", "iMessage (local mode)", "fetching attachments by GUID requires remote iMessage");
|
|
2535
2587
|
if (client.length === 0) throw new Error("No iMessage clients configured");
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@spectrum-ts/imessage",
|
|
3
|
-
"version": "9.
|
|
3
|
+
"version": "9.3.0",
|
|
4
4
|
"description": "iMessage provider for spectrum-ts — local and remote (advanced) modes.",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
@@ -31,7 +31,7 @@
|
|
|
31
31
|
"label": "iMessage"
|
|
32
32
|
},
|
|
33
33
|
"dependencies": {
|
|
34
|
-
"@photon-ai/advanced-imessage": "^0.
|
|
34
|
+
"@photon-ai/advanced-imessage": "^1.0.0",
|
|
35
35
|
"@photon-ai/imessage-kit": "^3.0.0",
|
|
36
36
|
"@photon-ai/otel": "^3.1.0",
|
|
37
37
|
"lru-cache": "^11.0.0",
|