rustant_core/channels/
mod.rs1pub mod agent_bridge;
8pub mod auto_reply;
9pub mod digest;
10pub mod discord;
11pub mod email;
12pub mod email_intelligence;
13pub mod imessage;
14pub mod intelligence;
15pub mod irc;
16pub mod manager;
17pub mod matrix;
18pub mod normalize;
19pub mod routing;
20pub mod scheduler_bridge;
21pub mod signal;
22pub mod slack;
23pub mod sms;
24pub mod teams;
25pub mod telegram;
26pub mod types;
27pub mod webchat;
28pub mod webhook;
29pub mod whatsapp;
30
31pub mod cdc;
32pub mod style_tracker;
33
34pub use agent_bridge::ChannelAgentBridge;
35pub use auto_reply::{AutoReplyEngine, PendingReply, ReplyStatus};
36pub use digest::{ChannelDigest, DigestActionItem, DigestCollector, DigestHighlight};
37pub use email_intelligence::{
38 EmailCategory, EmailClassification, EmailIntelligence, SenderProfile,
39};
40pub use imessage::{IMessageChannel, IMessageConfig, ResolvedContact};
41pub use intelligence::{
42 ClassificationCache, ClassifiedMessage, IntelligenceResult, LlmClassificationResponse,
43 MessageClassifier, MessageType, SuggestedAction,
44};
45pub use irc::{IrcChannel, IrcConfig};
46pub use manager::{ChannelManager, build_channel_manager};
47pub use normalize::MessageNormalizer;
48pub use routing::{ChannelRouter, RoutingCondition, RoutingRule};
49pub use scheduler_bridge::{FollowUpReminder, ReminderStatus, SchedulerBridge};
50pub use sms::{SmsChannel, SmsConfig};
51pub use teams::{TeamsChannel, TeamsConfig};
52pub use types::{
53 ChannelCapabilities, ChannelMessage, ChannelStatus, ChannelType, ChannelUser, MessageContent,
54 MessageId, StreamingMode, ThreadId,
55};
56pub use webhook::{WebhookChannel, WebhookConfig};
57
58pub use cdc::{CdcAction, CdcConfig, CdcProcessor, CdcState};
59pub use style_tracker::{CommunicationStyleTracker, SenderStyleProfile};
60
61use crate::error::RustantError;
62use async_trait::async_trait;
63
64#[async_trait]
66pub trait Channel: Send + Sync {
67 fn name(&self) -> &str;
69
70 fn channel_type(&self) -> ChannelType;
72
73 async fn connect(&mut self) -> Result<(), RustantError>;
75
76 async fn disconnect(&mut self) -> Result<(), RustantError>;
78
79 async fn send_message(&self, msg: ChannelMessage) -> Result<MessageId, RustantError>;
81
82 async fn receive_messages(&self) -> Result<Vec<ChannelMessage>, RustantError>;
84
85 fn status(&self) -> ChannelStatus;
87
88 fn is_connected(&self) -> bool {
90 self.status() == ChannelStatus::Connected
91 }
92
93 fn capabilities(&self) -> ChannelCapabilities {
95 ChannelCapabilities::default()
96 }
97
98 fn streaming_mode(&self) -> StreamingMode {
100 StreamingMode::default()
101 }
102
103 async fn receive_messages_since(
106 &self,
107 _cursor: Option<&str>,
108 ) -> Result<(Vec<ChannelMessage>, Option<String>), RustantError> {
109 let msgs = self.receive_messages().await?;
110 Ok((msgs, None))
111 }
112}
113
114#[cfg(test)]
115mod tests {
116 use super::*;
117
118 #[test]
119 fn test_channel_type_reexported() {
120 let _ = ChannelType::Telegram;
121 let _ = ChannelStatus::Connected;
122 }
123
124 struct DefaultTestChannel;
126
127 #[async_trait]
128 impl Channel for DefaultTestChannel {
129 fn name(&self) -> &str {
130 "default-test"
131 }
132 fn channel_type(&self) -> ChannelType {
133 ChannelType::WebChat
134 }
135 async fn connect(&mut self) -> Result<(), RustantError> {
136 Ok(())
137 }
138 async fn disconnect(&mut self) -> Result<(), RustantError> {
139 Ok(())
140 }
141 async fn send_message(&self, _msg: ChannelMessage) -> Result<MessageId, RustantError> {
142 Ok(MessageId::new("test"))
143 }
144 async fn receive_messages(&self) -> Result<Vec<ChannelMessage>, RustantError> {
145 Ok(Vec::new())
146 }
147 fn status(&self) -> ChannelStatus {
148 ChannelStatus::Disconnected
149 }
150 }
151
152 #[test]
153 fn test_default_capabilities() {
154 let ch = DefaultTestChannel;
155 let caps = ch.capabilities();
156 assert!(!caps.supports_threads);
157 assert!(!caps.supports_reactions);
158 assert!(!caps.supports_files);
159 assert!(!caps.supports_voice);
160 assert!(!caps.supports_video);
161 assert!(caps.max_message_length.is_none());
162 assert!(!caps.supports_editing);
163 assert!(!caps.supports_deletion);
164 }
165
166 #[test]
167 fn test_default_streaming_mode() {
168 let ch = DefaultTestChannel;
169 assert_eq!(
170 ch.streaming_mode(),
171 StreamingMode::Polling { interval_ms: 5000 }
172 );
173 }
174}