From e725bdfb2bc56d1995db2a8840cdb7d0b41d2311 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Kl=C3=A4hn?= <39526136+Septias@users.noreply.github.com> Date: Sun, 15 Oct 2023 12:40:32 +0200 Subject: [PATCH] feat: add bot field to contact (#4821) closes #4647 --- src/contact.rs | 21 ++++++++++++++++++++- src/message.rs | 4 ++++ src/mimeparser.rs | 8 ++++++++ src/receive_imf.rs | 2 ++ src/sql/migrations.rs | 9 +++++++++ 5 files changed, 43 insertions(+), 1 deletion(-) diff --git a/src/contact.rs b/src/contact.rs index be04523f9..4a4ff3540 100644 --- a/src/contact.rs +++ b/src/contact.rs @@ -139,6 +139,15 @@ impl ContactId { pub const fn to_u32(&self) -> u32 { self.0 } + + /// Mark contact as bot. + pub(crate) async fn mark_bot(&self, context: &Context, is_bot: bool) -> Result<()> { + context + .sql + .execute("UPDATE contacts SET is_bot=? WHERE id=?;", (is_bot, self.0)) + .await?; + Ok(()) + } } impl fmt::Display for ContactId { @@ -223,6 +232,9 @@ pub struct Contact { /// Last seen message signature for this contact, to be displayed in the profile. status: String, + + /// If the contact is a bot. + is_bot: bool, } /// Possible origins of a contact. @@ -366,7 +378,7 @@ impl Contact { .sql .query_row_optional( "SELECT c.name, c.addr, c.origin, c.blocked, c.last_seen, - c.authname, c.param, c.status + c.authname, c.param, c.status, c.is_bot FROM contacts c WHERE c.id=?;", (contact_id,), @@ -379,6 +391,7 @@ impl Contact { let authname: String = row.get(5)?; let param: String = row.get(6)?; let status: Option = row.get(7)?; + let is_bot: bool = row.get(8)?; let contact = Self { id: contact_id, name, @@ -389,6 +402,7 @@ impl Contact { origin, param: param.parse().unwrap_or_default(), status: status.unwrap_or_default(), + is_bot, }; Ok(contact) }, @@ -498,6 +512,11 @@ impl Contact { Ok(()) } + /// Returns whether contact is a bot. + pub fn is_bot(&self) -> bool { + self.is_bot + } + /// Check if an e-mail address belongs to a known and unblocked contact. /// /// Known and unblocked contacts will be returned by `get_contacts()`. diff --git a/src/message.rs b/src/message.rs index 0a299c3e9..8d5ec6fea 100644 --- a/src/message.rs +++ b/src/message.rs @@ -2341,6 +2341,8 @@ mod tests { let msg = alice.get_last_msg().await; assert_eq!(msg.get_text(), "hello".to_string()); assert!(msg.is_bot()); + let contact = Contact::get_by_id(&alice, msg.from_id).await?; + assert!(contact.is_bot()); // Alice receives a message from Bob who is not the bot anymore. receive_imf( @@ -2358,6 +2360,8 @@ mod tests { let msg = alice.get_last_msg().await; assert_eq!(msg.get_text(), "hello again".to_string()); assert!(!msg.is_bot()); + let contact = Contact::get_by_id(&alice, msg.from_id).await?; + assert!(!contact.is_bot()); Ok(()) } diff --git a/src/mimeparser.rs b/src/mimeparser.rs index d1cfd5fa2..21207a86a 100644 --- a/src/mimeparser.rs +++ b/src/mimeparser.rs @@ -114,7 +114,11 @@ pub(crate) struct MimeMessage { /// for e.g. late-parsing HTML. pub decoded_data: Vec, + /// Hop info for debugging. pub(crate) hop_info: String, + + /// Whether the contact sending this should be marked as bot. + pub(crate) is_bot: bool, } #[derive(Debug, PartialEq)] @@ -373,6 +377,9 @@ impl MimeMessage { signatures.clear(); } + // Auto-submitted is also set by holiday-notices so we also check `chat-version` + let is_bot = headers.contains_key("auto-submitted") && headers.contains_key("chat-version"); + let mut parser = MimeMessage { parts: Vec::new(), headers, @@ -401,6 +408,7 @@ impl MimeMessage { is_mime_modified: false, decoded_data: Vec::new(), hop_info, + is_bot, }; match partial { diff --git a/src/receive_imf.rs b/src/receive_imf.rs index 58a094c91..f254459e7 100644 --- a/src/receive_imf.rs +++ b/src/receive_imf.rs @@ -377,6 +377,8 @@ pub(crate) async fn receive_imf_inner( .handle_reports(context, from_id, sent_timestamp, &mime_parser.parts) .await; + from_id.mark_bot(context, mime_parser.is_bot).await?; + Ok(Some(received_msg)) } diff --git a/src/sql/migrations.rs b/src/sql/migrations.rs index a90f36b0e..8f3b24509 100644 --- a/src/sql/migrations.rs +++ b/src/sql/migrations.rs @@ -740,6 +740,15 @@ CREATE INDEX smtp_messageid ON imap(rfc724_mid); .await?; } + // Add is_bot column to contacts table with default false. + if dbversion < 103 { + sql.execute_migration( + "ALTER TABLE contacts ADD COLUMN is_bot INTEGER NOT NULL DEFAULT 0", + 103, + ) + .await?; + } + let new_version = sql .get_raw_config_int(VERSION_CFG) .await?