mirror of
https://github.com/t2linux/matrix-bot.git
synced 2026-08-16 05:18:05 -07:00
feat: some fixes, features, and README
This commit is contained in:
@@ -1,3 +1,4 @@
|
||||
MATRIX_HOMESERVER=https://matrix.org
|
||||
MATRIX_USERNAME=your_username
|
||||
MATRIX_PASSWORD=your_password
|
||||
IGNORE_BRIDGE_USERS=false
|
||||
|
||||
@@ -0,0 +1,42 @@
|
||||
# Matrix Wiki Link Bot
|
||||
|
||||
A simple Matrix bot that listens for commands starting with `.wiki` and responds with links from a configured JSON store.
|
||||
|
||||
## Configuration
|
||||
|
||||
The bot is configured via environment variables.
|
||||
|
||||
| Variable | Description | Default |
|
||||
|----------|-------------|---------|
|
||||
| `MATRIX_HOMESERVER` | The URL of your Matrix homeserver (e.g., `https://matrix.org`). | |
|
||||
| `MATRIX_USERNAME` | The bot's Matrix username. | |
|
||||
| `MATRIX_PASSWORD` | The bot's Matrix password. | |
|
||||
| `IGNORE_BRIDGE_USERS`| If set to `true`, the bot will ignore messages from senders whose MXID starts with `@discord_`. | `false` |
|
||||
|
||||
## Usage
|
||||
|
||||
### Docker
|
||||
|
||||
1. Copy `docker-compose.example.yml` to `docker-compose.yml` and `links.json` to a local file.
|
||||
2. Update the environment variables in `docker-compose.yml`.
|
||||
3. Populate `links.json` with your key-value pairs.
|
||||
4. Run the bot:
|
||||
|
||||
```bash
|
||||
docker-compose up -d
|
||||
```
|
||||
|
||||
### Local Development
|
||||
|
||||
1. Copy `.env.example` to `.env`.
|
||||
2. Update `.env` with your credentials.
|
||||
3. Run the bot:
|
||||
|
||||
```bash
|
||||
cargo run
|
||||
```
|
||||
|
||||
## Commands
|
||||
|
||||
- `.wiki list`: Lists all available wiki keys.
|
||||
- `.wiki <term>`: Fetches the link associated with `<term>` from the `links.json` file.
|
||||
@@ -5,6 +5,7 @@ services:
|
||||
- MATRIX_HOMESERVER=https://matrix.org
|
||||
- MATRIX_USERNAME=your_username
|
||||
- MATRIX_PASSWORD=your_password
|
||||
- IGNORE_BRIDGE_USERS=false
|
||||
volumes:
|
||||
- ./links.json:/usr/local/bin/links.json
|
||||
restart: unless-stopped
|
||||
|
||||
@@ -17,6 +17,12 @@ impl LinkStore {
|
||||
pub fn get(&self, key: &str) -> Option<&String> {
|
||||
self.links.get(key)
|
||||
}
|
||||
|
||||
pub fn list_keys(&self) -> Vec<String> {
|
||||
let mut keys: Vec<String> = self.links.keys().cloned().collect();
|
||||
keys.sort();
|
||||
keys
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
|
||||
+40
-5
@@ -37,20 +37,55 @@ async fn main() -> Result<()> {
|
||||
|
||||
client.matrix_auth().login_username(&username, &password).await?;
|
||||
|
||||
let ignore_bridge_users = env::var("IGNORE_BRIDGE_USERS")
|
||||
.map(|v| v.to_lowercase() == "true")
|
||||
.unwrap_or(false);
|
||||
|
||||
let start_time = std::time::SystemTime::now()
|
||||
.duration_since(std::time::UNIX_EPOCH)
|
||||
.expect("Time went backwards")
|
||||
.as_millis() as u64;
|
||||
|
||||
// Share link_store with event handler
|
||||
let store_clone = link_store.clone();
|
||||
|
||||
client.add_event_handler(move |event: OriginalSyncRoomMessageEvent, room: Room| {
|
||||
let store = store_clone.clone();
|
||||
async move {
|
||||
let sender = event.sender.as_str();
|
||||
if ignore_bridge_users && sender.starts_with("@discord_") {
|
||||
return;
|
||||
}
|
||||
|
||||
if u64::from(event.origin_server_ts.get()) < start_time {
|
||||
return;
|
||||
}
|
||||
|
||||
let RoomMessageEventContent { msgtype, .. } = event.content;
|
||||
|
||||
if let MessageType::Text(text_content) = msgtype {
|
||||
let body = text_content.body;
|
||||
if body.starts_with(".wiki ") {
|
||||
let argument = body.trim_start_matches(".wiki ").trim();
|
||||
if let Some(link) = store.get(argument) {
|
||||
let response = format!("Link for {}: {}", argument, link);
|
||||
if body == ".wiki" || body.starts_with(".wiki ") {
|
||||
let argument = body.trim_start_matches(".wiki").trim();
|
||||
if argument.is_empty() {
|
||||
let response = "Use .wiki list to print all available links";
|
||||
let content = RoomMessageEventContent::text_plain(response);
|
||||
if let Err(e) = room.send(content).await {
|
||||
eprintln!("Failed to send message: {}", e);
|
||||
}
|
||||
} else if argument == "list" {
|
||||
let keys = store.list_keys();
|
||||
let response = if keys.is_empty() {
|
||||
"No wiki links available.".to_string()
|
||||
} else {
|
||||
format!("Available wiki links: {}", keys.join(", "))
|
||||
};
|
||||
let content = RoomMessageEventContent::text_plain(response);
|
||||
if let Err(e) = room.send(content).await {
|
||||
eprintln!("Failed to send message: {}", e);
|
||||
}
|
||||
} else if let Some(link) = store.get(argument) {
|
||||
let response = format!("Link for {}: {}\n(Use .wiki list to print all available links)", argument, link);
|
||||
// Send response
|
||||
let content = RoomMessageEventContent::text_plain(response);
|
||||
if let Err(e) = room.send(content).await {
|
||||
@@ -58,7 +93,7 @@ async fn main() -> Result<()> {
|
||||
}
|
||||
} else {
|
||||
// Optional: reply not found, or just ignore
|
||||
let response = format!("No wiki link found for '{}'", argument);
|
||||
let response = format!("No wiki link found for '{}'\n(Use .wiki list to print all available links)", argument);
|
||||
let content = RoomMessageEventContent::text_plain(response);
|
||||
if let Err(e) = room.send(content).await {
|
||||
eprintln!("Failed to send message: {}", e);
|
||||
|
||||
Reference in New Issue
Block a user