agent-messenger 2.20.4 → 2.21.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.
Files changed (115) hide show
  1. package/.claude-plugin/plugin.json +1 -1
  2. package/README.md +8 -5
  3. package/bun.lock +2 -2
  4. package/dist/package.json +10 -2
  5. package/dist/src/cli.d.ts.map +1 -1
  6. package/dist/src/cli.js +3 -0
  7. package/dist/src/cli.js.map +1 -1
  8. package/dist/src/platforms/webexbot/cli.d.ts +5 -0
  9. package/dist/src/platforms/webexbot/cli.d.ts.map +1 -0
  10. package/dist/src/platforms/webexbot/cli.js +30 -0
  11. package/dist/src/platforms/webexbot/cli.js.map +1 -0
  12. package/dist/src/platforms/webexbot/client.d.ts +41 -0
  13. package/dist/src/platforms/webexbot/client.d.ts.map +1 -0
  14. package/dist/src/platforms/webexbot/client.js +66 -0
  15. package/dist/src/platforms/webexbot/client.js.map +1 -0
  16. package/dist/src/platforms/webexbot/commands/auth.d.ts +28 -0
  17. package/dist/src/platforms/webexbot/commands/auth.d.ts.map +1 -0
  18. package/dist/src/platforms/webexbot/commands/auth.js +166 -0
  19. package/dist/src/platforms/webexbot/commands/auth.js.map +1 -0
  20. package/dist/src/platforms/webexbot/commands/index.d.ts +7 -0
  21. package/dist/src/platforms/webexbot/commands/index.d.ts.map +1 -0
  22. package/dist/src/platforms/webexbot/commands/index.js +7 -0
  23. package/dist/src/platforms/webexbot/commands/index.js.map +1 -0
  24. package/dist/src/platforms/webexbot/commands/listen.d.ts +12 -0
  25. package/dist/src/platforms/webexbot/commands/listen.d.ts.map +1 -0
  26. package/dist/src/platforms/webexbot/commands/listen.js +85 -0
  27. package/dist/src/platforms/webexbot/commands/listen.js.map +1 -0
  28. package/dist/src/platforms/webexbot/commands/member.d.ts +19 -0
  29. package/dist/src/platforms/webexbot/commands/member.d.ts.map +1 -0
  30. package/dist/src/platforms/webexbot/commands/member.js +33 -0
  31. package/dist/src/platforms/webexbot/commands/member.js.map +1 -0
  32. package/dist/src/platforms/webexbot/commands/message.d.ts +37 -0
  33. package/dist/src/platforms/webexbot/commands/message.d.ts.map +1 -0
  34. package/dist/src/platforms/webexbot/commands/message.js +142 -0
  35. package/dist/src/platforms/webexbot/commands/message.js.map +1 -0
  36. package/dist/src/platforms/webexbot/commands/shared.d.ts +9 -0
  37. package/dist/src/platforms/webexbot/commands/shared.d.ts.map +1 -0
  38. package/dist/src/platforms/webexbot/commands/shared.js +13 -0
  39. package/dist/src/platforms/webexbot/commands/shared.js.map +1 -0
  40. package/dist/src/platforms/webexbot/commands/space.d.ts +28 -0
  41. package/dist/src/platforms/webexbot/commands/space.d.ts.map +1 -0
  42. package/dist/src/platforms/webexbot/commands/space.js +61 -0
  43. package/dist/src/platforms/webexbot/commands/space.js.map +1 -0
  44. package/dist/src/platforms/webexbot/commands/whoami.d.ts +16 -0
  45. package/dist/src/platforms/webexbot/commands/whoami.d.ts.map +1 -0
  46. package/dist/src/platforms/webexbot/commands/whoami.js +29 -0
  47. package/dist/src/platforms/webexbot/commands/whoami.js.map +1 -0
  48. package/dist/src/platforms/webexbot/credential-manager.d.ts +17 -0
  49. package/dist/src/platforms/webexbot/credential-manager.d.ts.map +1 -0
  50. package/dist/src/platforms/webexbot/credential-manager.js +120 -0
  51. package/dist/src/platforms/webexbot/credential-manager.js.map +1 -0
  52. package/dist/src/platforms/webexbot/index.d.ts +9 -0
  53. package/dist/src/platforms/webexbot/index.d.ts.map +1 -0
  54. package/dist/src/platforms/webexbot/index.js +6 -0
  55. package/dist/src/platforms/webexbot/index.js.map +1 -0
  56. package/dist/src/platforms/webexbot/listener.d.ts +44 -0
  57. package/dist/src/platforms/webexbot/listener.d.ts.map +1 -0
  58. package/dist/src/platforms/webexbot/listener.js +214 -0
  59. package/dist/src/platforms/webexbot/listener.js.map +1 -0
  60. package/dist/src/platforms/webexbot/types.d.ts +60 -0
  61. package/dist/src/platforms/webexbot/types.d.ts.map +1 -0
  62. package/dist/src/platforms/webexbot/types.js +28 -0
  63. package/dist/src/platforms/webexbot/types.js.map +1 -0
  64. package/dist/src/platforms/webexbot/wdm-discovery.d.ts +4 -0
  65. package/dist/src/platforms/webexbot/wdm-discovery.d.ts.map +1 -0
  66. package/dist/src/platforms/webexbot/wdm-discovery.js +36 -0
  67. package/dist/src/platforms/webexbot/wdm-discovery.js.map +1 -0
  68. package/docs/content/docs/cli/meta.json +1 -0
  69. package/docs/content/docs/cli/webexbot.mdx +290 -0
  70. package/docs/content/docs/sdk/meta.json +1 -0
  71. package/docs/content/docs/sdk/webexbot.mdx +340 -0
  72. package/docs/src/app/page.tsx +115 -19
  73. package/package.json +10 -2
  74. package/skills/agent-channeltalk/SKILL.md +1 -1
  75. package/skills/agent-channeltalkbot/SKILL.md +1 -1
  76. package/skills/agent-discord/SKILL.md +1 -1
  77. package/skills/agent-discordbot/SKILL.md +1 -1
  78. package/skills/agent-instagram/SKILL.md +1 -1
  79. package/skills/agent-kakaotalk/SKILL.md +1 -1
  80. package/skills/agent-line/SKILL.md +1 -1
  81. package/skills/agent-slack/SKILL.md +1 -1
  82. package/skills/agent-slackbot/SKILL.md +1 -1
  83. package/skills/agent-teams/SKILL.md +1 -1
  84. package/skills/agent-telegram/SKILL.md +1 -1
  85. package/skills/agent-telegrambot/SKILL.md +1 -1
  86. package/skills/agent-webex/SKILL.md +1 -1
  87. package/skills/agent-webexbot/SKILL.md +361 -0
  88. package/skills/agent-webexbot/references/authentication.md +225 -0
  89. package/skills/agent-webexbot/references/common-patterns.md +590 -0
  90. package/skills/agent-wechatbot/SKILL.md +1 -1
  91. package/skills/agent-whatsapp/SKILL.md +1 -1
  92. package/skills/agent-whatsappbot/SKILL.md +1 -1
  93. package/src/cli.ts +4 -0
  94. package/src/platforms/webex/typings/webex-message-handler.d.ts +360 -29
  95. package/src/platforms/webexbot/cli.ts +42 -0
  96. package/src/platforms/webexbot/client.ts +87 -0
  97. package/src/platforms/webexbot/commands/auth.test.ts +185 -0
  98. package/src/platforms/webexbot/commands/auth.ts +210 -0
  99. package/src/platforms/webexbot/commands/index.ts +6 -0
  100. package/src/platforms/webexbot/commands/listen.test.ts +20 -0
  101. package/src/platforms/webexbot/commands/listen.ts +104 -0
  102. package/src/platforms/webexbot/commands/member.ts +51 -0
  103. package/src/platforms/webexbot/commands/message.ts +197 -0
  104. package/src/platforms/webexbot/commands/shared.ts +22 -0
  105. package/src/platforms/webexbot/commands/space.ts +88 -0
  106. package/src/platforms/webexbot/commands/whoami.ts +43 -0
  107. package/src/platforms/webexbot/credential-manager.test.ts +182 -0
  108. package/src/platforms/webexbot/credential-manager.ts +149 -0
  109. package/src/platforms/webexbot/index.ts +8 -0
  110. package/src/platforms/webexbot/listener.test.ts +234 -0
  111. package/src/platforms/webexbot/listener.ts +255 -0
  112. package/src/platforms/webexbot/types.test.ts +87 -0
  113. package/src/platforms/webexbot/types.ts +72 -0
  114. package/src/platforms/webexbot/wdm-discovery.test.ts +97 -0
  115. package/src/platforms/webexbot/wdm-discovery.ts +43 -0
@@ -0,0 +1,290 @@
1
+ ---
2
+ title: Webex Bot
3
+ description: Complete reference for the agent-webexbot CLI.
4
+ ---
5
+
6
+ > **Tip**: `agent-webexbot` is a shortcut for `agent-messenger webexbot`.
7
+
8
+ ## Overview
9
+
10
+ `agent-webexbot` wraps the Webex REST API using **bot tokens** issued at [developer.webex.com](https://developer.webex.com). It's designed for server-side and CI/CD integrations where you want a persistent bot identity rather than a user session.
11
+
12
+ For acting as a real user account (browser token extraction or OAuth Device Grant), use [`agent-webex`](./webex) instead.
13
+
14
+ ## Requirements
15
+
16
+ - A bot token from [developer.webex.com](https://developer.webex.com/my-apps/new/bot)
17
+ - Node.js 18+ or Bun runtime
18
+
19
+ ## Quick Start
20
+
21
+ ```bash
22
+ # 1. Set your bot token (validates against Webex)
23
+ agent-webexbot auth set YOUR_BOT_TOKEN
24
+
25
+ # 2. Verify auth
26
+ agent-webexbot whoami
27
+
28
+ # 3. Send a message
29
+ agent-webexbot message send <space-id> "Hello from the bot!"
30
+
31
+ # 4. Stream real-time events
32
+ agent-webexbot listen
33
+ ```
34
+
35
+ ## Authentication
36
+
37
+ ### Bot Token Setup
38
+
39
+ Create a bot at [developer.webex.com → My Webex Apps → Create a Bot](https://developer.webex.com/my-apps/new/bot). The token is shown once at creation time — save it immediately. Bot tokens never expire.
40
+
41
+ ```bash
42
+ # Set bot token (validates against Webex API before saving)
43
+ agent-webexbot auth set YOUR_BOT_TOKEN
44
+
45
+ # Set with a custom bot identifier for multi-bot setups
46
+ agent-webexbot auth set YOUR_BOT_TOKEN --bot deploy
47
+
48
+ # Check auth status
49
+ agent-webexbot auth status
50
+
51
+ # Clear all stored credentials
52
+ agent-webexbot auth clear
53
+ ```
54
+
55
+ Credentials are stored in `~/.config/agent-messenger/webexbot-credentials.json` (0600 permissions).
56
+
57
+ ### Multi-Bot Support
58
+
59
+ ```bash
60
+ # List all configured bots
61
+ agent-webexbot auth list
62
+
63
+ # Switch active bot
64
+ agent-webexbot auth use <bot-id>
65
+
66
+ # Remove a stored bot
67
+ agent-webexbot auth remove <bot-id>
68
+
69
+ # Use a specific bot for a single command
70
+ agent-webexbot --bot deploy message send <space-id> "Deploy succeeded"
71
+ ```
72
+
73
+ ## Commands
74
+
75
+ ### Whoami Command
76
+
77
+ ```bash
78
+ # Show current authenticated bot
79
+ agent-webexbot whoami
80
+ agent-webexbot whoami --pretty
81
+ ```
82
+
83
+ Output includes the bot's identity information from the Webex API.
84
+
85
+ ### Space Commands
86
+
87
+ ```bash
88
+ # List spaces the bot is a member of
89
+ agent-webexbot space list
90
+ agent-webexbot space list --type group
91
+ agent-webexbot space list --type direct
92
+ agent-webexbot space list --max 20
93
+
94
+ # Get space details
95
+ agent-webexbot space info <space-id>
96
+ ```
97
+
98
+ ### Message Commands
99
+
100
+ ```bash
101
+ # Send a message to a space
102
+ agent-webexbot message send <space-id> "Hello world"
103
+
104
+ # Send a markdown message
105
+ agent-webexbot message send <space-id> "**Bold** and _italic_" --markdown
106
+
107
+ # Send a direct message by email
108
+ agent-webexbot message dm alice@example.com "Hey, quick question"
109
+ agent-webexbot message dm alice@example.com "**Build failed**" --markdown
110
+
111
+ # List messages in a space
112
+ agent-webexbot message list <space-id>
113
+ agent-webexbot message list <space-id> --max 50
114
+
115
+ # Get a specific message
116
+ agent-webexbot message get <message-id>
117
+
118
+ # Edit a message (bot's own messages only)
119
+ agent-webexbot message edit <message-id> <space-id> "Updated text"
120
+ agent-webexbot message edit <message-id> <space-id> "**Updated**" --markdown
121
+
122
+ # Delete a message
123
+ agent-webexbot message delete <message-id>
124
+ ```
125
+
126
+ ### Member Commands
127
+
128
+ ```bash
129
+ # List members of a space
130
+ agent-webexbot member list <space-id>
131
+ agent-webexbot member list <space-id> --max 100
132
+ ```
133
+
134
+ ### Listen Command
135
+
136
+ Stream real-time Webex events over the Mercury WebSocket. No public URL required — works behind firewalls and in CI/CD environments.
137
+
138
+ ```bash
139
+ # Listen for all default events (NDJSON output)
140
+ agent-webexbot listen
141
+
142
+ # Filter to specific events
143
+ agent-webexbot listen --events message_created,membership_created
144
+
145
+ # Pretty-print each event
146
+ agent-webexbot listen --pretty
147
+
148
+ # Use a specific bot
149
+ agent-webexbot listen --bot deploy
150
+ ```
151
+
152
+ Supported events:
153
+
154
+ | Event | Description |
155
+ | -------------------- | ------------------------------------------- |
156
+ | `message_created` | New message posted in a space the bot is in |
157
+ | `message_updated` | Existing message edited |
158
+ | `message_deleted` | Message deleted |
159
+ | `membership_created` | Bot added to a new space |
160
+ | `attachment_action` | Adaptive card button clicked |
161
+ | `room_created` | New space created |
162
+ | `room_updated` | Space details changed |
163
+ | `webex_event` | Catch-all — every content event |
164
+ | `connected` | WebSocket connection established |
165
+ | `reconnecting` | Reconnect attempt in progress |
166
+ | `disconnected` | Connection dropped (will auto-reconnect) |
167
+ | `error` | Connection error (auto-reconnect continues) |
168
+
169
+ Default events (when `--events` is omitted): `message_created`, `message_updated`, `message_deleted`, `membership_created`, `attachment_action`, `connected`, `reconnecting`, `disconnected`, `error`.
170
+
171
+ Output is NDJSON — one JSON object per line:
172
+
173
+ ```json
174
+ {"type":"connected","payload":{"connected":true,"status":{"status":"connected","webSocketOpen":true,"kmsInitialized":true,"deviceRegistered":true,"reconnectAttempt":0}}}
175
+ {"type":"message_created","payload":{"id":"Y2lz...","text":"Hello bot!","personEmail":"alice@example.com"}}
176
+ ```
177
+
178
+ The listener filters the bot's own messages by default (`ignoreSelfMessages` defaults to `true`), preventing echo loops.
179
+
180
+ ## Global Options
181
+
182
+ All commands support these options:
183
+
184
+ ```bash
185
+ --pretty # Pretty-print JSON output (default is compact JSON)
186
+ --bot <id> # Use a specific bot for this command
187
+ ```
188
+
189
+ ## Key Differences: Webex Bot vs Webex User
190
+
191
+ | Feature | agent-webex (user) | agent-webexbot (bot) |
192
+ | ------------------ | ---------------------------------- | ------------------------------- |
193
+ | Token type | Browser session / OAuth / PAT | Bot token (developer.webex.com) |
194
+ | Auth method | Browser extraction or Device Grant | `auth set <token>` (manual) |
195
+ | Token lifetime | Session-based or 14-day OAuth | Never expires |
196
+ | Messages appear as | You (your name) | Bot identity |
197
+ | Real-time events | No | Yes (Mercury WebSocket) |
198
+ | CI/CD friendly | Possible (bot token via `--token`) | Yes (designed for it) |
199
+ | Initiate DMs | Yes | Yes (by email) |
200
+
201
+ ## Troubleshooting
202
+
203
+ ### "No credentials configured"
204
+
205
+ No bot token stored. Set one first:
206
+
207
+ ```bash
208
+ agent-webexbot auth set YOUR_BOT_TOKEN
209
+ ```
210
+
211
+ ### "Token is not a bot token"
212
+
213
+ The token you provided belongs to a user account, not a bot. Use `agent-webex` for user tokens, or create a bot at [developer.webex.com](https://developer.webex.com/my-apps/new/bot) to get a proper bot token.
214
+
215
+ ### "401 Unauthorized"
216
+
217
+ Bot tokens don't expire, so a 401 usually means the token was copied incorrectly or the bot was deleted. Double-check the full token, then re-run:
218
+
219
+ ```bash
220
+ agent-webexbot auth set YOUR_BOT_TOKEN
221
+ ```
222
+
223
+ ### Bot can't see a space
224
+
225
+ The bot must be added to each space it needs to interact with. Invite the bot from the Webex app, then retry.
226
+
227
+ ### Rate Limiting (429 Too Many Requests)
228
+
229
+ Webex allows roughly 600 API calls per minute. Add delays between bulk operations:
230
+
231
+ ```bash
232
+ sleep 1
233
+ ```
234
+
235
+ ### Space or Message Not Found
236
+
237
+ Webex uses opaque Base64-encoded IDs. Always get IDs from `space list` first:
238
+
239
+ ```bash
240
+ agent-webexbot space list --pretty
241
+ ```
242
+
243
+ ### `agent-webexbot: command not found`
244
+
245
+ The npm package is `agent-messenger`, not `agent-webexbot`:
246
+
247
+ ```bash
248
+ npm install -g agent-messenger
249
+ ```
250
+
251
+ ## AI Agent Integration
252
+
253
+ See [`skills/agent-webexbot/`](https://github.com/agent-messenger/agent-messenger/tree/main/skills/agent-webexbot) for:
254
+
255
+ - Complete skill documentation
256
+ - Common patterns and runnable templates
257
+
258
+ ### Example: CI/CD Notifier
259
+
260
+ ```bash
261
+ #!/bin/bash
262
+ # Post build status to a Webex space
263
+
264
+ SPACE_ID="Y2lzY29zcGFyazovL..."
265
+
266
+ # Send initial status
267
+ RESULT=$(agent-webexbot message send "$SPACE_ID" "Deploying v2.1.0...")
268
+ MSG_ID=$(echo "$RESULT" | jq -r '.id')
269
+
270
+ # ... do work ...
271
+
272
+ # Update with final status
273
+ agent-webexbot message edit "$MSG_ID" "$SPACE_ID" "Deployed v2.1.0 successfully!"
274
+ ```
275
+
276
+ ### Example: Real-Time Event Handler
277
+
278
+ ```bash
279
+ #!/bin/bash
280
+ # Stream events and react to messages
281
+
282
+ agent-webexbot listen --events message_created | while read -r line; do
283
+ TEXT=$(echo "$line" | jq -r '.payload.text // ""')
284
+ SPACE=$(echo "$line" | jq -r '.payload.roomId // ""')
285
+
286
+ if echo "$TEXT" | grep -qi "status"; then
287
+ agent-webexbot message send "$SPACE" "All systems operational."
288
+ fi
289
+ done
290
+ ```
@@ -7,6 +7,7 @@
7
7
  "discordbot",
8
8
  "teams",
9
9
  "webex",
10
+ "webexbot",
10
11
  "telegrambot",
11
12
  "whatsapp",
12
13
  "whatsappbot",
@@ -0,0 +1,340 @@
1
+ ---
2
+ title: Webex Bot
3
+ description: TypeScript SDK reference for Webex Bot — client, real-time Mercury WebSocket listener, credential management, and types.
4
+ ---
5
+
6
+ ## Installation
7
+
8
+ ```bash
9
+ npm install agent-messenger
10
+ ```
11
+
12
+ ```typescript
13
+ import { WebexBotClient, WebexBotCredentialManager, WebexBotListener } from 'agent-messenger/webexbot'
14
+ ```
15
+
16
+ ## WebexBotClient
17
+
18
+ The main client for interacting with the Webex REST API using a bot token. Delegates to the same underlying HTTP layer as `WebexClient`, with automatic rate-limit handling and exponential backoff on server errors.
19
+
20
+ Bot tokens never expire, so no refresh logic is needed.
21
+
22
+ ```typescript
23
+ const client = await new WebexBotClient().login({ token: 'YOUR_BOT_TOKEN' })
24
+ ```
25
+
26
+ Or use stored credentials — read from `~/.config/agent-messenger/webexbot-credentials.json` (managed by `agent-webexbot auth set`):
27
+
28
+ ```typescript
29
+ const client = await new WebexBotClient().login()
30
+ ```
31
+
32
+ ### Authentication
33
+
34
+ ```typescript
35
+ // Verify credentials and get bot identity
36
+ const me = await client.testAuth()
37
+ // → WebexPerson { id, displayName, emails, orgId, type }
38
+ ```
39
+
40
+ ### Spaces
41
+
42
+ ```typescript
43
+ // List spaces the bot is a member of (default limit: 50)
44
+ const spaces = await client.listSpaces()
45
+ const grouped = await client.listSpaces({ type: 'group', max: 20 })
46
+ // → WebexSpace[]
47
+
48
+ // Get a specific space by ID
49
+ const space = await client.getSpace(spaceId)
50
+ // → WebexSpace { id, title, type, isLocked, lastActivity, created, creatorId }
51
+ ```
52
+
53
+ ### Messages
54
+
55
+ ```typescript
56
+ // Send a message to a space
57
+ const msg = await client.sendMessage(roomId, 'Hello world')
58
+ // → WebexMessage { id, roomId, roomType, text, personId, personEmail, created }
59
+
60
+ // Send a markdown message
61
+ await client.sendMessage(roomId, '**Bold** and _italic_', { markdown: true })
62
+
63
+ // Send a direct message by email
64
+ const dm = await client.sendDirectMessage('alice@example.com', 'Hey!')
65
+ await client.sendDirectMessage('alice@example.com', '**Important**', { markdown: true })
66
+
67
+ // List messages in a space (default limit: 50)
68
+ const messages = await client.listMessages(roomId)
69
+ const limited = await client.listMessages(roomId, { max: 25 })
70
+ // → WebexMessage[]
71
+
72
+ // Get a single message by ID
73
+ const message = await client.getMessage(messageId)
74
+ // → WebexMessage
75
+
76
+ // Edit a message (bot's own messages only)
77
+ const updated = await client.editMessage(messageId, roomId, 'Updated text')
78
+ await client.editMessage(messageId, roomId, '**Updated**', { markdown: true })
79
+ // → WebexMessage
80
+
81
+ // Delete a message
82
+ await client.deleteMessage(messageId)
83
+ ```
84
+
85
+ ### Memberships
86
+
87
+ ```typescript
88
+ // List members of a space
89
+ const members = await client.listMemberships(roomId)
90
+ const limited = await client.listMemberships(roomId, { max: 100 })
91
+ // → WebexMembership[]
92
+
93
+ // List all spaces the bot belongs to
94
+ const mySpaces = await client.listMyMemberships()
95
+ // → WebexMembership[]
96
+ ```
97
+
98
+ ### People
99
+
100
+ ```typescript
101
+ // Search people by email or display name
102
+ const people = await client.listPeople({ email: 'alice@example.com' })
103
+ const byName = await client.listPeople({ displayName: 'Alice', max: 10 })
104
+ // → WebexPerson[]
105
+ ```
106
+
107
+ ## WebexBotListener
108
+
109
+ A real-time event listener using the Mercury WebSocket protocol. No public URL required — works behind firewalls and in CI/CD environments. Analogous to Slack Socket Mode or Discord Gateway.
110
+
111
+ Under the hood, the listener uses `webex-message-handler` which handles WDM device registration, Mercury WebSocket connection, KMS key decryption, and auto-reconnect with exponential backoff. The bot's Webex cluster is auto-discovered from the U2C catalog at startup, so the listener works regardless of the org's home region.
112
+
113
+ The bot's own messages are filtered by default (`ignoreSelfMessages` defaults to `true`), preventing echo loops.
114
+
115
+ ```typescript
116
+ import { WebexBotClient, WebexBotListener } from 'agent-messenger/webexbot'
117
+
118
+ const client = await new WebexBotClient().login({ token: 'YOUR_BOT_TOKEN' })
119
+ const listener = new WebexBotListener(client)
120
+
121
+ listener.on('connected', ({ connected, status }) => {
122
+ console.log(`Connected (${connected}, state: ${status.status})`)
123
+ })
124
+
125
+ listener.on('message_created', (event) => {
126
+ console.log(`New message in ${event.roomId}: ${event.text}`)
127
+ })
128
+
129
+ listener.on('membership_created', (event) => {
130
+ console.log(`Bot added to space: ${event.roomId}`)
131
+ })
132
+
133
+ listener.on('disconnected', (reason) => {
134
+ console.log(`Disconnected: ${reason} — will reconnect`)
135
+ })
136
+
137
+ listener.on('error', (error) => {
138
+ console.error('Fatal error:', error)
139
+ })
140
+
141
+ await listener.start()
142
+ ```
143
+
144
+ ### Constructor Options
145
+
146
+ ```typescript
147
+ const listener = new WebexBotListener(client, {
148
+ ignoreSelfMessages: true, // Filter bot's own messages (default: true)
149
+ pingInterval: 15000, // WebSocket ping interval in ms
150
+ pongTimeout: 5000, // Pong response timeout in ms
151
+ reconnectBackoffMax: 30000, // Max reconnect delay in ms
152
+ maxReconnectAttempts: 10, // Max reconnect attempts before giving up
153
+ })
154
+ ```
155
+
156
+ ### Lifecycle
157
+
158
+ - `start()` — Registers a WDM device, opens the Mercury WebSocket, and begins streaming events.
159
+ - `stop()` — Closes the WebSocket and cleans up listeners. Safe to call multiple times.
160
+
161
+ ### Events
162
+
163
+ | Event | Payload | Notes |
164
+ | -------------------- | ------------------------ | ------------------------------------------------------ |
165
+ | `message_created` | `DecryptedMessage` | New message in a space the bot is in |
166
+ | `message_updated` | `DecryptedMessage` | Existing message edited |
167
+ | `message_deleted` | `DeletedMessage` | Message deleted |
168
+ | `membership_created` | `MembershipActivity` | Bot added to a new space |
169
+ | `attachment_action` | `AttachmentAction` | Adaptive card button clicked |
170
+ | `room_created` | `RoomActivity` | New space created |
171
+ | `room_updated` | `RoomActivity` | Space details changed |
172
+ | `webex_event` | (any of the above) | Catch-all — every content event |
173
+ | `connected` | `{ connected, status }` | Once after `start()` succeeds |
174
+ | `reconnecting` | `number` (attempt count) | Reconnect attempt in progress |
175
+ | `disconnected` | `string` (reason) | Connection dropped; listener will auto-reconnect |
176
+ | `error` | `Error` | Fatal error (max reconnects exceeded). Listener stops. |
177
+
178
+ ### Reconnection
179
+
180
+ 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.
181
+
182
+ ## WebexBotCredentialManager
183
+
184
+ ```typescript
185
+ const manager = new WebexBotCredentialManager()
186
+
187
+ // Store credentials (sets this bot as current)
188
+ await manager.setCredentials({ token, bot_id: 'deploy', bot_name: 'Deploy Bot' })
189
+
190
+ // Retrieve current bot credentials
191
+ const creds = await manager.getCredentials()
192
+ // → { token, bot_id, bot_name } | null
193
+
194
+ // Retrieve a specific bot
195
+ const creds = await manager.getCredentials('deploy')
196
+
197
+ // Multi-bot support
198
+ const all = await manager.listAll()
199
+ // → Array<{ bot_id, bot_name, is_current }>
200
+
201
+ await manager.setCurrent('deploy')
202
+ await manager.removeBot('alert')
203
+ await manager.clearCredentials()
204
+ ```
205
+
206
+ Credentials are stored under `~/.config/agent-messenger/webexbot-credentials.json` with `0600` file permissions. Override the directory with the `AGENT_MESSENGER_CONFIG_DIR` environment variable, or pass `new WebexBotCredentialManager(customDir)`.
207
+
208
+ ## Types
209
+
210
+ ```typescript
211
+ import type {
212
+ WebexSpace,
213
+ WebexMessage,
214
+ WebexPerson,
215
+ WebexMembership,
216
+ WebexBotConfig,
217
+ WebexBotCredentials,
218
+ WebexBotListenerOptions,
219
+ WebexBotListenerEventMap,
220
+ } from 'agent-messenger/webexbot'
221
+ ```
222
+
223
+ ### Zod Schemas
224
+
225
+ Runtime-validated schemas are also exported:
226
+
227
+ ```typescript
228
+ import {
229
+ WebexSpaceSchema,
230
+ WebexMessageSchema,
231
+ WebexPersonSchema,
232
+ WebexMembershipSchema,
233
+ WebexBotConfigSchema,
234
+ WebexBotCredentialsSchema,
235
+ } from 'agent-messenger/webexbot'
236
+ ```
237
+
238
+ ## Real-time Events (Webex Bot)
239
+
240
+ Stream messages and membership events over the Mercury WebSocket — no public HTTP endpoint required.
241
+
242
+ ```typescript
243
+ import { WebexBotClient, WebexBotListener } from 'agent-messenger/webexbot'
244
+
245
+ const client = await new WebexBotClient().login({ token: 'YOUR_BOT_TOKEN' })
246
+ const listener = new WebexBotListener(client)
247
+
248
+ listener.on('message_created', (event) => {
249
+ console.log(`New message in ${event.roomId}: ${event.text}`)
250
+ })
251
+
252
+ listener.on('membership_created', (event) => {
253
+ console.log(`Bot added to space: ${event.roomId}`)
254
+ })
255
+
256
+ await listener.start()
257
+ ```
258
+
259
+ ## Examples
260
+
261
+ ### Deploy Notifier
262
+
263
+ Post a deployment message, then update it when done.
264
+
265
+ ```typescript
266
+ import { WebexBotClient } from 'agent-messenger/webexbot'
267
+
268
+ const client = await new WebexBotClient().login()
269
+
270
+ // Post initial status
271
+ const msg = await client.sendMessage(spaceId, 'Deploying v2.1.0 to production...')
272
+
273
+ // Stream progress
274
+ await client.sendMessage(spaceId, 'Building application...')
275
+ await client.sendMessage(spaceId, 'Running tests (142 passed)...')
276
+ await client.sendMessage(spaceId, 'Rolling out to 3 regions...')
277
+
278
+ // Update original message with final status
279
+ await client.editMessage(msg.id, spaceId, 'Deployed v2.1.0 to production')
280
+ ```
281
+
282
+ ### Reactive Bot
283
+
284
+ Listen for messages and respond to keywords.
285
+
286
+ ```typescript
287
+ import { WebexBotClient, WebexBotListener } from 'agent-messenger/webexbot'
288
+
289
+ const client = await new WebexBotClient().login({ token: 'YOUR_BOT_TOKEN' })
290
+ const listener = new WebexBotListener(client)
291
+
292
+ listener.on('message_created', async (event) => {
293
+ const text = event.text?.toLowerCase() ?? ''
294
+
295
+ if (text.includes('status')) {
296
+ await client.sendMessage(event.roomId, 'All systems operational.')
297
+ }
298
+
299
+ if (text.includes('help')) {
300
+ await client.sendMessage(event.roomId, 'Available commands: `status`, `help`')
301
+ }
302
+ })
303
+
304
+ await listener.start()
305
+ ```
306
+
307
+ ### Multi-Space Broadcast
308
+
309
+ Send a message to every space the bot is in.
310
+
311
+ ```typescript
312
+ import { WebexBotClient } from 'agent-messenger/webexbot'
313
+
314
+ const client = await new WebexBotClient().login()
315
+
316
+ const spaces = await client.listSpaces({ type: 'group' })
317
+
318
+ for (const space of spaces) {
319
+ await client.sendMessage(space.id, 'Maintenance window starts in 30 minutes.')
320
+ // Respect rate limits
321
+ await new Promise((r) => setTimeout(r, 200))
322
+ }
323
+ ```
324
+
325
+ ### Direct Message Pipeline
326
+
327
+ Send a DM to multiple people by email.
328
+
329
+ ```typescript
330
+ import { WebexBotClient } from 'agent-messenger/webexbot'
331
+
332
+ const client = await new WebexBotClient().login()
333
+
334
+ const recipients = ['alice@example.com', 'bob@example.com', 'carol@example.com']
335
+
336
+ for (const email of recipients) {
337
+ await client.sendDirectMessage(email, 'Reminder: standup in 5 minutes')
338
+ await new Promise((r) => setTimeout(r, 200))
339
+ }
340
+ ```