webex-message-handler
Lightweight Rust crate for receiving and decrypting Webex messages over the Mercury WebSocket, without the full Webex SDK.
Features
- Mercury WebSocket — connects to Webex Mercury with auth, ping/pong heartbeat, and automatic reconnection with exponential backoff
- KMS decryption — ECDH P-256 key exchange + A256KW/A256GCM JWE decryption, all handled transparently
- WDM device registration — automatic device lifecycle management
- Async Tokio — built on
tokioandtokio-tungstenitefor high-performance async I/O - Structured logging — uses the
tracingecosystem
Installation
Add to your Cargo.toml:
[]
= { = "https://github.com/ecopelan/webex-message-handler-rs" }
Quick Start
use ;
async
Important: Implementing Loop Detection
This library only handles the receive side of messaging — it decrypts incoming messages from the Mercury WebSocket. It has no visibility into messages your bot sends via the REST API. This means it cannot detect message loops on its own.
If your bot replies to incoming messages, you must implement loop detection in your wrapper code. Without it, a bug or misconfiguration could cause your bot to endlessly reply to its own messages. Webex enforces a server-side rate limit (approximately 11 consecutive messages before throttling), but that still results in spam before the cutoff.
Recommended approach: Track your bot's outgoing message rate. If it exceeds a threshold (e.g., 5 messages in 3 seconds to the same room), pause sending and log a warning.
The ignore_self_messages option (default: true) provides a first line of defense by filtering out messages sent by this bot's own identity. If the library cannot verify the bot's identity during connect() (e.g., /people/me API failure), connection will fail rather than silently running without protection. Set ignore_self_messages to false to opt out, but only if you have your own loop prevention in place.
Proxy Support (Enterprise)
For corporate environments behind a proxy, pass a configured reqwest::Client:
use ;
use Proxy;
async
Note: The reqwest::Client proxy configuration applies to HTTP traffic (device registration, KMS). The Mercury WebSocket (tokio-tungstenite) connects directly and does not read proxy environment variables. For full WebSocket proxy support, use injected mode with a custom WebSocketFactory.
Configuration
| Field | Type | Default | Description |
|---|---|---|---|
token |
String |
(required) | Webex bot or user access token |
ignore_self_messages |
bool |
true |
Filter out messages sent by this bot |
client |
Option<reqwest::Client> |
None |
HTTP client for proxy support (creates default if None) |
ping_interval |
f64 |
15.0 |
Mercury ping interval in seconds |
pong_timeout |
f64 |
14.0 |
Pong response timeout in seconds |
reconnect_backoff_max |
f64 |
32.0 |
Max reconnect backoff in seconds |
max_reconnect_attempts |
u32 |
10 |
Max consecutive reconnection attempts |
API
See API.md for the full API reference.
Architecture
WebexMessageHandler (orchestrator)
├── DeviceManager — WDM register/refresh/unregister
├── MercurySocket — WebSocket + auth + heartbeat + reconnect
├── KmsClient — ECDH handshake + key retrieval
└── MessageDecryptor — JWE A256KW+A256GCM decryption
Running the Example
WEBEX_BOT_TOKEN=your_token_here
License
MIT