diff --git a/deltachat-jsonrpc/src/api.rs b/deltachat-jsonrpc/src/api.rs index 5c34a554c9..fde2b5cae1 100644 --- a/deltachat-jsonrpc/src/api.rs +++ b/deltachat-jsonrpc/src/api.rs @@ -1944,7 +1944,7 @@ impl CommandApi { let ctx = self.get_context(account_id).await?; let mut msg = Message::new(Viewtype::Sticker); - msg.set_file(&sticker_path, None); + msg.set_file_and_deduplicate(&ctx, Path::new(&sticker_path), None, None)?; // JSON-rpc does not need heuristics to turn [Viewtype::Sticker] into [Viewtype::Image] msg.force_sticker(); @@ -2164,12 +2164,14 @@ impl CommandApi { // mimics the old desktop call, will get replaced with something better in the composer rewrite, // the better version will just be sending the current draft, though there will be probably something similar with more options to this for the corner cases like setting a marker on the map + #[expect(clippy::too_many_arguments)] async fn misc_send_msg( &self, account_id: u32, chat_id: u32, text: Option, file: Option, + filename: Option, location: Option<(f64, f64)>, quoted_message_id: Option, ) -> Result<(u32, MessageObject)> { @@ -2181,7 +2183,7 @@ impl CommandApi { }); message.set_text(text.unwrap_or_default()); if let Some(file) = file { - message.set_file(file, None); + message.set_file_and_deduplicate(&ctx, Path::new(&file), filename.as_deref(), None)?; } if let Some((latitude, longitude)) = location { message.set_location(latitude, longitude); @@ -2209,12 +2211,14 @@ impl CommandApi { // the better version should support: // - changing viewtype to enable/disable compression // - keeping same message id as long as attachment does not change for webxdc messages + #[expect(clippy::too_many_arguments)] async fn misc_set_draft( &self, account_id: u32, chat_id: u32, text: Option, file: Option, + filename: Option, quoted_message_id: Option, view_type: Option, ) -> Result<()> { @@ -2231,7 +2235,7 @@ impl CommandApi { )); draft.set_text(text.unwrap_or_default()); if let Some(file) = file { - draft.set_file(file, None); + draft.set_file_and_deduplicate(&ctx, Path::new(&file), filename.as_deref(), None)?; } if let Some(id) = quoted_message_id { draft diff --git a/deltachat-jsonrpc/src/api/types/message.rs b/deltachat-jsonrpc/src/api/types/message.rs index efe7b66ca6..f26a948d89 100644 --- a/deltachat-jsonrpc/src/api/types/message.rs +++ b/deltachat-jsonrpc/src/api/types/message.rs @@ -1,3 +1,5 @@ +use std::path::Path; + use crate::api::VcardContact; use anyhow::{Context as _, Result}; use deltachat::chat::Chat; @@ -593,6 +595,7 @@ pub struct MessageData { pub html: Option, pub viewtype: Option, pub file: Option, + pub filename: Option, pub location: Option<(f64, f64)>, pub override_sender_name: Option, /// Quoted message id. Takes preference over `quoted_text` (see below). @@ -617,7 +620,12 @@ impl MessageData { message.set_override_sender_name(self.override_sender_name); } if let Some(file) = self.file { - message.set_file(file, None); + message.set_file_and_deduplicate( + context, + Path::new(&file), + self.filename.as_deref(), + None, + )?; } if let Some((latitude, longitude)) = self.location { message.set_location(latitude, longitude); diff --git a/deltachat-rpc-client/src/deltachat_rpc_client/chat.py b/deltachat-rpc-client/src/deltachat_rpc_client/chat.py index 9d33a5a0f4..3522e88992 100644 --- a/deltachat-rpc-client/src/deltachat_rpc_client/chat.py +++ b/deltachat-rpc-client/src/deltachat_rpc_client/chat.py @@ -124,6 +124,7 @@ def send_message( html: Optional[str] = None, viewtype: Optional[ViewType] = None, file: Optional[str] = None, + filename: Optional[str] = None, location: Optional[tuple[float, float]] = None, override_sender_name: Optional[str] = None, quoted_msg: Optional[Union[int, Message]] = None, @@ -137,6 +138,7 @@ def send_message( "html": html, "viewtype": viewtype, "file": file, + "filename": filename, "location": location, "overrideSenderName": override_sender_name, "quotedMessageId": quoted_msg, @@ -172,13 +174,14 @@ def set_draft( self, text: Optional[str] = None, file: Optional[str] = None, + filename: Optional[str] = None, quoted_msg: Optional[int] = None, viewtype: Optional[str] = None, ) -> None: """Set draft message.""" if isinstance(quoted_msg, Message): quoted_msg = quoted_msg.id - self._rpc.misc_set_draft(self.account.id, self.id, text, file, quoted_msg, viewtype) + self._rpc.misc_set_draft(self.account.id, self.id, text, file, filename, quoted_msg, viewtype) def remove_draft(self) -> None: """Remove draft message."""