diff --git a/CHANGELOG.md b/CHANGELOG.md index ce2da427e..039ce1254 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -19,6 +19,7 @@ - Clear config cache after backup import. This bug sometimes resulted in the import to seemingly work at first. #4067 ### API-Changes +- jsonrpc: add more advanced API to send a message. ## 1.109.0 diff --git a/deltachat-jsonrpc/src/api/mod.rs b/deltachat-jsonrpc/src/api/mod.rs index 22f261ced..6064f476a 100644 --- a/deltachat-jsonrpc/src/api/mod.rs +++ b/deltachat-jsonrpc/src/api/mod.rs @@ -41,6 +41,7 @@ use types::account::Account; use types::chat::FullChat; use types::chat_list::ChatListEntry; use types::contact::ContactObject; +use types::message::DraftMessage; use types::message::MessageObject; use types::provider_info::ProviderInfo; use types::webxdc::WebxdcMessageInfo; @@ -1511,6 +1512,54 @@ impl CommandApi { Ok(message_id.to_u32()) } + async fn send_msg( + &self, + account_id: u32, + chat_id: u32, + draft: DraftMessage, + ) -> Result<(u32, MessageObject)> { + let ctx = self.get_context(account_id).await?; + let mut message = Message::new(if let Some(viewtype) = draft.viewtype { + viewtype.into() + } else if draft.file.is_some() { + Viewtype::File + } else { + Viewtype::Text + }); + if draft.text.is_some() { + message.set_text(draft.text); + } + if draft.html.is_some() { + message.set_html(draft.html); + } + if draft.override_sender_name.is_some() { + message.set_override_sender_name(draft.override_sender_name); + } + if let Some(file) = draft.file { + message.set_file(file, None); + } + if let Some((latitude, longitude)) = draft.location { + message.set_location(latitude, longitude); + } + if let Some(id) = draft.quoted_message_id { + message + .set_quote( + &ctx, + Some( + &Message::load_from_db(&ctx, MsgId::new(id)) + .await + .context("message to quote could not be loaded")?, + ), + ) + .await?; + } + let msg_id = chat::send_msg(&ctx, ChatId::new(chat_id), &mut message) + .await? + .to_u32(); + let message = MessageObject::from_message_id(&ctx, msg_id).await?; + Ok((msg_id, message)) + } + // --------------------------------------------- // functions for the composer // the composer is the message input field diff --git a/deltachat-jsonrpc/src/api/types/message.rs b/deltachat-jsonrpc/src/api/types/message.rs index 04a850715..f5185fdb6 100644 --- a/deltachat-jsonrpc/src/api/types/message.rs +++ b/deltachat-jsonrpc/src/api/types/message.rs @@ -502,3 +502,15 @@ impl From for JSONRPCMessageListItem { } } } + +#[derive(Deserialize, TypeDef)] +#[serde(rename_all = "camelCase")] +pub struct DraftMessage { + pub text: Option, + pub html: Option, + pub viewtype: Option, + pub file: Option, + pub location: Option<(f64, f64)>, + pub override_sender_name: Option, + pub quoted_message_id: Option, +} diff --git a/deltachat-rpc-client/src/deltachat_rpc_client/chat.py b/deltachat-rpc-client/src/deltachat_rpc_client/chat.py index 7dac7d2f4..91cb48e4e 100644 --- a/deltachat-rpc-client/src/deltachat_rpc_client/chat.py +++ b/deltachat-rpc-client/src/deltachat_rpc_client/chat.py @@ -3,7 +3,7 @@ from dataclasses import dataclass from typing import TYPE_CHECKING, Dict, List, Optional, Tuple, Union from ._utils import AttrDict -from .const import ChatVisibility +from .const import ChatVisibility, ViewType from .contact import Contact from .message import Message @@ -108,15 +108,27 @@ class Chat: async def send_message( self, text: Optional[str] = None, + html: Optional[str] = None, + viewtype: Optional[ViewType] = None, file: Optional[str] = None, location: Optional[Tuple[float, float]] = None, + override_sender_name: Optional[str] = None, quoted_msg: Optional[Union[int, Message]] = None, ) -> Message: """Send a message and return the resulting Message instance.""" if isinstance(quoted_msg, Message): quoted_msg = quoted_msg.id - msg_id, _ = await self._rpc.misc_send_msg(self.account.id, self.id, text, file, location, quoted_msg) + draft = { + "text": text, + "html": html, + "viewtype": viewtype, + "file": file, + "location": location, + "overrideSenderName": override_sender_name, + "quotedMsg": quoted_msg, + } + msg_id, _ = await self._rpc.send_msg(self.account.id, self.id, draft) return Message(self.account, msg_id) async def send_text(self, text: str) -> Message: