From 16320357845da5cd963f7f3597c2ae18a2b8b6b9 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 ccf6b29c23..fed85e0533 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 c3e21b8036..915c19af37 100644 --- a/src/message.rs +++ b/src/message.rs @@ -2339,6 +2339,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( @@ -2356,6 +2358,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 b8b6b0a3a3..b07e067df6 100644 --- a/src/mimeparser.rs +++ b/src/mimeparser.rs @@ -113,7 +113,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)] @@ -390,6 +394,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, @@ -418,6 +425,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 14fa6f0613..59442a1187 100644 --- a/src/receive_imf.rs +++ b/src/receive_imf.rs @@ -379,6 +379,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 b358adb842..e8cc8a556b 100644 --- a/src/sql/migrations.rs +++ b/src/sql/migrations.rs @@ -731,6 +731,15 @@ CREATE INDEX smtp_messageid ON imap(rfc724_mid); .await?; } + // Add is_bot column to contacts table with default false. + if dbversion < 102 { + sql.execute_migration( + "ALTER TABLE contacts ADD COLUMN is_bot INTEGER NOT NULL DEFAULT 0", + 102, + ) + .await?; + } + let new_version = sql .get_raw_config_int(VERSION_CFG) .await?