Skip to main content

webex_message_handler/
types.rs

1//! Data types for webex-message-handler.
2
3use serde::{Deserialize, Serialize};
4use std::collections::HashMap;
5
6/// Configuration for WebexMessageHandler.
7#[derive(Clone)]
8pub struct Config {
9    /// Webex bot or user access token (required).
10    pub token: String,
11
12    /// Optional HTTP client for proxy support or custom connection handling.
13    /// If None, a default client will be created.
14    pub client: Option<reqwest::Client>,
15
16    /// Mercury ping interval in seconds (default: 15).
17    pub ping_interval: f64,
18
19    /// Pong response timeout in seconds (default: 14).
20    pub pong_timeout: f64,
21
22    /// Max reconnect backoff in seconds (default: 32).
23    pub reconnect_backoff_max: f64,
24
25    /// Max consecutive reconnection attempts (default: 10).
26    pub max_reconnect_attempts: u32,
27}
28
29impl Default for Config {
30    fn default() -> Self {
31        Self {
32            token: String::new(),
33            client: None,
34            ping_interval: 15.0,
35            pong_timeout: 14.0,
36            reconnect_backoff_max: 32.0,
37            max_reconnect_attempts: 10,
38        }
39    }
40}
41
42/// Result of WDM device registration.
43#[derive(Debug, Clone, Serialize, Deserialize)]
44pub struct DeviceRegistration {
45    /// Mercury WebSocket URL.
46    #[serde(rename = "webSocketUrl")]
47    pub web_socket_url: String,
48
49    /// Device URL (used as clientId for KMS).
50    #[serde(rename = "url")]
51    pub device_url: String,
52
53    /// Bot's user ID.
54    #[serde(rename = "userId")]
55    pub user_id: String,
56
57    /// Service catalog from WDM.
58    #[serde(default)]
59    pub services: HashMap<String, String>,
60
61    /// Encryption service URL extracted from services.
62    #[serde(skip)]
63    pub encryption_service_url: String,
64}
65
66/// Actor in a Mercury activity.
67#[derive(Debug, Clone, Default, Serialize, Deserialize)]
68pub struct MercuryActor {
69    #[serde(default)]
70    pub id: String,
71
72    #[serde(rename = "objectType", default)]
73    pub object_type: String,
74
75    #[serde(rename = "emailAddress", default)]
76    pub email_address: Option<String>,
77}
78
79/// Object in a Mercury activity.
80#[derive(Debug, Clone, Default, Serialize, Deserialize)]
81pub struct MercuryObject {
82    #[serde(default)]
83    pub id: String,
84
85    #[serde(rename = "objectType", default)]
86    pub object_type: String,
87
88    #[serde(rename = "displayName", default)]
89    pub display_name: Option<String>,
90
91    #[serde(default)]
92    pub content: Option<String>,
93
94    #[serde(rename = "encryptionKeyUrl", default)]
95    pub encryption_key_url: Option<String>,
96}
97
98/// Target in a Mercury activity.
99#[derive(Debug, Clone, Default, Serialize, Deserialize)]
100pub struct MercuryTarget {
101    #[serde(default)]
102    pub id: String,
103
104    #[serde(rename = "objectType", default)]
105    pub object_type: String,
106
107    #[serde(rename = "encryptionKeyUrl", default)]
108    pub encryption_key_url: Option<String>,
109
110    #[serde(default)]
111    pub tags: Vec<String>,
112}
113
114/// A Mercury conversation activity.
115#[derive(Debug, Clone, Serialize, Deserialize)]
116pub struct MercuryActivity {
117    #[serde(default)]
118    pub id: String,
119
120    #[serde(default)]
121    pub verb: String,
122
123    #[serde(default)]
124    pub actor: MercuryActor,
125
126    #[serde(default)]
127    pub object: MercuryObject,
128
129    #[serde(default)]
130    pub target: MercuryTarget,
131
132    #[serde(default)]
133    pub published: String,
134
135    #[serde(rename = "encryptionKeyUrl", default)]
136    pub encryption_key_url: Option<String>,
137}
138
139/// A decrypted Webex message.
140#[derive(Debug, Clone)]
141pub struct DecryptedMessage {
142    /// Unique message ID.
143    pub id: String,
144
145    /// Conversation/space ID.
146    pub room_id: String,
147
148    /// Sender's user ID.
149    pub person_id: String,
150
151    /// Sender's email address.
152    pub person_email: String,
153
154    /// Decrypted plain text.
155    pub text: String,
156
157    /// Decrypted HTML content (rich text messages).
158    pub html: Option<String>,
159
160    /// ISO 8601 timestamp.
161    pub created: String,
162
163    /// "direct", "group", or None.
164    pub room_type: Option<String>,
165
166    /// Full decrypted activity for advanced use.
167    pub raw: MercuryActivity,
168}
169
170/// A deleted Webex message notification.
171#[derive(Debug, Clone)]
172pub struct DeletedMessage {
173    pub message_id: String,
174    pub room_id: String,
175    pub person_id: String,
176}
177
178/// Overall connection state.
179#[derive(Debug, Clone, Copy, PartialEq, Eq)]
180pub enum ConnectionStatus {
181    Connected,
182    Connecting,
183    Reconnecting,
184    Disconnected,
185}
186
187impl std::fmt::Display for ConnectionStatus {
188    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
189        match self {
190            Self::Connected => write!(f, "connected"),
191            Self::Connecting => write!(f, "connecting"),
192            Self::Reconnecting => write!(f, "reconnecting"),
193            Self::Disconnected => write!(f, "disconnected"),
194        }
195    }
196}
197
198/// Structured health check of all connection subsystems.
199#[derive(Debug, Clone)]
200pub struct HandlerStatus {
201    /// Overall connection state.
202    pub status: ConnectionStatus,
203
204    /// Whether the Mercury WebSocket is currently open.
205    pub web_socket_open: bool,
206
207    /// Whether the KMS encryption context has been established.
208    pub kms_initialized: bool,
209
210    /// Whether the device is registered with WDM.
211    pub device_registered: bool,
212
213    /// Current auto-reconnect attempt number (0 if not reconnecting).
214    pub reconnect_attempt: u32,
215}