133 lines
5.1 KiB
Rust
133 lines
5.1 KiB
Rust
|
use matrix_sdk::{Client, ruma::{UserId, RoomId, events::{room::message::RoomMessageEventContent}}, Session, room::Room, config::SyncSettings};
|
||
|
use postbus::command::Mailbox;
|
||
|
use crate::config::{Mapping, Config};
|
||
|
|
||
|
pub async fn get_clients(config: &mut Config) -> Vec<Client> {
|
||
|
let mut clients: Vec<Client> = vec![];
|
||
|
|
||
|
// Try to build a matrix_sdk::Client object for each configured client
|
||
|
for conf in &mut config.clients {
|
||
|
let user_id = match UserId::parse(&conf.mxid) {
|
||
|
Ok(id) => id,
|
||
|
Err(_e) => continue,
|
||
|
};
|
||
|
let client = match Client::builder().user_id(&user_id).build().await {
|
||
|
Ok(c) => c,
|
||
|
Err(_e) => continue,
|
||
|
};
|
||
|
// Attempt to restore a previous login
|
||
|
if let Some(token) = &conf.access_token {
|
||
|
if let Some(dev_id) = &conf.device_id {
|
||
|
match client.restore_login(Session { access_token: token.to_string(), user_id: (&user_id).to_owned(), device_id: dev_id.as_str().into()}).await {
|
||
|
Ok(_) => (),
|
||
|
Err(_e) => continue,
|
||
|
};
|
||
|
}
|
||
|
}
|
||
|
// If login restoration did not work, log in using the password
|
||
|
if !client.logged_in().await {
|
||
|
match conf.password.len() {
|
||
|
0 => continue,
|
||
|
_ => match client.login(
|
||
|
user_id,
|
||
|
&conf.password,
|
||
|
(&conf).device_id.as_deref(),
|
||
|
Some("matrixmailer")
|
||
|
).await {
|
||
|
Ok(_) => (),
|
||
|
Err(_) => continue,
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
clients.push(client.clone());
|
||
|
}
|
||
|
|
||
|
clients
|
||
|
}
|
||
|
|
||
|
async fn client_from_mxid(mxid: &str, clients: &Vec<Client>) -> Option<Client> {
|
||
|
for client in clients {
|
||
|
if client.user_id().await.unwrap().as_str() == mxid {
|
||
|
return Some(client.to_owned());
|
||
|
}
|
||
|
}
|
||
|
None
|
||
|
}
|
||
|
|
||
|
pub async fn send(from_mail: &Option<Mailbox>, recipient: &Mailbox, content: &str, clients: &Vec<Client>, mappings: &Vec<Mapping>) {
|
||
|
for mapping in mappings {
|
||
|
let mut applies = true;
|
||
|
|
||
|
if let Some(from) = &mapping.from {
|
||
|
if let Some(mailbox) = from_mail {
|
||
|
if from != &format!("{}@{}", mailbox.local, mailbox.domain.0) {
|
||
|
applies = false;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if let Some(to) = &mapping.to {
|
||
|
if to != &format!("{}@{}", recipient.local, recipient.domain.0) {
|
||
|
applies = false;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if applies {
|
||
|
let local = &recipient.local;
|
||
|
let domain = &recipient.domain.0;
|
||
|
let sender_mxid = match &mapping.mxid_sender {
|
||
|
Some(s) => s.to_owned(),
|
||
|
None => {
|
||
|
format!("@{}:{}", local, domain)
|
||
|
},
|
||
|
};
|
||
|
if let Some(c) = client_from_mxid(&sender_mxid, clients).await {
|
||
|
if let Ok(roomid) = RoomId::parse(&mapping.room_id) {
|
||
|
match c.sync_once(SyncSettings::default()).await {
|
||
|
Ok(_) => (),
|
||
|
Err(_e) => (),
|
||
|
};
|
||
|
|
||
|
let room = match c.get_room(&roomid) {
|
||
|
Some(Room::Joined(room)) => room,
|
||
|
Some(Room::Invited(room)) => {
|
||
|
match room.accept_invitation().await {
|
||
|
Ok(_) => (),
|
||
|
Err(_e) => println!("Could not accept invitation"),
|
||
|
};
|
||
|
// Continuously check whether the room has been joined.
|
||
|
// Joins can be significantly delayed, depending on the room and the server
|
||
|
let mut joined = false;
|
||
|
while !joined {
|
||
|
match c.get_room(&roomid) {
|
||
|
Some(Room::Joined(_)) => joined = true,
|
||
|
_ => (),
|
||
|
}
|
||
|
match c.sync_once(SyncSettings::default()).await {
|
||
|
Ok(_) => (),
|
||
|
Err(_e) => (),
|
||
|
};
|
||
|
std::thread::sleep(std::time::Duration::from_millis(250));
|
||
|
}
|
||
|
if let Some(Room::Joined(joined)) = c.get_room(&roomid) {
|
||
|
joined
|
||
|
}
|
||
|
else {
|
||
|
continue;
|
||
|
}
|
||
|
},
|
||
|
_ => {
|
||
|
println!("Room either left or unfound.");
|
||
|
continue;
|
||
|
}
|
||
|
};
|
||
|
match room.send(RoomMessageEventContent::text_html(content, content), None).await {
|
||
|
Ok(_) => (),
|
||
|
Err(_e) => println!("Sending message failed"),
|
||
|
};
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|