use serde::Deserialize;
use crate::ops::check::Result;
use crate::ops::check::output::{
DEFAULT_MESSAGE_TEMPLATE, TableFormat, render_message, should_skip_empty,
};
use crate::ops::check::{Options, VersionedSource};
#[derive(Debug, Clone, PartialEq, Deserialize)]
pub struct OutputConfig {
pub user_id: String,
pub password: String,
pub room_id: String,
pub message_template: Option<String>,
pub send_empty: Option<bool>,
}
pub async fn output_element(
opts: &Options,
sources: &[VersionedSource],
config: &OutputConfig,
) -> Result<()> {
if should_skip_empty(config.send_empty, sources) {
println!("No updates, no message has been sent.");
return Ok(());
}
let msg = render_message(
opts,
sources,
config
.message_template
.as_deref()
.unwrap_or(DEFAULT_MESSAGE_TEMPLATE),
TableFormat::Html,
)?;
send_message(opts, config, msg).await?;
Ok(())
}
async fn send_message(_opts: &Options, config: &OutputConfig, msg: impl AsRef<str>) -> Result<()> {
use crate::Error;
use matrix_sdk::{
Client,
config::SyncSettings,
ruma::{RoomId, UserId, events::room::message::RoomMessageEventContent},
};
let user: &UserId = config
.user_id
.as_str()
.try_into()
.map_err(|err| Error::InvalidUserId {
user_id: config.user_id.clone(),
err,
})?;
let client = Client::builder()
.server_name(user.server_name())
.build()
.await?;
client
.matrix_auth()
.login_username(user, &config.password)
.send()
.await
.map_err(|err| Error::NonMatchingUserIdPassword {
user_id: config.user_id.clone(),
err,
})?;
let room_id: &RoomId =
config
.room_id
.as_str()
.try_into()
.map_err(|err| Error::InvalidRoomId {
room_id: config.room_id.clone(),
err,
})?;
client
.join_room_by_id(room_id)
.await
.map_err(|err| Error::ImpossibleToJoinRoom {
room_id: config.room_id.clone(),
err,
})?;
client.sync_once(SyncSettings::default()).await?;
let room = client
.get_room(room_id)
.ok_or(Error::ImpossibleToGetRoom(room_id.to_string()))?;
let content = RoomMessageEventContent::text_markdown(msg.as_ref());
room.send(content).await?;
client.matrix_auth().logout().await?;
Ok(())
}