Skip to main content

botkit_matrix/
config.rs

1use std::path::PathBuf;
2
3use matrix_sdk::ruma::{OwnedDeviceId, OwnedUserId};
4
5/// Matrix bot configuration
6///
7/// Configure the homeserver, authentication, command prefix, and other options.
8///
9/// # Example
10/// ```ignore
11/// let config = MatrixConfig::new("https://matrix.org")
12///     .password_auth("@bot:matrix.org", "password")
13///     .command_prefix("!")
14///     .auto_join_rooms(true);
15/// ```
16pub struct MatrixConfig {
17    /// Homeserver URL (e.g., "https://matrix.org")
18    pub(crate) homeserver_url: String,
19
20    /// Authentication method
21    pub(crate) auth: MatrixAuth,
22
23    /// Command prefix for parsing commands from messages (default: "!")
24    pub(crate) command_prefix: String,
25
26    /// Device display name for this bot session
27    pub(crate) device_name: Option<String>,
28
29    /// State store path for persistence (enables session restore and E2EE key storage)
30    pub(crate) state_store_path: Option<PathBuf>,
31
32    /// Whether to auto-join rooms when invited
33    pub(crate) auto_join_rooms: bool,
34}
35
36/// Authentication options for Matrix
37pub enum MatrixAuth {
38    /// Username and password login
39    Password {
40        /// Matrix user ID (e.g., "@bot:matrix.org")
41        user_id: String,
42        /// Password
43        password: String,
44    },
45    /// Access token (for pre-authenticated sessions)
46    AccessToken {
47        /// Matrix user ID
48        user_id: OwnedUserId,
49        /// Access token
50        access_token: String,
51        /// Device ID (required for E2EE)
52        device_id: OwnedDeviceId,
53    },
54}
55
56impl MatrixConfig {
57    /// Create a new Matrix configuration with the given homeserver URL
58    ///
59    /// Authentication must be configured before building the bot.
60    pub fn new(homeserver_url: impl Into<String>) -> Self {
61        Self {
62            homeserver_url: homeserver_url.into(),
63            auth: MatrixAuth::Password {
64                user_id: String::new(),
65                password: String::new(),
66            },
67            command_prefix: "!".to_string(),
68            device_name: None,
69            state_store_path: None,
70            auto_join_rooms: false,
71        }
72    }
73
74    /// Set password authentication
75    ///
76    /// # Arguments
77    /// * `user_id` - Matrix user ID (e.g., "@bot:matrix.org")
78    /// * `password` - Password for the account
79    pub fn password_auth(
80        mut self,
81        user_id: impl Into<String>,
82        password: impl Into<String>,
83    ) -> Self {
84        self.auth = MatrixAuth::Password {
85            user_id: user_id.into(),
86            password: password.into(),
87        };
88        self
89    }
90
91    /// Set access token authentication
92    ///
93    /// Use this for pre-authenticated sessions. Requires the device ID for E2EE.
94    pub fn access_token_auth(
95        mut self,
96        user_id: OwnedUserId,
97        access_token: impl Into<String>,
98        device_id: OwnedDeviceId,
99    ) -> Self {
100        self.auth = MatrixAuth::AccessToken {
101            user_id,
102            access_token: access_token.into(),
103            device_id,
104        };
105        self
106    }
107
108    /// Set the command prefix (default: "!")
109    ///
110    /// Messages starting with this prefix will be parsed as commands.
111    pub fn command_prefix(mut self, prefix: impl Into<String>) -> Self {
112        self.command_prefix = prefix.into();
113        self
114    }
115
116    /// Set the device display name
117    ///
118    /// This appears in the user's device list.
119    pub fn device_name(mut self, name: impl Into<String>) -> Self {
120        self.device_name = Some(name.into());
121        self
122    }
123
124    /// Set the state store path for persistence
125    ///
126    /// Enables session persistence and E2EE key storage.
127    /// Without this, E2EE keys are lost on restart.
128    pub fn state_store_path(mut self, path: impl Into<PathBuf>) -> Self {
129        self.state_store_path = Some(path.into());
130        self
131    }
132
133    /// Enable or disable auto-joining rooms when invited
134    pub fn auto_join_rooms(mut self, enabled: bool) -> Self {
135        self.auto_join_rooms = enabled;
136        self
137    }
138}