Compare commits

...

6 commits

Author SHA1 Message Date
d4bb9c20b5
Merge branch 'bugfixes' into 'master'
This merge fixes issues #12 and #13 as well as refactoring the embed generation
code and cleaning up embed outputs in chat to make them slightly less
disruptive to the flow of conversations.
2023-10-08 14:06:32 +10:00
1783ed00e6
Clean up & refactor embed output code 2023-10-08 14:04:23 +10:00
da62c7c2c6
Refactor metadata parsing to avoid repetition 2023-10-08 12:43:03 +10:00
4f5e01802f
Fix bug that broke partial metadata parsing 2023-10-08 04:06:25 +10:00
7d379448ff
Run rustfmt 2023-10-08 03:52:21 +10:00
df7b01b5c1
Fix issues #12 and #13 2023-10-08 03:51:36 +10:00
3 changed files with 49 additions and 25 deletions

View file

@ -1,6 +1,6 @@
[package] [package]
name = "frogbot" name = "frogbot"
version = "0.1.0" version = "0.1.1"
edition = "2021" edition = "2021"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

View file

@ -15,6 +15,7 @@ use regex::Regex;
use scraper::{Html, Selector}; use scraper::{Html, Selector};
/// Represents an Embed in the chat /// Represents an Embed in the chat
#[derive(Default)]
pub struct Embed { pub struct Embed {
/// The title of the embed /// The title of the embed
pub title: String, pub title: String,
@ -30,7 +31,7 @@ impl Embed {
} }
/// Scrapes the HTML of a webpage and generates an [`Embed`] with the scraped information. /// Scrapes the HTML of a webpage and generates an [`Embed`] with the scraped information.
pub fn parse_metadata(page: &str) -> Embed { pub fn parse_metadata(page: &str) -> Option<Embed> {
let doc_body = Html::parse_document(page); let doc_body = Html::parse_document(page);
// Selectors used to get metadata are defined here // Selectors used to get metadata are defined here
@ -44,6 +45,11 @@ pub fn parse_metadata(page: &str) -> Embed {
let mut meta_title = String::default(); let mut meta_title = String::default();
let mut meta_description = String::default(); let mut meta_description = String::default();
if let (None, None) = (title, desc) {
warn!("Couldn't parse any metadata for URL");
return None;
}
if let Some(title) = title { if let Some(title) = title {
meta_title = title.text().collect(); meta_title = title.text().collect();
} else { } else {
@ -56,7 +62,7 @@ pub fn parse_metadata(page: &str) -> Embed {
warn!("Failed to parse description HTML"); warn!("Failed to parse description HTML");
} }
Embed::new(meta_title, meta_description) Some(Embed::new(meta_title, meta_description))
} }
/// Check if the message has any urls in it and get them if it does /// Check if the message has any urls in it and get them if it does
@ -119,40 +125,52 @@ pub async fn embed_handler(event: OriginalSyncRoomMessageEvent, room: Room, clie
let urls = get_urls_from_message(&text_content.body); let urls = get_urls_from_message(&text_content.body);
let reqwest_client = reqwest::Client::builder().user_agent("Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/109.0.0.0 Safari/537.36").build().unwrap(); let reqwest_client = reqwest::Client::builder().user_agent("Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/118.0.0.0 Safari/537.36").build().unwrap();
for url in urls { for url in urls {
if let Ok(req) = reqwest_client.get(url).send().await { if let Ok(req) = reqwest_client.get(url).send().await {
if let Ok(res) = req.text().await { if let Ok(res) = req.text().await {
// beware, dirty HTML parsing code // beware, dirty HTML parsing code
let embed = parse_metadata(&res); let metadata = parse_metadata(&res);
// Build our message reply // Build and send our message reply
let bot_reply = RoomMessageEventContent::text_html( if metadata.is_some() {
&embed.title, let embed = metadata.unwrap();
format!( let bot_reply = RoomMessageEventContent::text_html(
r#" &embed.title,
<blockquote> format!(
<h6><a href="{}">{}</a></h6> "<blockquote>
<h3><strong>{}</strong></h3> <h4>{}</h4>
<p>{}</p> <p>{}</p>
</blockquote> </blockquote>",
"#, &embed.title, &embed.description
&url, &url, &embed.title, &embed.description ),
), )
) .make_reply_to(&full_reply_event);
.make_reply_to(&full_reply_event);
// Finally send the reply to the room // Finally send the reply to the room
warn!("Sending embed for URL: '{}'", &url); warn!("Sending embed for URL: '{}'", &url);
if room.send(bot_reply, None).await.is_err() { if room.send(bot_reply, None).await.is_err() {
warn!("Failed to send embed for URL: '{}'", &url); warn!("Failed to send embed for URL: '{}'", &url);
}
// If we didn't get any metadata send a generic "No metadata" response
} else {
let bot_reply = RoomMessageEventContent::text_html(
"Couldn't parse metadata for URL",
"<blockquote><h5>Couldn't parse metadata for URL</h5></blockquote>",
)
.make_reply_to(&full_reply_event);
// Send the reply to the room
warn!("Sending 'No metadata' embed for URL: '{}'", &url);
if room.send(bot_reply, None).await.is_err() {
warn!("Failed to send embed for URL: '{}'", &url);
}
} }
} else { } else {
warn!("Failed to parse HTML for URL: '{}'", &url); warn!("Failed to parse HTML for URL: '{}'", &url);
} }
} else { } else {
warn!("Failed to get metadata for '{}'", &url); warn!("Failed to fetch metadata for '{}'", &url);
} }
} }
}; };

View file

@ -141,6 +141,12 @@ pub async fn run(config: Config) -> anyhow::Result<()> {
.await .await
.expect("frogbot couldn't log into it's account."); .expect("frogbot couldn't log into it's account.");
// Set the bot account's display name according to config
client
.account()
.set_display_name(Some(&config.display_name))
.await?;
warn!("Logged in successfully!"); warn!("Logged in successfully!");
warn!( warn!(
"server: '{}', username: '{}', display name: '{}'", "server: '{}', username: '{}', display name: '{}'",