From 2dbccf5e475632d98afcd03909717f29737ae03d Mon Sep 17 00:00:00 2001 From: Miklos Vajna Date: Fri, 29 May 2026 22:39:47 +0200 Subject: [PATCH] matrix: improve non-self member detection of a DM room for bridges Have a bridged DM (e.g. Signal DM) as a Matrix room, which technically has 4 nicks: an admin bot, the other person, your bridged equivalent and yourself. Reading messages was possible in this case (mapped to an IRC DM) but sending resulted in a ": No such nick/channel" error message. It seems what happens is that dm_peer() used to find the bridged equivalent of "me" in such rooms as the "nick": debug, register_dm: room.room_id() is '!...:vmiklos.hu', nick is 'vmiklos' Fix the problem by taking a hint from the DM display name: if we find the user based on that (which is typical in such bridged rooms), then use that nick: debug, register_dm: room.room_id() is '!...:vmiklos.hu', nick is 'othernick' No test is added: dm_peer() currently takes a matrix SDK Client and Room as parameters, which are hard to construct in a testcase. --- src/matrix.rs | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/src/matrix.rs b/src/matrix.rs index 1415aa0..9b5a60c 100644 --- a/src/matrix.rs +++ b/src/matrix.rs @@ -861,6 +861,19 @@ async fn dm_peer_nick(client: &Client, room: &Room) -> Option { async fn dm_peer(client: &Client, room: &Room) -> Option<(String, matrix_sdk::ruma::OwnedUserId)> { let me = client.user_id()?; let members = room.members(RoomMemberships::JOIN | RoomMemberships::INVITE).await.ok()?; + + // First try to find a member that matches the room's display name. + // This is common in bridged DMs where the room is named after the peer. + let room_display_name = room.display_name().await.ok().map(|n| n.to_string()); + if let Some(ref rdn) = room_display_name { + if let Some(m) = members.iter().find(|m| { + m.user_id() != me && m.display_name() == Some(rdn.as_str()) + }) { + let nick = sanitize_nick(rdn); + return Some((nick, m.user_id().to_owned())); + } + } + members.into_iter().find(|m| m.user_id() != me).map(|m| { let nick = m.display_name() .map(sanitize_nick)