1use std::collections::HashMap;
7
8use serde::{Deserialize, Serialize};
9
10use crate::secret::SecretString;
11
12#[derive(Debug, Clone, Serialize, Deserialize, Default)]
16pub struct ChannelsConfig {
17 #[serde(default)]
19 pub telegram: TelegramConfig,
20
21 #[serde(default)]
23 pub slack: SlackConfig,
24
25 #[serde(default)]
27 pub discord: DiscordConfig,
28
29 #[serde(default)]
31 pub whatsapp: WhatsAppConfig,
32
33 #[serde(default)]
35 pub feishu: FeishuConfig,
36
37 #[serde(default)]
39 pub dingtalk: DingTalkConfig,
40
41 #[serde(default)]
43 pub mochat: MochatConfig,
44
45 #[serde(default)]
47 pub email: EmailConfig,
48
49 #[serde(default)]
51 pub qq: QQConfig,
52
53 #[serde(flatten)]
55 pub extra: HashMap<String, serde_json::Value>,
56}
57
58#[derive(Debug, Clone, Serialize, Deserialize, Default)]
60pub struct TelegramConfig {
61 #[serde(default)]
63 pub enabled: bool,
64
65 #[serde(default)]
67 pub token: SecretString,
68
69 #[serde(default, alias = "tokenEnv")]
72 pub token_env: Option<String>,
73
74 #[serde(default, alias = "allowFrom")]
76 pub allow_from: Vec<String>,
77
78 #[serde(default)]
80 pub proxy: Option<String>,
81}
82
83#[derive(Debug, Clone, Serialize, Deserialize)]
85pub struct SlackConfig {
86 #[serde(default)]
88 pub enabled: bool,
89
90 #[serde(default = "default_slack_mode")]
92 pub mode: String,
93
94 #[serde(default = "default_webhook_path", alias = "webhookPath")]
96 pub webhook_path: String,
97
98 #[serde(default, alias = "botToken")]
100 pub bot_token: SecretString,
101
102 #[serde(default, alias = "botTokenEnv")]
105 pub bot_token_env: Option<String>,
106
107 #[serde(default, alias = "appToken")]
109 pub app_token: SecretString,
110
111 #[serde(default, alias = "appTokenEnv")]
114 pub app_token_env: Option<String>,
115
116 #[serde(default = "super::default_true", alias = "userTokenReadOnly")]
118 pub user_token_read_only: bool,
119
120 #[serde(default = "default_group_policy", alias = "groupPolicy")]
122 pub group_policy: String,
123
124 #[serde(default, alias = "groupAllowFrom")]
126 pub group_allow_from: Vec<String>,
127
128 #[serde(default)]
130 pub dm: SlackDMConfig,
131}
132
133fn default_slack_mode() -> String {
134 "socket".into()
135}
136fn default_webhook_path() -> String {
137 "/slack/events".into()
138}
139fn default_group_policy() -> String {
140 "mention".into()
141}
142
143impl Default for SlackConfig {
144 fn default() -> Self {
145 Self {
146 enabled: false,
147 mode: default_slack_mode(),
148 webhook_path: default_webhook_path(),
149 bot_token: SecretString::default(),
150 bot_token_env: None,
151 app_token: SecretString::default(),
152 app_token_env: None,
153 user_token_read_only: true,
154 group_policy: default_group_policy(),
155 group_allow_from: Vec::new(),
156 dm: SlackDMConfig::default(),
157 }
158 }
159}
160
161#[derive(Debug, Clone, Serialize, Deserialize)]
163pub struct SlackDMConfig {
164 #[serde(default = "super::default_true")]
166 pub enabled: bool,
167
168 #[serde(default = "default_dm_policy")]
170 pub policy: String,
171
172 #[serde(default, alias = "allowFrom")]
174 pub allow_from: Vec<String>,
175}
176
177fn default_dm_policy() -> String {
178 "open".into()
179}
180
181impl Default for SlackDMConfig {
182 fn default() -> Self {
183 Self {
184 enabled: true,
185 policy: default_dm_policy(),
186 allow_from: Vec::new(),
187 }
188 }
189}
190
191#[derive(Debug, Clone, Serialize, Deserialize)]
193pub struct DiscordConfig {
194 #[serde(default)]
196 pub enabled: bool,
197
198 #[serde(default)]
200 pub token: SecretString,
201
202 #[serde(default, alias = "tokenEnv")]
205 pub token_env: Option<String>,
206
207 #[serde(default, alias = "allowFrom")]
209 pub allow_from: Vec<String>,
210
211 #[serde(default = "default_discord_gateway_url", alias = "gatewayUrl")]
213 pub gateway_url: String,
214
215 #[serde(default = "default_discord_intents")]
217 pub intents: u32,
218}
219
220fn default_discord_gateway_url() -> String {
221 "wss://gateway.discord.gg/?v=10&encoding=json".into()
222}
223fn default_discord_intents() -> u32 {
224 37377 }
226
227impl Default for DiscordConfig {
228 fn default() -> Self {
229 Self {
230 enabled: false,
231 token: SecretString::default(),
232 token_env: None,
233 allow_from: Vec::new(),
234 gateway_url: default_discord_gateway_url(),
235 intents: default_discord_intents(),
236 }
237 }
238}
239
240#[derive(Debug, Clone, Serialize, Deserialize)]
242pub struct WhatsAppConfig {
243 #[serde(default)]
245 pub enabled: bool,
246
247 #[serde(default = "default_whatsapp_bridge_url", alias = "bridgeUrl")]
249 pub bridge_url: String,
250
251 #[serde(default, alias = "bridgeToken")]
253 pub bridge_token: SecretString,
254
255 #[serde(default, alias = "allowFrom")]
257 pub allow_from: Vec<String>,
258}
259
260fn default_whatsapp_bridge_url() -> String {
261 "ws://localhost:3001".into()
262}
263
264impl Default for WhatsAppConfig {
265 fn default() -> Self {
266 Self {
267 enabled: false,
268 bridge_url: default_whatsapp_bridge_url(),
269 bridge_token: SecretString::default(),
270 allow_from: Vec::new(),
271 }
272 }
273}
274
275#[derive(Debug, Clone, Serialize, Deserialize, Default)]
277pub struct FeishuConfig {
278 #[serde(default)]
280 pub enabled: bool,
281
282 #[serde(default, alias = "appId")]
284 pub app_id: String,
285
286 #[serde(default, alias = "appSecret")]
288 pub app_secret: SecretString,
289
290 #[serde(default, alias = "encryptKey")]
292 pub encrypt_key: String,
293
294 #[serde(default, alias = "verificationToken")]
296 pub verification_token: SecretString,
297
298 #[serde(default, alias = "allowFrom")]
300 pub allow_from: Vec<String>,
301}
302
303#[derive(Debug, Clone, Serialize, Deserialize, Default)]
305pub struct DingTalkConfig {
306 #[serde(default)]
308 pub enabled: bool,
309
310 #[serde(default, alias = "clientId")]
312 pub client_id: String,
313
314 #[serde(default, alias = "clientSecret")]
316 pub client_secret: SecretString,
317
318 #[serde(default, alias = "allowFrom")]
320 pub allow_from: Vec<String>,
321}
322
323#[derive(Debug, Clone, Serialize, Deserialize, Default)]
325pub struct MochatMentionConfig {
326 #[serde(default, alias = "requireInGroups")]
328 pub require_in_groups: bool,
329}
330
331#[derive(Debug, Clone, Serialize, Deserialize, Default)]
333pub struct MochatGroupRule {
334 #[serde(default, alias = "requireMention")]
336 pub require_mention: bool,
337}
338
339#[derive(Debug, Clone, Serialize, Deserialize)]
341pub struct MochatConfig {
342 #[serde(default)]
344 pub enabled: bool,
345
346 #[serde(default = "default_mochat_base_url", alias = "baseUrl")]
348 pub base_url: String,
349
350 #[serde(default, alias = "socketUrl")]
352 pub socket_url: String,
353
354 #[serde(default = "default_socket_path", alias = "socketPath")]
356 pub socket_path: String,
357
358 #[serde(default, alias = "socketDisableMsgpack")]
360 pub socket_disable_msgpack: bool,
361
362 #[serde(default = "default_1000", alias = "socketReconnectDelayMs")]
364 pub socket_reconnect_delay_ms: i64,
365
366 #[serde(default = "default_10000", alias = "socketMaxReconnectDelayMs")]
368 pub socket_max_reconnect_delay_ms: i64,
369
370 #[serde(default = "default_10000", alias = "socketConnectTimeoutMs")]
372 pub socket_connect_timeout_ms: i64,
373
374 #[serde(default = "default_30000", alias = "refreshIntervalMs")]
376 pub refresh_interval_ms: i64,
377
378 #[serde(default = "default_25000", alias = "watchTimeoutMs")]
380 pub watch_timeout_ms: i64,
381
382 #[serde(default = "default_100", alias = "watchLimit")]
384 pub watch_limit: i64,
385
386 #[serde(default = "default_500", alias = "retryDelayMs")]
388 pub retry_delay_ms: i64,
389
390 #[serde(default, alias = "maxRetryAttempts")]
392 pub max_retry_attempts: i64,
393
394 #[serde(default, alias = "clawToken")]
396 pub claw_token: SecretString,
397
398 #[serde(default, alias = "agentUserId")]
400 pub agent_user_id: String,
401
402 #[serde(default)]
404 pub sessions: Vec<String>,
405
406 #[serde(default)]
408 pub panels: Vec<String>,
409
410 #[serde(default, alias = "allowFrom")]
412 pub allow_from: Vec<String>,
413
414 #[serde(default)]
416 pub mention: MochatMentionConfig,
417
418 #[serde(default)]
420 pub groups: HashMap<String, MochatGroupRule>,
421
422 #[serde(default = "default_reply_delay_mode", alias = "replyDelayMode")]
424 pub reply_delay_mode: String,
425
426 #[serde(default = "default_120000", alias = "replyDelayMs")]
428 pub reply_delay_ms: i64,
429}
430
431fn default_mochat_base_url() -> String {
432 "https://mochat.io".into()
433}
434fn default_socket_path() -> String {
435 "/socket.io".into()
436}
437fn default_reply_delay_mode() -> String {
438 "non-mention".into()
439}
440fn default_1000() -> i64 {
441 1000
442}
443fn default_10000() -> i64 {
444 10000
445}
446fn default_30000() -> i64 {
447 30000
448}
449fn default_25000() -> i64 {
450 25000
451}
452fn default_100() -> i64 {
453 100
454}
455fn default_500() -> i64 {
456 500
457}
458fn default_120000() -> i64 {
459 120000
460}
461
462impl Default for MochatConfig {
463 fn default() -> Self {
464 Self {
465 enabled: false,
466 base_url: default_mochat_base_url(),
467 socket_url: String::new(),
468 socket_path: default_socket_path(),
469 socket_disable_msgpack: false,
470 socket_reconnect_delay_ms: default_1000(),
471 socket_max_reconnect_delay_ms: default_10000(),
472 socket_connect_timeout_ms: default_10000(),
473 refresh_interval_ms: default_30000(),
474 watch_timeout_ms: default_25000(),
475 watch_limit: default_100(),
476 retry_delay_ms: default_500(),
477 max_retry_attempts: 0,
478 claw_token: SecretString::default(),
479 agent_user_id: String::new(),
480 sessions: Vec::new(),
481 panels: Vec::new(),
482 allow_from: Vec::new(),
483 mention: MochatMentionConfig::default(),
484 groups: HashMap::new(),
485 reply_delay_mode: default_reply_delay_mode(),
486 reply_delay_ms: default_120000(),
487 }
488 }
489}
490
491#[derive(Debug, Clone, Serialize, Deserialize)]
493pub struct EmailConfig {
494 #[serde(default)]
496 pub enabled: bool,
497
498 #[serde(default, alias = "consentGranted")]
500 pub consent_granted: bool,
501
502 #[serde(default, alias = "imapHost")]
505 pub imap_host: String,
506
507 #[serde(default = "default_imap_port", alias = "imapPort")]
509 pub imap_port: u16,
510
511 #[serde(default, alias = "imapUsername")]
513 pub imap_username: String,
514
515 #[serde(default, alias = "imapPassword")]
517 pub imap_password: SecretString,
518
519 #[serde(default = "default_imap_mailbox", alias = "imapMailbox")]
521 pub imap_mailbox: String,
522
523 #[serde(default = "super::default_true", alias = "imapUseSsl")]
525 pub imap_use_ssl: bool,
526
527 #[serde(default, alias = "smtpHost")]
530 pub smtp_host: String,
531
532 #[serde(default = "default_smtp_port", alias = "smtpPort")]
534 pub smtp_port: u16,
535
536 #[serde(default, alias = "smtpUsername")]
538 pub smtp_username: String,
539
540 #[serde(default, alias = "smtpPassword")]
542 pub smtp_password: SecretString,
543
544 #[serde(default = "super::default_true", alias = "smtpUseTls")]
546 pub smtp_use_tls: bool,
547
548 #[serde(default, alias = "smtpUseSsl")]
550 pub smtp_use_ssl: bool,
551
552 #[serde(default, alias = "fromAddress")]
554 pub from_address: String,
555
556 #[serde(default = "super::default_true", alias = "autoReplyEnabled")]
559 pub auto_reply_enabled: bool,
560
561 #[serde(default = "default_poll_interval", alias = "pollIntervalSeconds")]
563 pub poll_interval_seconds: u32,
564
565 #[serde(default = "super::default_true", alias = "markSeen")]
567 pub mark_seen: bool,
568
569 #[serde(default = "default_max_body_chars", alias = "maxBodyChars")]
571 pub max_body_chars: u32,
572
573 #[serde(default = "default_subject_prefix", alias = "subjectPrefix")]
575 pub subject_prefix: String,
576
577 #[serde(default, alias = "allowFrom")]
579 pub allow_from: Vec<String>,
580}
581
582fn default_imap_port() -> u16 {
583 993
584}
585fn default_imap_mailbox() -> String {
586 "INBOX".into()
587}
588fn default_smtp_port() -> u16 {
589 587
590}
591fn default_poll_interval() -> u32 {
592 30
593}
594fn default_max_body_chars() -> u32 {
595 12000
596}
597fn default_subject_prefix() -> String {
598 "Re: ".into()
599}
600
601impl Default for EmailConfig {
602 fn default() -> Self {
603 Self {
604 enabled: false,
605 consent_granted: false,
606 imap_host: String::new(),
607 imap_port: default_imap_port(),
608 imap_username: String::new(),
609 imap_password: SecretString::default(),
610 imap_mailbox: default_imap_mailbox(),
611 imap_use_ssl: true,
612 smtp_host: String::new(),
613 smtp_port: default_smtp_port(),
614 smtp_username: String::new(),
615 smtp_password: SecretString::default(),
616 smtp_use_tls: true,
617 smtp_use_ssl: false,
618 from_address: String::new(),
619 auto_reply_enabled: true,
620 poll_interval_seconds: default_poll_interval(),
621 mark_seen: true,
622 max_body_chars: default_max_body_chars(),
623 subject_prefix: default_subject_prefix(),
624 allow_from: Vec::new(),
625 }
626 }
627}
628
629#[derive(Debug, Clone, Serialize, Deserialize, Default)]
631pub struct QQConfig {
632 #[serde(default)]
634 pub enabled: bool,
635
636 #[serde(default, alias = "appId")]
638 pub app_id: String,
639
640 #[serde(default)]
642 pub secret: SecretString,
643
644 #[serde(default, alias = "allowFrom")]
646 pub allow_from: Vec<String>,
647}