@plosson/agentio 0.5.15 → 0.6.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/package.json +1 -1
- package/src/auth/oauth.ts +1 -0
- package/src/services/gchat/client.ts +81 -21
- package/src/types/gchat.ts +1 -0
- package/src/utils/output.ts +8 -2
package/package.json
CHANGED
package/src/auth/oauth.ts
CHANGED
|
@@ -15,6 +15,7 @@ const GCHAT_SCOPES = [
|
|
|
15
15
|
'https://www.googleapis.com/auth/chat.messages.readonly', // read messages (get operations)
|
|
16
16
|
'https://www.googleapis.com/auth/chat.spaces.readonly', // read space info and list
|
|
17
17
|
'https://www.googleapis.com/auth/chat.memberships.readonly', // read space members
|
|
18
|
+
'https://www.googleapis.com/auth/directory.readonly', // resolve user IDs to names/emails via People API
|
|
18
19
|
'https://www.googleapis.com/auth/userinfo.email', // get user email for profile naming
|
|
19
20
|
];
|
|
20
21
|
|
|
@@ -15,8 +15,14 @@ import type {
|
|
|
15
15
|
GChatSpace,
|
|
16
16
|
} from '../../types/gchat';
|
|
17
17
|
|
|
18
|
+
interface ResolvedUser {
|
|
19
|
+
displayName: string;
|
|
20
|
+
email?: string;
|
|
21
|
+
}
|
|
22
|
+
|
|
18
23
|
export class GChatClient implements ServiceClient {
|
|
19
24
|
private credentials: GChatCredentials;
|
|
25
|
+
private userCache = new Map<string, ResolvedUser>();
|
|
20
26
|
|
|
21
27
|
constructor(credentials: GChatCredentials) {
|
|
22
28
|
this.credentials = credentials;
|
|
@@ -223,6 +229,11 @@ export class GChatClient implements ServiceClient {
|
|
|
223
229
|
});
|
|
224
230
|
|
|
225
231
|
const messages = response.data.messages || [];
|
|
232
|
+
|
|
233
|
+
// Resolve unique sender IDs to display names via People API
|
|
234
|
+
const senderIds = [...new Set(messages.map(m => m.sender?.name).filter(Boolean))] as string[];
|
|
235
|
+
await this.resolveUsers(senderIds, auth);
|
|
236
|
+
|
|
226
237
|
return messages.map((msg: chat_v1.Schema$Message) => {
|
|
227
238
|
const gchatMsg: GChatMessage = {
|
|
228
239
|
name: msg.name || '',
|
|
@@ -231,12 +242,7 @@ export class GChatClient implements ServiceClient {
|
|
|
231
242
|
updateTime: (msg as Record<string, unknown>).lastUpdateTime as string || new Date().toISOString(),
|
|
232
243
|
};
|
|
233
244
|
if (msg.text) gchatMsg.text = msg.text;
|
|
234
|
-
|
|
235
|
-
gchatMsg.sender = {
|
|
236
|
-
name: msg.sender.name,
|
|
237
|
-
displayName: msg.sender.displayName || msg.sender.name,
|
|
238
|
-
};
|
|
239
|
-
}
|
|
245
|
+
gchatMsg.sender = this.enrichSender(msg);
|
|
240
246
|
if (msg.thread?.name) {
|
|
241
247
|
gchatMsg.thread = {
|
|
242
248
|
name: msg.thread.name,
|
|
@@ -270,6 +276,12 @@ export class GChatClient implements ServiceClient {
|
|
|
270
276
|
}
|
|
271
277
|
|
|
272
278
|
const msg = response.data as chat_v1.Schema$Message;
|
|
279
|
+
|
|
280
|
+
// Resolve sender
|
|
281
|
+
if (msg.sender?.name) {
|
|
282
|
+
await this.resolveUsers([msg.sender.name], auth);
|
|
283
|
+
}
|
|
284
|
+
|
|
273
285
|
const gchatMsg: GChatMessage = {
|
|
274
286
|
name: msg.name || '',
|
|
275
287
|
createTime: msg.createTime || new Date().toISOString(),
|
|
@@ -277,12 +289,7 @@ export class GChatClient implements ServiceClient {
|
|
|
277
289
|
updateTime: (msg as Record<string, unknown>).lastUpdateTime as string || new Date().toISOString(),
|
|
278
290
|
};
|
|
279
291
|
if (msg.text) gchatMsg.text = msg.text;
|
|
280
|
-
|
|
281
|
-
gchatMsg.sender = {
|
|
282
|
-
name: msg.sender.name,
|
|
283
|
-
displayName: msg.sender.displayName || msg.sender.name,
|
|
284
|
-
};
|
|
285
|
-
}
|
|
292
|
+
gchatMsg.sender = this.enrichSender(msg);
|
|
286
293
|
if (msg.thread?.name) {
|
|
287
294
|
gchatMsg.thread = {
|
|
288
295
|
name: msg.thread.name,
|
|
@@ -306,15 +313,29 @@ export class GChatClient implements ServiceClient {
|
|
|
306
313
|
const chat = gchat({ version: 'v1', auth: auth as any });
|
|
307
314
|
|
|
308
315
|
try {
|
|
309
|
-
const
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
316
|
+
const allSpaces: GChatSpace[] = [];
|
|
317
|
+
let pageToken: string | undefined;
|
|
318
|
+
|
|
319
|
+
do {
|
|
320
|
+
const response = await chat.spaces.list({
|
|
321
|
+
pageSize: 100,
|
|
322
|
+
pageToken,
|
|
323
|
+
});
|
|
324
|
+
|
|
325
|
+
const spaces = response.data.spaces || [];
|
|
326
|
+
for (const space of spaces) {
|
|
327
|
+
allSpaces.push({
|
|
328
|
+
name: space.name || '',
|
|
329
|
+
displayName: space.displayName || 'Unnamed',
|
|
330
|
+
type: (space.type as 'ROOM' | 'DM') || 'ROOM',
|
|
331
|
+
description: space.spaceDetails?.description || undefined,
|
|
332
|
+
});
|
|
333
|
+
}
|
|
334
|
+
|
|
335
|
+
pageToken = response.data.nextPageToken || undefined;
|
|
336
|
+
} while (pageToken);
|
|
337
|
+
|
|
338
|
+
return allSpaces;
|
|
318
339
|
} catch (err) {
|
|
319
340
|
const code = this.getErrorCode(err);
|
|
320
341
|
const message = this.getErrorMessage(err);
|
|
@@ -326,6 +347,45 @@ export class GChatClient implements ServiceClient {
|
|
|
326
347
|
}
|
|
327
348
|
}
|
|
328
349
|
|
|
350
|
+
private async resolveUsers(userIds: string[], auth: OAuth2Client): Promise<void> {
|
|
351
|
+
const unknown = userIds.filter(id => !this.userCache.has(id));
|
|
352
|
+
if (unknown.length === 0) return;
|
|
353
|
+
|
|
354
|
+
const token = await auth.getAccessToken();
|
|
355
|
+
if (!token.token) return;
|
|
356
|
+
|
|
357
|
+
// Resolve users in parallel via People API
|
|
358
|
+
await Promise.all(unknown.map(async (userId) => {
|
|
359
|
+
try {
|
|
360
|
+
// userId is like "users/123456", extract the numeric part
|
|
361
|
+
const personId = userId.replace('users/', '');
|
|
362
|
+
const res = await fetch(
|
|
363
|
+
`https://people.googleapis.com/v1/people/${personId}?personFields=names,emailAddresses`,
|
|
364
|
+
{ headers: { Authorization: `Bearer ${token.token}` } }
|
|
365
|
+
);
|
|
366
|
+
if (!res.ok) return;
|
|
367
|
+
const data = await res.json() as Record<string, any>;
|
|
368
|
+
const name = data.names?.[0]?.displayName;
|
|
369
|
+
const email = data.emailAddresses?.[0]?.value;
|
|
370
|
+
if (name) {
|
|
371
|
+
this.userCache.set(userId, { displayName: name, email });
|
|
372
|
+
}
|
|
373
|
+
} catch {
|
|
374
|
+
// Silently skip unresolvable users
|
|
375
|
+
}
|
|
376
|
+
}));
|
|
377
|
+
}
|
|
378
|
+
|
|
379
|
+
private enrichSender(msg: chat_v1.Schema$Message): GChatMessage['sender'] {
|
|
380
|
+
if (!msg.sender?.name) return undefined;
|
|
381
|
+
const cached = this.userCache.get(msg.sender.name);
|
|
382
|
+
return {
|
|
383
|
+
name: msg.sender.name,
|
|
384
|
+
displayName: cached?.displayName || msg.sender.displayName || msg.sender.name,
|
|
385
|
+
email: cached?.email,
|
|
386
|
+
};
|
|
387
|
+
}
|
|
388
|
+
|
|
329
389
|
private getErrorCode(err: unknown): ErrorCode {
|
|
330
390
|
if (err && typeof err === 'object') {
|
|
331
391
|
const error = err as Record<string, unknown>;
|
package/src/types/gchat.ts
CHANGED
package/src/utils/output.ts
CHANGED
|
@@ -132,7 +132,10 @@ export function printGChatMessageList(messages: GChatMessage[]): void {
|
|
|
132
132
|
const msg = messages[i];
|
|
133
133
|
console.log(`[${i + 1}] ${msg.name}`);
|
|
134
134
|
if (msg.sender) {
|
|
135
|
-
|
|
135
|
+
const from = msg.sender.email
|
|
136
|
+
? `${msg.sender.displayName} <${msg.sender.email}>`
|
|
137
|
+
: msg.sender.displayName || 'Unknown';
|
|
138
|
+
console.log(` From: ${from}`);
|
|
136
139
|
}
|
|
137
140
|
if (msg.text) {
|
|
138
141
|
const snippet = msg.text.length > 100 ? msg.text.substring(0, 100) + '...' : msg.text;
|
|
@@ -146,7 +149,10 @@ export function printGChatMessageList(messages: GChatMessage[]): void {
|
|
|
146
149
|
export function printGChatMessage(msg: GChatMessage): void {
|
|
147
150
|
console.log(`ID: ${msg.name}`);
|
|
148
151
|
if (msg.sender) {
|
|
149
|
-
|
|
152
|
+
const from = msg.sender.email
|
|
153
|
+
? `${msg.sender.displayName} <${msg.sender.email}>`
|
|
154
|
+
: msg.sender.displayName || 'Unknown';
|
|
155
|
+
console.log(`From: ${from}`);
|
|
150
156
|
}
|
|
151
157
|
console.log(`Date: ${msg.createTime}`);
|
|
152
158
|
if (msg.thread) {
|