Completed logic to login bot

main
David 2022-12-10 21:31:02 +01:00
parent 4aa0de124d
commit 96372b83fd
4 changed files with 120 additions and 47 deletions

View File

@ -1,68 +1,120 @@
#[allow(clippy::module_inception)]
pub mod bot {
use crate::config_reader::config_reader::BotUserCreds;
use anyhow;
use log::info;
use crate::{config_reader::config_reader::BotUserInfo, utils};
use log::{info, debug};
use matrix_sdk::{
config::SyncSettings,
config::{SyncSettings, RequestConfig},
event_handler::Ctx,
room::{Joined, Room, RoomMember},
ruma::{
events::room::message::SyncRoomMessageEvent, user_id, OriginalSyncRoomMessageEvent,
UserId, ServerName,
events::room::message::{OriginalSyncRoomMessageEvent,
RoomMessageEventContent},
user_id, RoomId,
},
Client,
};
use crate::utils::utils::*;
#[allow(dead_code)]
#[derive(Clone)]
pub struct Bot {
client: Client,
joined_room: Joined,
}
pub async fn bot_login(creds: BotUserCreds) -> anyhow::Result<Bot> {
let user_id = creds.user_id.as_str();
let password = creds.password.as_str();
let homeserver = creds.homeserver.as_str();
let client = Client::builder().homeserver_url(homeserver).build().await?;
impl Bot {
pub async fn bot_login(creds: BotUserInfo) {
let user_id = creds.user_id.as_str();
let password = creds.password.as_str();
// let homeserver = creds.homeserver.as_str();
let room = RoomId::parse(creds.room.as_str()).unwrap();
// let client = Client::builder().homeserver_url(homeserver).build().await.unwrap();
info!("Logging in…");
let response = client
.login_username(user_id, password)
.initial_device_display_name("matrix-modbot")
.send()
.await
.expect("Unable to login");
let user = UserId::parse(user_id).expect("Unable to parse bot user id");
let server_name = ServerName::parse(user.server_name()).unwrap();
let request_config = RequestConfig::new().force_auth();
let client = Client::builder()
.server_name(&server_name)
.request_config(request_config)
.build()
.await.
unwrap();
info!("Doing the initial sync…");
client
.sync_once(SyncSettings::new())
.await
.expect("Unable to sync");
info!("Logging in…");
let response = client
.login_username(user.localpart(), password)
.initial_device_display_name("Matrix-Modbot")
.send()
.await
.expect("Unable to login");
info!(
"Logged in as {}, got device_id {}",
response.user_id, response.device_id
);
info!("Doing the initial sync…");
client
.sync_once(SyncSettings::new())
.await
.expect("Unable to sync");
Ok(Bot { client })
}
pub async fn message_handler(bot: Bot) {
// Setup event handlers
// bot.client.add_event_handler(on_room_message);
// bot.client.add_event_handler(on_room_reaction);
// bot.client.add_event_handler(on_room_redaction);
}
info!(
"Logged in as {}, got device_id {}",
response.user_id, response.device_id
);
async fn on_room_message(event: OriginalSyncRoomMessageEvent, room: Room, Ctx(bot): Ctx<Bot>) {
if let Room::Joined(_joined) = &room {
// Standard text message
if let Some(text) = utils::get_message_event_text(&event) {
let member = room.get_member(&event.sender).await.unwrap().unwrap();
let id = &event.event_id;
// Code snippet from hebbot https://github.com/haecker-felix/hebbot
// Try to accept room invite, if any
if let Some(invited_room) = client.get_invited_room(&room) {
invited_room
.accept_invitation()
.await
.expect("Matrix-Modbot could not join the invited room");
}
// Need to do another sync to make sure bot knows the newly joined rooms
client
.sync_once(SyncSettings::new())
.await
.expect("Unable to sync");
let joined_room = client
.get_joined_room(&room)
.expect("Cannot get joined room");
let bot = Bot {
client,
joined_room
};
bot.send_message("Sucessfully started Matrix-Modbot").await;
bot.client.add_event_handler_context(bot.clone());
bot.client.add_event_handler(Self::on_room_message);
info!("Started syncing");
bot.client.sync(SyncSettings::new()).await.unwrap();
}
pub async fn on_room_message(event: OriginalSyncRoomMessageEvent,
room: Room, Ctx(bot): Ctx<Bot>) {
if let Room::Joined(_joined) = &room {
// Standard text message
if let Some(text) = get_message_event_text(&event) {
let member = room.get_member(&event.sender).await.unwrap().unwrap();
let id = &event.event_id;
}
// Message edit
if let Some((edited_msg_event_id, text)) = get_edited_message_event_text(&event) {}
}
}
pub async fn send_message(&self, message: &str) {
debug!("Send message ({:?}): {}", &self.joined_room, message);
let content = RoomMessageEventContent::text_plain(message);
&self.joined_room.send(content, None)
.await
.expect("Unable to send message");
}
}
pub async fn on_room_reaction() {}
pub async fn on_room_redaction() {}
}

View File

@ -5,23 +5,26 @@ pub mod config_reader {
#[derive(Debug)]
#[allow(dead_code)]
pub struct BotUserCreds {
pub struct BotUserInfo {
pub user_id: String,
pub password: String,
pub homeserver: String,
pub room: String
}
impl BotUserCreds {
pub fn new(config_file_path: &str) -> Result<Self, Box<dyn Error>> {
impl BotUserInfo {
pub fn get_info(config_file_path: &str) -> Result<Self, Box<dyn Error>> {
let mut config = Ini::new();
let _map = config.load(config_file_path)?;
let user_id = config.get("credentials", "user_id").unwrap();
let password = config.get("credentials", "password").unwrap();
let homeserver = config.get("credentials", "homeserver").unwrap();
Ok(BotUserCreds {
let room = config.get("room", "room").unwrap();
Ok(BotUserInfo {
user_id,
password,
homeserver,
room
})
}
}

View File

@ -1,8 +1,10 @@
// Snippet from https://github.com/haecker-felix/hebbot, licensed under AGPL, License terms apply
#[allow(clippy::module_inception)]
pub mod utils {
use matrix_sdk::ruma::events::room::message::{
MessageType, OriginalSyncRoomMessageEvent, TextMessageEventContent,
MessageType, OriginalSyncRoomMessageEvent, TextMessageEventContent, Relation,
};
use matrix_sdk::ruma::OwnedEventId;
pub fn get_message_event_text(event: &OriginalSyncRoomMessageEvent) -> Option<String> {
if let MessageType::Text(TextMessageEventContent { body, .. }) = &event.content.msgtype {
@ -11,4 +13,17 @@ pub mod utils {
None
}
}
// A simplified way of getting an edited message
pub fn get_edited_message_event_text(
event: &OriginalSyncRoomMessageEvent,
) -> Option<(OwnedEventId, String)> {
if let Some(Relation::Replacement(r)) = &event.content.relates_to {
if let MessageType::Text(TextMessageEventContent { body, .. }) = &r.new_content.msgtype {
return Some((r.event_id.clone(), body.to_owned()));
}
}
None
}
}

View File

@ -2,3 +2,6 @@
user_id = john
homeserver = http://example.com
password = correcthorsebatterystaple
[room]
room = general