diff --git a/example-config.yaml b/example-config.yaml
index 3c01c84e..e5e18d53 100644
--- a/example-config.yaml
+++ b/example-config.yaml
@@ -189,8 +189,6 @@ bridge:
# The formats to use when sending messages to Telegram via the relay bot.
# Text msgtypes (m.text, m.notice and m.emote) support HTML, media msgtypes don't.
#
- # Telegram doesn't have built-in emotes, so the m.emote format is also used for non-relaybot users.
- #
# Available variables:
# $sender_displayname - The display name of the sender (e.g. Example User)
# $sender_username - The username (Matrix ID localpart) of the sender (e.g. exampleuser)
@@ -206,6 +204,13 @@ bridge:
m.audio: "$sender_displayname sent an audio file: $body"
m.video: "$sender_displayname sent a video: $body"
m.location: "$sender_displayname sent a location: $body"
+ # Telegram doesn't have built-in emotes, this field specifies how m.emote's from authenticated
+ # users are sent to telegram. All fields in message_formats are supported. Additionally, the
+ # Telegram user info is available in the following variables:
+ # $displayname - Telegram displayname
+ # $username - Telegram username (may not exist)
+ # $mention - Telegram @username or displayname mention (depending on which exists)
+ emote_format: "* $mention $formatted_body"
# The formats to use when sending state events to Telegram via the relay bot.
#
diff --git a/mautrix_telegram/commands/portal/config.py b/mautrix_telegram/commands/portal/config.py
index 2ce9c283..f8e9c2e5 100644
--- a/mautrix_telegram/commands/portal/config.py
+++ b/mautrix_telegram/commands/portal/config.py
@@ -85,6 +85,7 @@ def config_defaults(evt: CommandEvent) -> Awaitable[EventID]:
"bot_messages_as_notices": evt.config["bridge.bot_messages_as_notices"],
"inline_images": evt.config["bridge.inline_images"],
"message_formats": evt.config["bridge.message_formats"],
+ "emote_format": evt.config["bridge.emote_format"],
"state_event_formats": evt.config["bridge.state_event_formats"],
"telegram_link_preview": evt.config["bridge.telegram_link_preview"],
}, stream)
diff --git a/mautrix_telegram/config.py b/mautrix_telegram/config.py
index ded96573..fb80a26f 100644
--- a/mautrix_telegram/config.py
+++ b/mautrix_telegram/config.py
@@ -117,6 +117,7 @@ class Config(BaseBridgeConfig):
if "bridge.message_formats.m_text" in self:
del self["bridge.message_formats"]
copy_dict("bridge.message_formats", override_existing_map=False)
+ copy("bridge.emote_format")
copy("bridge.state_event_formats.join")
copy("bridge.state_event_formats.leave")
diff --git a/mautrix_telegram/portal/matrix.py b/mautrix_telegram/portal/matrix.py
index aee53ed8..5dfbe7a7 100644
--- a/mautrix_telegram/portal/matrix.py
+++ b/mautrix_telegram/portal/matrix.py
@@ -194,13 +194,31 @@ class PortalMatrix(BasePortal, MautrixBasePortal, ABC):
tpl_args["message"] = content.body
content.body = Template(tpl).safe_substitute(tpl_args)
+ async def _apply_emote_format(self, sender: 'u.User',
+ content: TextMessageEventContent) -> None:
+ if content.format != Format.HTML:
+ content.format = Format.HTML
+ content.formatted_body = escape_html(content.body).replace("\n", "
")
+
+ tpl = self.get_config("emote_format")
+ puppet = p.Puppet.get(sender.tgid)
+ content.formatted_body = Template(tpl).safe_substitute(
+ dict(sender_mxid=sender.mxid,
+ sender_username=sender.mxid_localpart,
+ sender_displayname=escape_html(await self.get_displayname(sender)),
+ mention=f"{puppet.displayname}",
+ username=sender.username,
+ displayname=puppet.displayname,
+ body=content.body,
+ formatted_body=content.formatted_body))
+ content.msgtype = MessageType.TEXT
+
async def _pre_process_matrix_message(self, sender: 'u.User', use_relaybot: bool,
content: MessageEventContent) -> None:
- if content.msgtype == MessageType.EMOTE:
- await self._apply_msg_format(sender, content)
- content.msgtype = MessageType.TEXT
- elif use_relaybot:
+ if use_relaybot:
await self._apply_msg_format(sender, content)
+ elif content.msgtype == MessageType.EMOTE:
+ await self._apply_emote_format(sender, content)
@staticmethod
def _matrix_event_to_entities(event: Union[str, MessageEventContent]