matrix-rust-sdk/matrix_sdk/examples/image_bot.rs
Damir Jelić 137fa9619f matrix-sdk: Add the ability to stop the sync loop and rename the sync methods.
This renames our sync methods so it's clearer which one the main one is.
Syncing should be done with the sync method, if one wishes to sync only
once the sync_method is provided.

If one wishes to have a callback called with every sync the
sync_with_callback method exists, the callback now returns a boolean
that signals if the loop should be aborted. This does not mean that the
current sync request will abort, a cancelable future is still needed for
this.
2020-10-06 11:37:29 +02:00

123 lines
3.3 KiB
Rust

use std::{
env,
fs::File,
io::{Seek, SeekFrom},
path::PathBuf,
process::exit,
sync::Arc,
};
use tokio::sync::Mutex;
use matrix_sdk::{
self,
events::{
room::message::{MessageEventContent, TextMessageEventContent},
SyncMessageEvent,
},
Client, ClientConfig, EventEmitter, SyncRoom, SyncSettings,
};
use matrix_sdk_common_macros::async_trait;
use url::Url;
struct ImageBot {
client: Client,
image: Arc<Mutex<File>>,
}
impl ImageBot {
pub fn new(client: Client, image: File) -> Self {
let image = Arc::new(Mutex::new(image));
Self { client, image }
}
}
#[async_trait]
impl EventEmitter for ImageBot {
async fn on_room_message(&self, room: SyncRoom, event: &SyncMessageEvent<MessageEventContent>) {
if let SyncRoom::Joined(room) = room {
let msg_body = if let SyncMessageEvent {
content: MessageEventContent::Text(TextMessageEventContent { body: msg_body, .. }),
..
} = event
{
msg_body
} else {
return;
};
if msg_body.contains("!image") {
let room_id = room.read().await.room_id.clone();
println!("sending image");
let mut image = self.image.lock().await;
self.client
.room_send_attachment(&room_id, "cat", "image/jpg", &mut *image, None)
.await
.unwrap();
image.seek(SeekFrom::Start(0)).unwrap();
println!("message sent");
}
}
}
}
async fn login_and_sync(
homeserver_url: String,
username: String,
password: String,
image: File,
) -> Result<(), matrix_sdk::Error> {
let client_config = ClientConfig::new()
.proxy("http://localhost:8080")?
.disable_ssl_verification();
let homeserver_url = Url::parse(&homeserver_url).expect("Couldn't parse the homeserver URL");
let mut client = Client::new_with_config(homeserver_url, client_config).unwrap();
client
.login(&username, &password, None, Some("command bot"))
.await?;
client.sync_once(SyncSettings::default()).await.unwrap();
client
.add_event_emitter(Box::new(ImageBot::new(client.clone(), image)))
.await;
let settings = SyncSettings::default().token(client.sync_token().await.unwrap());
client.sync(settings).await;
Ok(())
}
#[tokio::main]
async fn main() -> Result<(), matrix_sdk::Error> {
tracing_subscriber::fmt::init();
let (homeserver_url, username, password, image_path) = match (
env::args().nth(1),
env::args().nth(2),
env::args().nth(3),
env::args().nth(4),
) {
(Some(a), Some(b), Some(c), Some(d)) => (a, b, c, d),
_ => {
eprintln!(
"Usage: {} <homeserver_url> <username> <password> <image>",
env::args().next().unwrap()
);
exit(1)
}
};
println!(
"helloooo {} {} {} {:#?}",
homeserver_url, username, password, image_path
);
let path = PathBuf::from(image_path);
let image = File::open(path).expect("Can't open image file.");
login_and_sync(homeserver_url, username, password, image).await?;
Ok(())
}