diff --git i/heisenbridge/__main__.py w/heisenbridge/__main__.py index d59febd..4898955 100644 --- i/heisenbridge/__main__.py +++ w/heisenbridge/__main__.py @@ -28,6 +28,7 @@ from mautrix.errors import MUserInUse from mautrix.types import EventType from mautrix.types import JoinRule from mautrix.types import Membership +from mautrix.types import PresenceState from mautrix.util.bridge_state import BridgeState from mautrix.util.bridge_state import BridgeStateEvent from mautrix.util.config import yaml @@ -192,6 +193,19 @@ class BridgeAppService(AppService): return ret + def set_user_state(self, user_id, away, status=None): + if user_id not in self._users: + return + + presence = PresenceState.ONLINE + if away: + presence = PresenceState.UNAVAILABLE + + async def later(): + await self.az.intent.user(user_id).set_presence(presence=presence, status=status) + + asyncio.ensure_future(later()) + async def cache_user(self, user_id, displayname): # start by caching that the user_id exists without a displayname if user_id not in self._users: diff --git i/heisenbridge/channel_room.py w/heisenbridge/channel_room.py index 119dad0..3e0651d 100644 --- i/heisenbridge/channel_room.py +++ w/heisenbridge/channel_room.py @@ -478,6 +478,9 @@ class ChannelRoom(PrivateRoom): asyncio.ensure_future(autocmd(self)) + # Run a WHO on the channel to get initial away status + self.network.conn.who(target=event.target) + return # ensure, append, invite and join diff --git i/heisenbridge/network_room.py w/heisenbridge/network_room.py index 3c20654..2758462 100644 --- i/heisenbridge/network_room.py +++ w/heisenbridge/network_room.py @@ -139,7 +139,7 @@ class NetworkRoom(Room): self.tls_cert = None self.rejoin_invite = True self.rejoin_kick = False - self.caps = ["message-tags", "chghost", "znc.in/self-message"] + self.caps = ["message-tags", "chghost", "znc.in/self-message", "away-notify"] self.forward = False self.backoff = 0 self.backoff_task = None @@ -1378,6 +1378,7 @@ class NetworkRoom(Room): self.conn.add_global_handler("338", self.on_whoisrealhost) # is actually using host self.conn.add_global_handler("away", self.on_away) self.conn.add_global_handler("endofwhois", self.on_endofwhois) + self.conn.add_global_handler("whoreply", self.on_whoreply) # tags self.conn.add_global_handler("tagmsg", self.on_pass_or_ignore) @@ -1936,9 +1937,34 @@ class NetworkRoom(Room): data = self.whois_data[event.arguments[0].lower()] data["realhost"] = event.arguments[1] + def on_whoreply(self, conn, event) -> None: + data = self.whois_data[event.arguments[4].lower()] + data["nick"] = event.arguments[4] + data["user"] = event.arguments[1] + data["host"] = event.arguments[2] + if "G" in event.arguments[5]: + data["away"] = True + elif "H" in event.arguments[5]: + data["away"] = False + # data["realname"] = event.arguments[4] + + nick, mode = self.serv.strip_nick(data["nick"]) + irc_user_id = self.serv.irc_user_id(self.name, data["nick"]) + self.serv.set_user_state(irc_user_id, data["away"]) + def on_away(self, conn, event) -> None: + nick, mode = self.serv.strip_nick(event.arguments[0]) + irc_user_id = self.serv.irc_user_id(self.name, event.arguments[0]) + if event.arguments[0].lower() in self.whois_data: - self.whois_data[event.arguments[0].lower()]["away"] = event.arguments[1] + if len(event.arguments) > 1: + self.whois_data[event.arguments[0].lower()]["away"] = True + self.whois_data[event.arguments[0].lower()]["awaymsg"] = event.arguments[1] + self.serv.set_user_state(irc_user_id, True, event.arguments[1]) + else: + self.whois_data[event.arguments[0].lower()]["away"] = False + self.whois_data[event.arguments[0].lower()]["awaymsg"] = "" + self.serv.set_user_state(irc_user_id, False) else: self.send_notice(f"{event.arguments[0]} is away: {event.arguments[1]}")