agent-messenger 2.21.0 → 2.23.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/.claude-plugin/plugin.json +1 -1
- package/README.md +21 -0
- package/dist/package.json +1 -1
- package/dist/src/platforms/webex/client.d.ts +25 -0
- package/dist/src/platforms/webex/client.d.ts.map +1 -1
- package/dist/src/platforms/webex/client.js +115 -5
- package/dist/src/platforms/webex/client.js.map +1 -1
- package/dist/src/platforms/webex/commands/auth.d.ts +9 -1
- package/dist/src/platforms/webex/commands/auth.d.ts.map +1 -1
- package/dist/src/platforms/webex/commands/auth.js +141 -25
- package/dist/src/platforms/webex/commands/auth.js.map +1 -1
- package/dist/src/platforms/webex/credential-manager.d.ts.map +1 -1
- package/dist/src/platforms/webex/credential-manager.js +8 -4
- package/dist/src/platforms/webex/credential-manager.js.map +1 -1
- package/dist/src/platforms/webex/id-normalizer.d.ts +19 -0
- package/dist/src/platforms/webex/id-normalizer.d.ts.map +1 -0
- package/dist/src/platforms/webex/id-normalizer.js +60 -0
- package/dist/src/platforms/webex/id-normalizer.js.map +1 -0
- package/dist/src/platforms/webex/index.d.ts +4 -0
- package/dist/src/platforms/webex/index.d.ts.map +1 -1
- package/dist/src/platforms/webex/index.js +2 -0
- package/dist/src/platforms/webex/index.js.map +1 -1
- package/dist/src/platforms/webex/listener.d.ts +61 -0
- package/dist/src/platforms/webex/listener.d.ts.map +1 -0
- package/dist/src/platforms/webex/listener.js +222 -0
- package/dist/src/platforms/webex/listener.js.map +1 -0
- package/dist/src/platforms/webex/password-login.d.ts +18 -0
- package/dist/src/platforms/webex/password-login.d.ts.map +1 -0
- package/dist/src/platforms/webex/password-login.js +259 -0
- package/dist/src/platforms/webex/password-login.js.map +1 -0
- package/dist/src/platforms/webex/types.d.ts +2 -1
- package/dist/src/platforms/webex/types.d.ts.map +1 -1
- package/dist/src/platforms/webex/types.js +1 -1
- package/dist/src/platforms/webex/types.js.map +1 -1
- package/dist/src/platforms/webex/wdm-discovery.d.ts.map +1 -0
- package/dist/src/platforms/{webexbot → webex}/wdm-discovery.js +3 -3
- package/dist/src/platforms/webex/wdm-discovery.js.map +1 -0
- package/dist/src/platforms/webexbot/cli.d.ts.map +1 -1
- package/dist/src/platforms/webexbot/cli.js +4 -1
- package/dist/src/platforms/webexbot/cli.js.map +1 -1
- package/dist/src/platforms/webexbot/client.d.ts +24 -0
- package/dist/src/platforms/webexbot/client.d.ts.map +1 -1
- package/dist/src/platforms/webexbot/client.js +81 -5
- package/dist/src/platforms/webexbot/client.js.map +1 -1
- package/dist/src/platforms/webexbot/commands/file.d.ts +22 -0
- package/dist/src/platforms/webexbot/commands/file.d.ts.map +1 -0
- package/dist/src/platforms/webexbot/commands/file.js +64 -0
- package/dist/src/platforms/webexbot/commands/file.js.map +1 -0
- package/dist/src/platforms/webexbot/commands/index.d.ts +3 -0
- package/dist/src/platforms/webexbot/commands/index.d.ts.map +1 -1
- package/dist/src/platforms/webexbot/commands/index.js +3 -0
- package/dist/src/platforms/webexbot/commands/index.js.map +1 -1
- package/dist/src/platforms/webexbot/commands/message.d.ts +7 -0
- package/dist/src/platforms/webexbot/commands/message.d.ts.map +1 -1
- package/dist/src/platforms/webexbot/commands/message.js +52 -1
- package/dist/src/platforms/webexbot/commands/message.js.map +1 -1
- package/dist/src/platforms/webexbot/commands/snapshot.d.ts +24 -0
- package/dist/src/platforms/webexbot/commands/snapshot.d.ts.map +1 -0
- package/dist/src/platforms/webexbot/commands/snapshot.js +37 -0
- package/dist/src/platforms/webexbot/commands/snapshot.js.map +1 -0
- package/dist/src/platforms/webexbot/commands/user.d.ts +30 -0
- package/dist/src/platforms/webexbot/commands/user.d.ts.map +1 -0
- package/dist/src/platforms/webexbot/commands/user.js +66 -0
- package/dist/src/platforms/webexbot/commands/user.js.map +1 -0
- package/dist/src/platforms/webexbot/index.d.ts +2 -0
- package/dist/src/platforms/webexbot/index.d.ts.map +1 -1
- package/dist/src/platforms/webexbot/index.js +1 -0
- package/dist/src/platforms/webexbot/index.js.map +1 -1
- package/dist/src/platforms/webexbot/listener.d.ts +3 -41
- package/dist/src/platforms/webexbot/listener.d.ts.map +1 -1
- package/dist/src/platforms/webexbot/listener.js +13 -208
- package/dist/src/platforms/webexbot/listener.js.map +1 -1
- package/dist/src/platforms/webexbot/types.d.ts +1 -18
- package/dist/src/platforms/webexbot/types.d.ts.map +1 -1
- package/dist/src/platforms/webexbot/types.js.map +1 -1
- package/docs/content/docs/cli/webex.mdx +38 -12
- package/docs/content/docs/cli/webexbot.mdx +2 -0
- package/docs/content/docs/sdk/webexbot.mdx +18 -0
- package/package.json +1 -1
- package/skills/agent-channeltalk/SKILL.md +1 -1
- package/skills/agent-channeltalkbot/SKILL.md +1 -1
- package/skills/agent-discord/SKILL.md +1 -1
- package/skills/agent-discordbot/SKILL.md +1 -1
- package/skills/agent-instagram/SKILL.md +1 -1
- package/skills/agent-kakaotalk/SKILL.md +1 -1
- package/skills/agent-line/SKILL.md +1 -1
- package/skills/agent-slack/SKILL.md +1 -1
- package/skills/agent-slackbot/SKILL.md +1 -1
- package/skills/agent-teams/SKILL.md +1 -1
- package/skills/agent-telegram/SKILL.md +1 -1
- package/skills/agent-telegrambot/SKILL.md +1 -1
- package/skills/agent-webex/SKILL.md +76 -22
- package/skills/agent-webex/references/authentication.md +55 -14
- package/skills/agent-webex/references/common-patterns.md +5 -2
- package/skills/agent-webexbot/SKILL.md +60 -5
- package/skills/agent-webexbot/references/common-patterns.md +118 -0
- package/skills/agent-wechatbot/SKILL.md +1 -1
- package/skills/agent-whatsapp/SKILL.md +1 -1
- package/skills/agent-whatsappbot/SKILL.md +1 -1
- package/src/platforms/webex/cli.test.ts +31 -1
- package/src/platforms/webex/client.test.ts +67 -0
- package/src/platforms/webex/client.ts +136 -7
- package/src/platforms/webex/commands/auth.test.ts +189 -28
- package/src/platforms/webex/commands/auth.ts +194 -35
- package/src/platforms/webex/credential-manager.test.ts +40 -0
- package/src/platforms/webex/credential-manager.ts +7 -4
- package/src/platforms/webex/id-normalizer.test.ts +207 -0
- package/src/platforms/webex/id-normalizer.ts +76 -0
- package/src/platforms/webex/index.test.ts +6 -0
- package/src/platforms/webex/index.ts +4 -0
- package/src/platforms/webex/listener.test.ts +243 -0
- package/src/platforms/webex/listener.ts +285 -0
- package/src/platforms/webex/password-login.test.ts +193 -0
- package/src/platforms/webex/password-login.ts +332 -0
- package/src/platforms/webex/types.test.ts +16 -0
- package/src/platforms/webex/types.ts +2 -2
- package/src/platforms/{webexbot → webex}/wdm-discovery.ts +3 -3
- package/src/platforms/webexbot/cli.ts +6 -0
- package/src/platforms/webexbot/client.test.ts +322 -0
- package/src/platforms/webexbot/client.ts +104 -7
- package/src/platforms/webexbot/commands/file.ts +104 -0
- package/src/platforms/webexbot/commands/index.ts +3 -0
- package/src/platforms/webexbot/commands/message.ts +68 -2
- package/src/platforms/webexbot/commands/snapshot.ts +60 -0
- package/src/platforms/webexbot/commands/user.test.ts +77 -0
- package/src/platforms/webexbot/commands/user.ts +98 -0
- package/src/platforms/webexbot/index.ts +2 -0
- package/src/platforms/webexbot/listener.test.ts +37 -224
- package/src/platforms/webexbot/listener.ts +18 -250
- package/src/platforms/webexbot/types.ts +2 -23
- package/dist/src/platforms/webexbot/wdm-discovery.d.ts.map +0 -1
- package/dist/src/platforms/webexbot/wdm-discovery.js.map +0 -1
- /package/dist/src/platforms/{webexbot → webex}/wdm-discovery.d.ts +0 -0
- /package/src/platforms/{webexbot → webex}/wdm-discovery.test.ts +0 -0
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
import { Command } from 'commander';
|
|
2
|
+
import { cliOutput } from '../../../shared/utils/cli-output.js';
|
|
3
|
+
import { getClient } from './shared.js';
|
|
4
|
+
function formatPerson(person) {
|
|
5
|
+
return {
|
|
6
|
+
id: person.id,
|
|
7
|
+
emails: person.emails,
|
|
8
|
+
displayName: person.displayName,
|
|
9
|
+
nickName: person.nickName,
|
|
10
|
+
firstName: person.firstName,
|
|
11
|
+
lastName: person.lastName,
|
|
12
|
+
avatar: person.avatar,
|
|
13
|
+
orgId: person.orgId,
|
|
14
|
+
type: person.type,
|
|
15
|
+
created: person.created,
|
|
16
|
+
};
|
|
17
|
+
}
|
|
18
|
+
export async function listAction(options) {
|
|
19
|
+
try {
|
|
20
|
+
const client = await getClient(options);
|
|
21
|
+
const max = options.max ? parseInt(options.max, 10) : undefined;
|
|
22
|
+
const people = await client.listPeople({ email: options.email, displayName: options.displayName, max });
|
|
23
|
+
return {
|
|
24
|
+
users: people.map((p) => ({
|
|
25
|
+
id: p.id,
|
|
26
|
+
emails: p.emails,
|
|
27
|
+
displayName: p.displayName,
|
|
28
|
+
type: p.type,
|
|
29
|
+
})),
|
|
30
|
+
};
|
|
31
|
+
}
|
|
32
|
+
catch (error) {
|
|
33
|
+
return { error: error.message };
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
export async function infoAction(personId, options) {
|
|
37
|
+
try {
|
|
38
|
+
const client = await getClient(options);
|
|
39
|
+
const person = await client.getPerson(personId);
|
|
40
|
+
return formatPerson(person);
|
|
41
|
+
}
|
|
42
|
+
catch (error) {
|
|
43
|
+
return { error: error.message };
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
export const userCommand = new Command('user')
|
|
47
|
+
.description('User commands')
|
|
48
|
+
.addCommand(new Command('list')
|
|
49
|
+
.description('Search people by email or display name')
|
|
50
|
+
.option('--email <email>', 'Filter by exact email')
|
|
51
|
+
.option('--display-name <name>', 'Filter by display name prefix')
|
|
52
|
+
.option('--max <n>', 'Number of users to retrieve')
|
|
53
|
+
.option('--bot <id>', 'Use specific bot')
|
|
54
|
+
.option('--pretty', 'Pretty print JSON output')
|
|
55
|
+
.action(async (opts) => {
|
|
56
|
+
cliOutput(await listAction(opts), opts.pretty);
|
|
57
|
+
}))
|
|
58
|
+
.addCommand(new Command('info')
|
|
59
|
+
.description('Get details for a person')
|
|
60
|
+
.argument('<id>', 'Person ID')
|
|
61
|
+
.option('--bot <id>', 'Use specific bot')
|
|
62
|
+
.option('--pretty', 'Pretty print JSON output')
|
|
63
|
+
.action(async (personId, opts) => {
|
|
64
|
+
cliOutput(await infoAction(personId, opts), opts.pretty);
|
|
65
|
+
}));
|
|
66
|
+
//# sourceMappingURL=user.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"user.js","sourceRoot":"","sources":["../../../../../src/platforms/webexbot/commands/user.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
export { WebexBotClient } from './client.js';
|
|
2
2
|
export { WebexBotCredentialManager } from './credential-manager.js';
|
|
3
|
+
export { fromRestId, toRestId } from '../webex/id-normalizer.js';
|
|
4
|
+
export type { WebexRestIdType } from '../webex/id-normalizer.js';
|
|
3
5
|
export { WebexBotListener } from './listener.js';
|
|
4
6
|
export type { WebexBotListenerOptions } from './listener.js';
|
|
5
7
|
export type { WebexBotConfig, WebexBotCredentials, WebexBotEntry, WebexBotListenerEventMap } from './types.js';
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/platforms/webexbot/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,UAAU,CAAA;AACzC,OAAO,EAAE,yBAAyB,EAAE,MAAM,sBAAsB,CAAA;AAChE,OAAO,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAA;AAC7C,YAAY,EAAE,uBAAuB,EAAE,MAAM,YAAY,CAAA;AACzD,YAAY,EAAE,cAAc,EAAE,mBAAmB,EAAE,aAAa,EAAE,wBAAwB,EAAE,MAAM,SAAS,CAAA;AAC3G,OAAO,EAAE,oBAAoB,EAAE,yBAAyB,EAAE,mBAAmB,EAAE,aAAa,EAAE,MAAM,SAAS,CAAA;AAC7G,YAAY,EAAE,eAAe,EAAE,YAAY,EAAE,WAAW,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAA;AAC5F,OAAO,EAAE,qBAAqB,EAAE,kBAAkB,EAAE,iBAAiB,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAA"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/platforms/webexbot/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,UAAU,CAAA;AACzC,OAAO,EAAE,yBAAyB,EAAE,MAAM,sBAAsB,CAAA;AAChE,OAAO,EAAE,UAAU,EAAE,QAAQ,EAAE,MAAM,wBAAwB,CAAA;AAC7D,YAAY,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAA;AAC7D,OAAO,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAA;AAC7C,YAAY,EAAE,uBAAuB,EAAE,MAAM,YAAY,CAAA;AACzD,YAAY,EAAE,cAAc,EAAE,mBAAmB,EAAE,aAAa,EAAE,wBAAwB,EAAE,MAAM,SAAS,CAAA;AAC3G,OAAO,EAAE,oBAAoB,EAAE,yBAAyB,EAAE,mBAAmB,EAAE,aAAa,EAAE,MAAM,SAAS,CAAA;AAC7G,YAAY,EAAE,eAAe,EAAE,YAAY,EAAE,WAAW,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAA;AAC5F,OAAO,EAAE,qBAAqB,EAAE,kBAAkB,EAAE,iBAAiB,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAA"}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
export { WebexBotClient } from './client.js';
|
|
2
2
|
export { WebexBotCredentialManager } from './credential-manager.js';
|
|
3
|
+
export { fromRestId, toRestId } from '../webex/id-normalizer.js';
|
|
3
4
|
export { WebexBotListener } from './listener.js';
|
|
4
5
|
export { WebexBotConfigSchema, WebexBotCredentialsSchema, WebexBotEntrySchema, WebexBotError } from './types.js';
|
|
5
6
|
export { WebexMembershipSchema, WebexMessageSchema, WebexPersonSchema, WebexSpaceSchema } from '../webex/types.js';
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../src/platforms/webexbot/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,UAAU,CAAA;AACzC,OAAO,EAAE,yBAAyB,EAAE,MAAM,sBAAsB,CAAA;AAChE,OAAO,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAA;AAG7C,OAAO,EAAE,oBAAoB,EAAE,yBAAyB,EAAE,mBAAmB,EAAE,aAAa,EAAE,MAAM,SAAS,CAAA;AAE7G,OAAO,EAAE,qBAAqB,EAAE,kBAAkB,EAAE,iBAAiB,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAA"}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../src/platforms/webexbot/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,UAAU,CAAA;AACzC,OAAO,EAAE,yBAAyB,EAAE,MAAM,sBAAsB,CAAA;AAChE,OAAO,EAAE,UAAU,EAAE,QAAQ,EAAE,MAAM,wBAAwB,CAAA;AAE7D,OAAO,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAA;AAG7C,OAAO,EAAE,oBAAoB,EAAE,yBAAyB,EAAE,mBAAmB,EAAE,aAAa,EAAE,MAAM,SAAS,CAAA;AAE7G,OAAO,EAAE,qBAAqB,EAAE,kBAAkB,EAAE,iBAAiB,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAA"}
|
|
@@ -1,44 +1,6 @@
|
|
|
1
|
-
import
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
type EventKey = keyof WebexBotListenerEventMap;
|
|
5
|
-
type WebexBotClientLike = Pick<WebexBotClient, 'getToken'>;
|
|
6
|
-
interface WebexMessageHandlerLike {
|
|
7
|
-
connect(): Promise<void>;
|
|
8
|
-
disconnect(): Promise<void>;
|
|
9
|
-
status(): HandlerStatus;
|
|
10
|
-
get connected(): boolean;
|
|
11
|
-
on<K extends keyof WebexMessageHandlerEvents>(event: K, listener: WebexMessageHandlerEvents[K]): this;
|
|
12
|
-
off<K extends keyof WebexMessageHandlerEvents>(event: K, listener: WebexMessageHandlerEvents[K]): this;
|
|
13
|
-
once<K extends keyof WebexMessageHandlerEvents>(event: K, listener: WebexMessageHandlerEvents[K]): this;
|
|
14
|
-
}
|
|
15
|
-
export interface WebexBotListenerOptions {
|
|
16
|
-
ignoreSelfMessages?: boolean;
|
|
17
|
-
pingInterval?: number;
|
|
18
|
-
pongTimeout?: number;
|
|
19
|
-
reconnectBackoffMax?: number;
|
|
20
|
-
maxReconnectAttempts?: number;
|
|
21
|
-
_handlerFactory?: (config: WebexMessageHandlerConfig) => WebexMessageHandlerLike;
|
|
22
|
-
}
|
|
23
|
-
export declare class WebexBotListener {
|
|
24
|
-
private client;
|
|
25
|
-
private options;
|
|
26
|
-
private running;
|
|
27
|
-
private emitter;
|
|
28
|
-
private handler;
|
|
29
|
-
private generation;
|
|
30
|
-
private detachHandler;
|
|
31
|
-
private startPromise;
|
|
32
|
-
constructor(client: WebexBotClientLike, options?: WebexBotListenerOptions);
|
|
1
|
+
import { WebexListener } from '../webex/listener.js';
|
|
2
|
+
export type { WebexListenerClient as WebexBotListenerClient, WebexListenerOptions as WebexBotListenerOptions, } from '../webex/listener.js';
|
|
3
|
+
export declare class WebexBotListener extends WebexListener {
|
|
33
4
|
start(): Promise<void>;
|
|
34
|
-
stop(): Promise<void>;
|
|
35
|
-
on<K extends EventKey>(event: K, listener: (...args: WebexBotListenerEventMap[K]) => void): this;
|
|
36
|
-
off<K extends EventKey>(event: K, listener: (...args: WebexBotListenerEventMap[K]) => void): this;
|
|
37
|
-
once<K extends EventKey>(event: K, listener: (...args: WebexBotListenerEventMap[K]) => void): this;
|
|
38
|
-
private isCurrent;
|
|
39
|
-
private emitError;
|
|
40
|
-
private createHandler;
|
|
41
|
-
private wireHandler;
|
|
42
5
|
}
|
|
43
|
-
export {};
|
|
44
6
|
//# sourceMappingURL=listener.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"listener.d.ts","sourceRoot":"","sources":["../../../../src/platforms/webexbot/listener.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"listener.d.ts","sourceRoot":"","sources":["../../../../src/platforms/webexbot/listener.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAA;AAIjD,YAAY,EACV,mBAAmB,IAAI,sBAAsB,EAC7C,oBAAoB,IAAI,uBAAuB,GAChD,MAAM,mBAAmB,CAAA;AAE1B,qBAAa,gBAAiB,SAAQ,aAAa;IAG3C,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;CAU7B"}
|
|
@@ -1,214 +1,19 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
import
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
options;
|
|
8
|
-
running = false;
|
|
9
|
-
emitter = new EventEmitter();
|
|
10
|
-
handler = null;
|
|
11
|
-
generation = 0;
|
|
12
|
-
detachHandler = null;
|
|
13
|
-
startPromise = null;
|
|
14
|
-
constructor(client, options = {}) {
|
|
15
|
-
this.client = client;
|
|
16
|
-
this.options = options;
|
|
17
|
-
}
|
|
1
|
+
import { WebexListener } from '../webex/listener.js';
|
|
2
|
+
import { WebexError } from '../webex/types.js';
|
|
3
|
+
import { WebexBotError } from './types.js';
|
|
4
|
+
export class WebexBotListener extends WebexListener {
|
|
5
|
+
// Preserve the bot error contract: WDM discovery (shared with the user platform)
|
|
6
|
+
// throws WebexError, but existing bot callers catch WebexBotError.
|
|
18
7
|
async start() {
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
if (this.running)
|
|
22
|
-
return;
|
|
23
|
-
this.running = true;
|
|
24
|
-
const generation = ++this.generation;
|
|
25
|
-
let startPromise;
|
|
26
|
-
startPromise = (async () => {
|
|
27
|
-
let handler = null;
|
|
28
|
-
try {
|
|
29
|
-
handler = await this.createHandler();
|
|
30
|
-
if (!this.running || this.generation !== generation) {
|
|
31
|
-
await handler.disconnect().catch(() => undefined);
|
|
32
|
-
return;
|
|
33
|
-
}
|
|
34
|
-
this.handler = handler;
|
|
35
|
-
this.detachHandler = this.wireHandler(handler, generation);
|
|
36
|
-
await handler.connect();
|
|
37
|
-
if (!this.running || this.handler !== handler || this.generation !== generation) {
|
|
38
|
-
await handler.disconnect().catch(() => undefined);
|
|
39
|
-
return;
|
|
40
|
-
}
|
|
41
|
-
}
|
|
42
|
-
catch (error) {
|
|
43
|
-
if (this.handler === handler && this.generation === generation) {
|
|
44
|
-
this.detachHandler?.();
|
|
45
|
-
this.detachHandler = null;
|
|
46
|
-
this.handler = null;
|
|
47
|
-
}
|
|
48
|
-
if (this.generation === generation) {
|
|
49
|
-
this.running = false;
|
|
50
|
-
}
|
|
51
|
-
await handler?.disconnect().catch(() => undefined);
|
|
52
|
-
throw error;
|
|
53
|
-
}
|
|
54
|
-
finally {
|
|
55
|
-
if (this.startPromise === startPromise) {
|
|
56
|
-
this.startPromise = null;
|
|
57
|
-
}
|
|
58
|
-
}
|
|
59
|
-
})();
|
|
60
|
-
this.startPromise = startPromise;
|
|
61
|
-
return startPromise;
|
|
62
|
-
}
|
|
63
|
-
async stop() {
|
|
64
|
-
const pendingStart = this.startPromise;
|
|
65
|
-
this.startPromise = null;
|
|
66
|
-
this.running = false;
|
|
67
|
-
this.generation++;
|
|
68
|
-
const detach = this.detachHandler;
|
|
69
|
-
this.detachHandler = null;
|
|
70
|
-
detach?.();
|
|
71
|
-
const handler = this.handler;
|
|
72
|
-
this.handler = null;
|
|
73
|
-
if (handler) {
|
|
74
|
-
await handler.disconnect().catch(() => undefined);
|
|
75
|
-
}
|
|
76
|
-
if (pendingStart) {
|
|
77
|
-
await pendingStart.catch(() => undefined);
|
|
8
|
+
try {
|
|
9
|
+
await super.start();
|
|
78
10
|
}
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
off(event, listener) {
|
|
85
|
-
this.emitter.off(event, listener);
|
|
86
|
-
return this;
|
|
87
|
-
}
|
|
88
|
-
once(event, listener) {
|
|
89
|
-
this.emitter.once(event, listener);
|
|
90
|
-
return this;
|
|
91
|
-
}
|
|
92
|
-
isCurrent(handler, generation) {
|
|
93
|
-
return this.running && this.handler === handler && this.generation === generation;
|
|
94
|
-
}
|
|
95
|
-
// Node's EventEmitter throws synchronously if an 'error' event is emitted with
|
|
96
|
-
// no registered listener. Guard it so SDK consumers that only subscribe to
|
|
97
|
-
// message events are never crashed by a transient connection error.
|
|
98
|
-
emitError(error) {
|
|
99
|
-
if (this.emitter.listenerCount('error') > 0) {
|
|
100
|
-
this.emitter.emit('error', error);
|
|
101
|
-
}
|
|
102
|
-
}
|
|
103
|
-
async createHandler() {
|
|
104
|
-
const token = this.client.getToken();
|
|
105
|
-
const config = { token };
|
|
106
|
-
if (this.options.ignoreSelfMessages !== undefined)
|
|
107
|
-
config.ignoreSelfMessages = this.options.ignoreSelfMessages;
|
|
108
|
-
if (this.options.pingInterval !== undefined)
|
|
109
|
-
config.pingInterval = this.options.pingInterval;
|
|
110
|
-
if (this.options.pongTimeout !== undefined)
|
|
111
|
-
config.pongTimeout = this.options.pongTimeout;
|
|
112
|
-
if (this.options.reconnectBackoffMax !== undefined)
|
|
113
|
-
config.reconnectBackoffMax = this.options.reconnectBackoffMax;
|
|
114
|
-
if (this.options.maxReconnectAttempts !== undefined)
|
|
115
|
-
config.maxReconnectAttempts = this.options.maxReconnectAttempts;
|
|
116
|
-
if (this.options._handlerFactory) {
|
|
117
|
-
return this.options._handlerFactory(config);
|
|
11
|
+
catch (error) {
|
|
12
|
+
if (error instanceof WebexError) {
|
|
13
|
+
throw new WebexBotError(error.message, error.code);
|
|
14
|
+
}
|
|
15
|
+
throw error;
|
|
118
16
|
}
|
|
119
|
-
const wdmDevicesUrl = await discoverWdmDevicesUrl(token);
|
|
120
|
-
config.mode = 'injected';
|
|
121
|
-
config.fetch = createWdmRewriteFetch(wdmDevicesUrl);
|
|
122
|
-
config.webSocketFactory = (url) => new WebSocket(url);
|
|
123
|
-
return new WebexMessageHandler(config);
|
|
124
|
-
}
|
|
125
|
-
wireHandler(handler, generation) {
|
|
126
|
-
const onMessageCreated = (event) => {
|
|
127
|
-
if (!this.isCurrent(handler, generation))
|
|
128
|
-
return;
|
|
129
|
-
this.emitter.emit('message_created', event);
|
|
130
|
-
this.emitter.emit('webex_event', event);
|
|
131
|
-
};
|
|
132
|
-
const onMessageUpdated = (event) => {
|
|
133
|
-
if (!this.isCurrent(handler, generation))
|
|
134
|
-
return;
|
|
135
|
-
this.emitter.emit('message_updated', event);
|
|
136
|
-
this.emitter.emit('webex_event', event);
|
|
137
|
-
};
|
|
138
|
-
const onMessageDeleted = (event) => {
|
|
139
|
-
if (!this.isCurrent(handler, generation))
|
|
140
|
-
return;
|
|
141
|
-
this.emitter.emit('message_deleted', event);
|
|
142
|
-
this.emitter.emit('webex_event', event);
|
|
143
|
-
};
|
|
144
|
-
const onMembershipCreated = (event) => {
|
|
145
|
-
if (!this.isCurrent(handler, generation))
|
|
146
|
-
return;
|
|
147
|
-
this.emitter.emit('membership_created', event);
|
|
148
|
-
this.emitter.emit('webex_event', event);
|
|
149
|
-
};
|
|
150
|
-
const onAttachmentAction = (event) => {
|
|
151
|
-
if (!this.isCurrent(handler, generation))
|
|
152
|
-
return;
|
|
153
|
-
this.emitter.emit('attachment_action', event);
|
|
154
|
-
this.emitter.emit('webex_event', event);
|
|
155
|
-
};
|
|
156
|
-
const onRoomCreated = (event) => {
|
|
157
|
-
if (!this.isCurrent(handler, generation))
|
|
158
|
-
return;
|
|
159
|
-
this.emitter.emit('room_created', event);
|
|
160
|
-
this.emitter.emit('webex_event', event);
|
|
161
|
-
};
|
|
162
|
-
const onRoomUpdated = (event) => {
|
|
163
|
-
if (!this.isCurrent(handler, generation))
|
|
164
|
-
return;
|
|
165
|
-
this.emitter.emit('room_updated', event);
|
|
166
|
-
this.emitter.emit('webex_event', event);
|
|
167
|
-
};
|
|
168
|
-
const onConnected = () => {
|
|
169
|
-
if (!this.isCurrent(handler, generation))
|
|
170
|
-
return;
|
|
171
|
-
this.emitter.emit('connected', { connected: handler.connected, status: handler.status() });
|
|
172
|
-
};
|
|
173
|
-
const onReconnecting = (attempt) => {
|
|
174
|
-
if (!this.isCurrent(handler, generation))
|
|
175
|
-
return;
|
|
176
|
-
this.emitter.emit('reconnecting', attempt);
|
|
177
|
-
};
|
|
178
|
-
const onDisconnected = (reason) => {
|
|
179
|
-
if (!this.isCurrent(handler, generation))
|
|
180
|
-
return;
|
|
181
|
-
this.emitter.emit('disconnected', reason);
|
|
182
|
-
};
|
|
183
|
-
const onError = (error) => {
|
|
184
|
-
if (!this.isCurrent(handler, generation))
|
|
185
|
-
return;
|
|
186
|
-
this.emitError(error);
|
|
187
|
-
};
|
|
188
|
-
handler.on('message:created', onMessageCreated);
|
|
189
|
-
handler.on('message:updated', onMessageUpdated);
|
|
190
|
-
handler.on('message:deleted', onMessageDeleted);
|
|
191
|
-
handler.on('membership:created', onMembershipCreated);
|
|
192
|
-
handler.on('attachmentAction:created', onAttachmentAction);
|
|
193
|
-
handler.on('room:created', onRoomCreated);
|
|
194
|
-
handler.on('room:updated', onRoomUpdated);
|
|
195
|
-
handler.on('connected', onConnected);
|
|
196
|
-
handler.on('reconnecting', onReconnecting);
|
|
197
|
-
handler.on('disconnected', onDisconnected);
|
|
198
|
-
handler.on('error', onError);
|
|
199
|
-
return () => {
|
|
200
|
-
handler.off('message:created', onMessageCreated);
|
|
201
|
-
handler.off('message:updated', onMessageUpdated);
|
|
202
|
-
handler.off('message:deleted', onMessageDeleted);
|
|
203
|
-
handler.off('membership:created', onMembershipCreated);
|
|
204
|
-
handler.off('attachmentAction:created', onAttachmentAction);
|
|
205
|
-
handler.off('room:created', onRoomCreated);
|
|
206
|
-
handler.off('room:updated', onRoomUpdated);
|
|
207
|
-
handler.off('connected', onConnected);
|
|
208
|
-
handler.off('reconnecting', onReconnecting);
|
|
209
|
-
handler.off('disconnected', onDisconnected);
|
|
210
|
-
handler.off('error', onError);
|
|
211
|
-
};
|
|
212
17
|
}
|
|
213
18
|
}
|
|
214
19
|
//# sourceMappingURL=listener.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"listener.js","sourceRoot":"","sources":["../../../../src/platforms/webexbot/listener.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"listener.js","sourceRoot":"","sources":["../../../../src/platforms/webexbot/listener.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAA;AACjD,OAAO,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAA;AAC3C,OAAO,EAAE,aAAa,EAAE,MAAM,SAAS,CAAA;AAOvC,MAAM,OAAO,gBAAiB,SAAQ,aAAa;IACjD,iFAAiF;IACjF,mEAAmE;IACnE,KAAK,CAAC,KAAK;QACT,IAAI,CAAC;YACH,MAAM,KAAK,CAAC,KAAK,EAAE,CAAA;QACrB,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,IAAI,KAAK,YAAY,UAAU,EAAE,CAAC;gBAChC,MAAM,IAAI,aAAa,CAAC,KAAK,CAAC,OAAO,EAAE,KAAK,CAAC,IAAI,CAAC,CAAA;YACpD,CAAC;YACD,MAAM,KAAK,CAAA;QACb,CAAC;IACH,CAAC;CACF"}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import type { AttachmentAction, DecryptedMessage, DeletedMessage, HandlerStatus, MembershipActivity, RoomActivity } from 'webex-message-handler';
|
|
2
1
|
import { z } from 'zod';
|
|
2
|
+
export type { WebexListenerEventMap as WebexBotListenerEventMap } from '../webex/listener.js';
|
|
3
3
|
export interface WebexBotEntry {
|
|
4
4
|
bot_id: string;
|
|
5
5
|
bot_name: string;
|
|
@@ -40,21 +40,4 @@ export declare const WebexBotCredentialsSchema: z.ZodObject<{
|
|
|
40
40
|
bot_id: z.ZodString;
|
|
41
41
|
bot_name: z.ZodString;
|
|
42
42
|
}, z.core.$strip>;
|
|
43
|
-
export interface WebexBotListenerEventMap {
|
|
44
|
-
message_created: [event: DecryptedMessage];
|
|
45
|
-
message_updated: [event: DecryptedMessage];
|
|
46
|
-
message_deleted: [event: DeletedMessage];
|
|
47
|
-
membership_created: [event: MembershipActivity];
|
|
48
|
-
attachment_action: [event: AttachmentAction];
|
|
49
|
-
room_created: [event: RoomActivity];
|
|
50
|
-
room_updated: [event: RoomActivity];
|
|
51
|
-
webex_event: [event: DecryptedMessage | DeletedMessage | MembershipActivity | AttachmentAction | RoomActivity];
|
|
52
|
-
connected: [info: {
|
|
53
|
-
connected: boolean;
|
|
54
|
-
status: HandlerStatus;
|
|
55
|
-
}];
|
|
56
|
-
reconnecting: [attempt: number];
|
|
57
|
-
disconnected: [reason: string];
|
|
58
|
-
error: [error: Error];
|
|
59
|
-
}
|
|
60
43
|
//# sourceMappingURL=types.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../../src/platforms/webexbot/types.ts"],"names":[],"mappings":"AAAA,OAAO,
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../../src/platforms/webexbot/types.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAA;AAEvB,YAAY,EAAE,qBAAqB,IAAI,wBAAwB,EAAE,MAAM,mBAAmB,CAAA;AAE1F,MAAM,WAAW,aAAa;IAC5B,MAAM,EAAE,MAAM,CAAA;IACd,QAAQ,EAAE,MAAM,CAAA;IAChB,KAAK,EAAE,MAAM,CAAA;CACd;AAED,MAAM,WAAW,cAAc;IAC7B,OAAO,EAAE;QAAE,MAAM,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI,CAAA;IAClC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,aAAa,CAAC,CAAA;CACpC;AAED,MAAM,WAAW,mBAAmB;IAClC,KAAK,EAAE,MAAM,CAAA;IACb,MAAM,EAAE,MAAM,CAAA;IACd,QAAQ,EAAE,MAAM,CAAA;CACjB;AAED,qBAAa,aAAc,SAAQ,KAAK;IACtC,IAAI,EAAE,MAAM,CAAA;gBAEA,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM;CAK1C;AAED,eAAO,MAAM,mBAAmB;;;;iBAI9B,CAAA;AAEF,eAAO,MAAM,oBAAoB;;;;;;;;;iBAO/B,CAAA;AAEF,eAAO,MAAM,yBAAyB;;;;iBAIpC,CAAA"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../../../src/platforms/webexbot/types.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../../../src/platforms/webexbot/types.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAA;AAqBvB,MAAM,OAAO,aAAc,SAAQ,KAAK;IACtC,IAAI,CAAQ;IAEZ,YAAY,OAAe,EAAE,IAAY;QACvC,KAAK,CAAC,OAAO,CAAC,CAAA;QACd,IAAI,CAAC,IAAI,GAAG,eAAe,CAAA;QAC3B,IAAI,CAAC,IAAI,GAAG,IAAI,CAAA;IAClB,CAAC;CACF;AAED,MAAM,CAAC,MAAM,mBAAmB,GAAG,CAAC,CAAC,MAAM,CAAC;IAC1C,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE;IAClB,QAAQ,EAAE,CAAC,CAAC,MAAM,EAAE;IACpB,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE;CAClB,CAAC,CAAA;AAEF,MAAM,CAAC,MAAM,oBAAoB,GAAG,CAAC,CAAC,MAAM,CAAC;IAC3C,OAAO,EAAE,CAAC;SACP,MAAM,CAAC;QACN,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE;KACnB,CAAC;SACD,QAAQ,EAAE;IACb,IAAI,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,EAAE,EAAE,mBAAmB,CAAC;CAChD,CAAC,CAAA;AAEF,MAAM,CAAC,MAAM,yBAAyB,GAAG,CAAC,CAAC,MAAM,CAAC;IAChD,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE;IACjB,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE;IAClB,QAAQ,EAAE,CAAC,CAAC,MAAM,EAAE;CACrB,CAAC,CAAA"}
|
|
@@ -42,12 +42,32 @@ This command:
|
|
|
42
42
|
- Auto-extraction runs when no valid token is stored, so manual extraction is rarely needed
|
|
43
43
|
- Messages are encrypted client-side (JWE/AES-256-GCM). Encryption keys are cached at extract time; for end-to-end encrypted conversations whose key is not cached, the key is fetched on demand (Mercury + KMS) and persisted for reuse. Non-encrypted conversations send as plaintext.
|
|
44
44
|
|
|
45
|
+
### Email/Password Login
|
|
46
|
+
|
|
47
|
+
Logs in with a Webex email and password — no browser. Useful for servers and CI/CD that need a real user token (e.g. for the real-time listener, which receives all space messages without an @mention). Run `agent-webex auth login` with no flags in a terminal to be prompted for your email and then your password (read without echoing); for headless use, pipe the password via stdin to keep it out of shell history.
|
|
48
|
+
|
|
49
|
+
```bash
|
|
50
|
+
# Interactive — prompts for email, then password (hidden)
|
|
51
|
+
agent-webex auth login
|
|
52
|
+
|
|
53
|
+
# Headless — provide the email and pipe the password from stdin
|
|
54
|
+
printf '%s' "$WEBEX_PASSWORD" | agent-webex auth login --email you@example.com --password-stdin
|
|
55
|
+
|
|
56
|
+
# Provide the email only — password is prompted securely
|
|
57
|
+
agent-webex auth login --email you@example.com
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
- Discovers the user's Webex region, performs OAuth2 Authorization Code + PKCE against Cisco IdBroker, and stores access/refresh tokens in `~/.config/agent-messenger/`
|
|
61
|
+
- Produces a KMS-scoped user token (client-side JWE/AES-256-GCM encryption works)
|
|
62
|
+
- `--idbroker-host <host>` overrides region auto-discovery if needed
|
|
63
|
+
- Accounts protected by SSO/IdP or MFA are not supported and fail with a clear error
|
|
64
|
+
|
|
45
65
|
### OAuth Device Grant (Fallback)
|
|
46
66
|
|
|
47
67
|
Uses OAuth Device Grant flow with built-in Integration credentials. No tokens to copy, no developer portal setup needed. Messages show "via agent-messenger".
|
|
48
68
|
|
|
49
69
|
```bash
|
|
50
|
-
agent-webex auth
|
|
70
|
+
agent-webex auth oauth
|
|
51
71
|
```
|
|
52
72
|
|
|
53
73
|
This command:
|
|
@@ -61,10 +81,11 @@ This command:
|
|
|
61
81
|
|
|
62
82
|
### How Login Works
|
|
63
83
|
|
|
64
|
-
1. Run `agent-webex auth extract` (recommended) or `agent-webex auth
|
|
84
|
+
1. Run `agent-webex auth extract` (recommended), `agent-webex auth login` (email/password), or `agent-webex auth oauth` (Device Grant)
|
|
65
85
|
2. For extraction: CLI reads your browser's Webex session — no prompts needed
|
|
66
|
-
3. For
|
|
67
|
-
4.
|
|
86
|
+
3. For email/password: CLI prompts for any missing credentials, then exchanges them for a token
|
|
87
|
+
4. For Device Grant: Browser opens, enter the displayed code, CLI stores tokens
|
|
88
|
+
5. Access tokens are refreshed automatically
|
|
68
89
|
|
|
69
90
|
### Token Types
|
|
70
91
|
|
|
@@ -72,6 +93,7 @@ This command:
|
|
|
72
93
|
| -------------------------------- | -------------------------------------------- | ------------------------------------ |
|
|
73
94
|
| Browser Extraction (recommended) | Session-based (re-extract when expired) | Interactive use, sending as yourself |
|
|
74
95
|
| OAuth Device Grant | 14-day access, 90-day refresh (auto-refresh) | Fallback when no browser session |
|
|
96
|
+
| Email/Password (headless) | Access + refresh (auto-refresh) | Server-side/CI without a browser |
|
|
75
97
|
| Bot Token | Never expires | CI/CD, long-running automation |
|
|
76
98
|
| Personal Access Token (PAT) | 12 hours | Quick testing |
|
|
77
99
|
|
|
@@ -81,11 +103,15 @@ This command:
|
|
|
81
103
|
# Extract token from browser (recommended)
|
|
82
104
|
agent-webex auth extract
|
|
83
105
|
|
|
84
|
-
# Log in (
|
|
106
|
+
# Log in with email/password (prompts when flags are omitted)
|
|
85
107
|
agent-webex auth login
|
|
108
|
+
printf '%s' "$WEBEX_PASSWORD" | agent-webex auth login --email you@example.com --password-stdin
|
|
86
109
|
|
|
87
|
-
# Log in
|
|
88
|
-
agent-webex auth
|
|
110
|
+
# Log in via OAuth Device Grant (opens browser)
|
|
111
|
+
agent-webex auth oauth
|
|
112
|
+
|
|
113
|
+
# Log in via OAuth with custom Integration credentials
|
|
114
|
+
agent-webex auth oauth --client-id <id> --client-secret <secret>
|
|
89
115
|
|
|
90
116
|
# Log in with a bot token (never expires)
|
|
91
117
|
agent-webex auth login --token <bot-token>
|
|
@@ -109,7 +135,7 @@ Override the built-in Integration credentials with your own:
|
|
|
109
135
|
| `AGENT_WEBEX_CLIENT_ID` | Webex Integration client ID |
|
|
110
136
|
| `AGENT_WEBEX_CLIENT_SECRET` | Webex Integration client secret |
|
|
111
137
|
|
|
112
|
-
Both must be set together. When set, `auth
|
|
138
|
+
Both must be set together. When set, `auth oauth` uses these instead of the built-in credentials.
|
|
113
139
|
|
|
114
140
|
## Commands
|
|
115
141
|
|
|
@@ -233,10 +259,10 @@ agent-webex auth login
|
|
|
233
259
|
|
|
234
260
|
### Token Expired (401 Unauthorized)
|
|
235
261
|
|
|
236
|
-
**If using Device Grant
|
|
262
|
+
**If using Device Grant**: Tokens auto-refresh. If you still get 401s, the refresh token may have expired (after 90 days). Re-run:
|
|
237
263
|
|
|
238
264
|
```bash
|
|
239
|
-
agent-webex auth
|
|
265
|
+
agent-webex auth oauth
|
|
240
266
|
```
|
|
241
267
|
|
|
242
268
|
**If using a PAT**: Generate a new one at https://developer.webex.com/docs/getting-started
|
|
@@ -245,10 +271,10 @@ agent-webex auth login
|
|
|
245
271
|
|
|
246
272
|
### "Device authorization timed out"
|
|
247
273
|
|
|
248
|
-
You didn't approve the request in the browser before the code expired. Run `auth
|
|
274
|
+
You didn't approve the request in the browser before the code expired. Run `auth oauth` again:
|
|
249
275
|
|
|
250
276
|
```bash
|
|
251
|
-
agent-webex auth
|
|
277
|
+
agent-webex auth oauth
|
|
252
278
|
```
|
|
253
279
|
|
|
254
280
|
### "Device authorization failed"
|
|
@@ -109,6 +109,8 @@ agent-webexbot message dm alice@example.com "Hey, quick question"
|
|
|
109
109
|
agent-webexbot message dm alice@example.com "**Build failed**" --markdown
|
|
110
110
|
|
|
111
111
|
# List messages in a space
|
|
112
|
+
# In group spaces, Webex only returns messages that mention the bot.
|
|
113
|
+
# Direct-space history is returned normally.
|
|
112
114
|
agent-webexbot message list <space-id>
|
|
113
115
|
agent-webexbot message list <space-id> --max 50
|
|
114
116
|
|
|
@@ -65,6 +65,8 @@ const dm = await client.sendDirectMessage('alice@example.com', 'Hey!')
|
|
|
65
65
|
await client.sendDirectMessage('alice@example.com', '**Important**', { markdown: true })
|
|
66
66
|
|
|
67
67
|
// List messages in a space (default limit: 50)
|
|
68
|
+
// In group spaces, Webex only returns messages that mention the bot.
|
|
69
|
+
// Direct-space history is returned normally.
|
|
68
70
|
const messages = await client.listMessages(roomId)
|
|
69
71
|
const limited = await client.listMessages(roomId, { max: 25 })
|
|
70
72
|
// → WebexMessage[]
|
|
@@ -175,6 +177,22 @@ const listener = new WebexBotListener(client, {
|
|
|
175
177
|
| `disconnected` | `string` (reason) | Connection dropped; listener will auto-reconnect |
|
|
176
178
|
| `error` | `Error` | Fatal error (max reconnects exceeded). Listener stops. |
|
|
177
179
|
|
|
180
|
+
### ID format
|
|
181
|
+
|
|
182
|
+
Every REST-resource ID on emitted events — person IDs (`personId`, `actorId`, `mentionedPeople`), room IDs (`roomId`), message IDs (`id`, `parentId`, `messageId`), and `AttachmentAction.id` — is in **Webex REST ID format** (`ciscospark://...` base64), directly comparable with IDs returned by `WebexBotClient` (e.g. `getMessage`, `listSpaces`, `listPeople`). The two Mercury-only activity IDs that have no REST resource — `MembershipActivity.id` and `RoomActivity.id` — stay as raw Mercury UUIDs. The original Mercury payload (with raw UUIDs) is preserved under `.raw` on every event except `message_deleted`, whose upstream Mercury event does not include the full activity.
|
|
183
|
+
|
|
184
|
+
```typescript
|
|
185
|
+
import { WebexBotClient, WebexBotListener, fromRestId } from 'agent-messenger/webexbot'
|
|
186
|
+
|
|
187
|
+
listener.on('message_created', async (event) => {
|
|
188
|
+
// event.roomId is a REST ID — compare it directly with REST results
|
|
189
|
+
const space = await client.getSpace(event.roomId)
|
|
190
|
+
|
|
191
|
+
// Recover the raw Mercury UUID when needed
|
|
192
|
+
const personUuid = fromRestId(event.personId)
|
|
193
|
+
})
|
|
194
|
+
```
|
|
195
|
+
|
|
178
196
|
### Reconnection
|
|
179
197
|
|
|
180
198
|
On transient failures (network drops, 5xx), the listener emits `disconnected` and retries with exponential backoff up to `reconnectBackoffMax`. After `maxReconnectAttempts` consecutive failures, it emits `error` and stops.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "agent-messenger",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.23.0",
|
|
4
4
|
"description": "Multi-platform messaging CLI for AI agents (Slack, Discord, Teams, Webex, Telegram, Telegram Bot, WhatsApp, LINE, Instagram, KakaoTalk, Channel Talk)",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: agent-channeltalk
|
|
3
3
|
description: Interact with Channel Talk using extracted desktop app or browser credentials - read chats, send messages, search messages, manage groups
|
|
4
|
-
version: 2.
|
|
4
|
+
version: 2.23.0
|
|
5
5
|
allowed-tools: Bash(agent-channeltalk:*)
|
|
6
6
|
metadata:
|
|
7
7
|
openclaw:
|