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.
This commit is contained in:
		
						commit
						d4bb9c20b5
					
				
					 3 changed files with 49 additions and 25 deletions
				
			
		|  | @ -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 | ||||||
|  |  | ||||||
|  | @ -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); | ||||||
|             } |             } | ||||||
|         } |         } | ||||||
|     }; |     }; | ||||||
|  |  | ||||||
|  | @ -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: '{}'", | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue