diff --git a/python/src/deltachat/chat.py b/python/src/deltachat/chat.py index b83ee30818..b5a2bd57a9 100644 --- a/python/src/deltachat/chat.py +++ b/python/src/deltachat/chat.py @@ -281,6 +281,29 @@ def send_msg(self, msg: Message) -> Message: msg._dc_msg = sent_msg._dc_msg return msg + def send_msg_sync(self, msg: Message) -> Message: + """Send a message synchronously. + This bypasses the IO scheduler and creates its own SMTP connection. + + :param msg: a :class:`deltachat.message.Message` instance + previously returned by + e.g. :meth:`deltachat.message.Message.new_empty`. + :raises ValueError: if message can not be sent. + + :returns: a :class:`deltachat.message.Message` instance as + sent out. This is the same object as was passed in, which + has been modified with the new state of the core. + """ + sent_id = lib.dc_send_msg_sync(self.account._dc_context, self.id, msg._dc_msg) + if sent_id == 0: + raise ValueError("message could not be sent") + # modify message in place to avoid bad state for the caller + sent_msg = Message.from_db(self.account, sent_id) + if sent_msg is None: + raise ValueError("cannot load just sent message from the database") + msg._dc_msg = sent_msg._dc_msg + return msg + def send_text(self, text): """send a text message and return the resulting Message instance. diff --git a/python/tests/test_1_online.py b/python/tests/test_1_online.py index 04957d98bc..623bca1033 100644 --- a/python/tests/test_1_online.py +++ b/python/tests/test_1_online.py @@ -291,6 +291,31 @@ def test_forward_own_message(acfactory, lp): assert msg_in.is_forwarded() +def test_send_msg_sync(acfactory, lp): + ac1, ac2 = acfactory.get_online_accounts(2) + chat1 = acfactory.get_accepted_chat(ac1, ac2) + + # Send some message from ac1 + # so we are testing not the first message + # being sent synchronously. + lp.sec("ac1: send message to ac2") + chat1.send_text("message") + + lp.sec("ac2: receive message") + msg_in = ac2._evtracker.wait_next_incoming_message() + assert msg_in.text == "message" + + # Stop I/O and send message synchronously. + ac1.stop_io() + msg1 = Message.new_empty(ac1, "text") + msg1.set_text("message1") + chat1.send_msg_sync(msg1) + + lp.sec("ac2: receive message") + msg_in = ac2._evtracker.wait_next_incoming_message() + assert msg_in.text == "message1" + + def test_resend_message(acfactory, lp): ac1, ac2 = acfactory.get_online_accounts(2) chat1 = acfactory.get_accepted_chat(ac1, ac2) diff --git a/src/chat.rs b/src/chat.rs index 037e56675e..aa92a88010 100644 --- a/src/chat.rs +++ b/src/chat.rs @@ -3037,21 +3037,21 @@ WHERE id=? )?; let all_recipients = recipients.join(" "); if let Some(pre_msg) = &rendered_pre_msg { - let row_id = stmt.execute(( + let row_id = stmt.insert(( &pre_msg.rfc724_mid, &all_recipients, &pre_msg.message, msg.id, ))?; - row_ids.push(row_id.try_into()?); + row_ids.push(row_id); } - let row_id = stmt.execute(( + let row_id = stmt.insert(( &rendered_msg.rfc724_mid, &all_recipients, &rendered_msg.message, msg.id, ))?; - row_ids.push(row_id.try_into()?); + row_ids.push(row_id); } Ok(row_ids) };