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