feat: add bot field to contact (#4821)

closes #4647
This commit is contained in:
Sebastian Klähn
2023-10-15 12:40:32 +02:00
committed by link2xt
parent ac557f73b3
commit e725bdfb2b
5 changed files with 43 additions and 1 deletions

View File

@@ -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<String> = 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()`.

View File

@@ -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(())
}

View File

@@ -114,7 +114,11 @@ pub(crate) struct MimeMessage {
/// for e.g. late-parsing HTML.
pub decoded_data: Vec<u8>,
/// 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 {

View File

@@ -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))
}

View File

@@ -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?