diff --git a/example-config.yaml b/example-config.yaml
index 9a601c8f..f1b72855 100644
--- a/example-config.yaml
+++ b/example-config.yaml
@@ -83,6 +83,9 @@ bridge:
allow_matrix_login: true
# Whether or not to allow creating portals from Telegram.
authless_relaybot_portals: true
+ # Use inline images instead of m.image to make rich captions possible.
+ # N.B. Inline images are not supported on all clients (e.g. Riot iOS).
+ inline_images: false
# The prefix for commands. Only required in non-management rooms.
command_prefix: "!tg"
@@ -112,4 +115,4 @@ telegram:
# The version of the config. The bridge will read this and automatically update the config if
# the schema has changed. For the latest version, check the example config.
-version: 1
+version: 2
diff --git a/mautrix_telegram/config.py b/mautrix_telegram/config.py
index 7bab5563..b7bcf8bc 100644
--- a/mautrix_telegram/config.py
+++ b/mautrix_telegram/config.py
@@ -16,6 +16,8 @@
# along with this program. If not, see .
from ruamel.yaml import YAML
from ruamel.yaml.comments import CommentedMap
+from ruamel.yaml.tokens import CommentToken
+from ruamel.yaml.error import CommentMark
import random
import string
@@ -42,6 +44,9 @@ class DictWithRecursion:
def __getitem__(self, key):
return self.get(key, None)
+ def __contains__(self, key):
+ return self[key] is not None
+
def _recursive_set(self, data, key, value):
if '.' in key:
key, next_key = key.split('.', 1)
@@ -71,6 +76,7 @@ class DictWithRecursion:
return
try:
del data[key]
+ del data.ca.items[key]
except KeyError:
pass
@@ -80,6 +86,7 @@ class DictWithRecursion:
return
try:
del self._data[key]
+ del self._data.ca.items[key]
except KeyError:
pass
@@ -93,10 +100,19 @@ class DictWithRecursion:
except ValueError:
path = None
entry = self[path] if path else self._data
- c = self._data.ca.items.setdefault(key, [None, [], None, None])
+ c = entry.ca.items.setdefault(key, [None, [], None, None])
c[1] = []
entry.yaml_set_comment_before_after_key(key=key, before=message, indent=indent)
+ def comment_newline(self, key):
+ try:
+ path, key = key.rsplit(".", 1)
+ except ValueError:
+ path = None
+ entry = self[path] if path else self._data
+ c = entry.ca.items.setdefault(key, [None, [], None, None])
+ c[2] = CommentToken("\n\n", CommentMark(0), None)
+
class Config(DictWithRecursion):
def __init__(self, path, registration_path):
@@ -131,10 +147,10 @@ class Config(DictWithRecursion):
del self["bridge.whitelist"]
del self["bridge.admins"]
- self["bridge.authless_relaybot_portals"] = self.get("bridge.authless_relaybot_portals",
- True)
- self.comment("bridge.authless_relaybot_portals",
- "Whether or not to allow creating portals from Telegram.")
+ if "bridge.authless_relaybot_portals" not in self:
+ self["bridge.authless_relaybot_portals"] = True
+ self.comment("bridge.authless_relaybot_portals",
+ "Whether or not to allow creating portals from Telegram.")
self.comment("bridge.permissions", "\n".join((
"",
@@ -156,13 +172,29 @@ class Config(DictWithRecursion):
"\nThe version of the config. The bridge will read this and automatically "
"update the config if\nthe schema has changed. For the latest version, "
"check the example config.")
+ return self["version"]
+
+ def update_1_2(self):
+ del self["bridge.link_in_reply"]
+ del self["bridge.native_replies"]
+ if "bridge.inline_images" not in self:
+ self["bridge.inline_images"] = False
+ self.comment("bridge.inline_images",
+ "Use inline images instead of m.image to make rich captions possible.\n"
+ "N.B. Inline images are not supported on all clients (e.g. Riot iOS).")
+ self.comment_newline("bridge.inline_images")
+ self["version"] = 2
+ return self["version"]
def check_updates(self):
- if self.get("version", 0) == 0:
- self.update_0_1()
- else:
- return
- self.save()
+ version = self.get("version", 0)
+ new_version = version
+ if version < 1:
+ new_version = self.update_0_1()
+ if version < 2:
+ new_version = self.update_1_2()
+ if new_version != version:
+ self.save()
def _get_permissions(self, key):
level = self["bridge.permissions"].get(key, "")
diff --git a/mautrix_telegram/portal.py b/mautrix_telegram/portal.py
index 1de1f907..01055ab6 100644
--- a/mautrix_telegram/portal.py
+++ b/mautrix_telegram/portal.py
@@ -16,6 +16,7 @@
# along with this program. If not, see .
from collections import deque
from datetime import datetime
+from html import escape
import asyncio
import random
import mimetypes
@@ -838,6 +839,15 @@ class Portal:
largest_size.location)
if not file:
return None
+ if config["bridge.inline_images"] and evt.message:
+ text, html, relates_to = await formatter.telegram_to_matrix(evt, source,
+ self.main_intent)
+ await intent.set_typing(self.mxid, is_typing=False)
+ print(self.main_intent.client.get_download_url(file.mxc))
+ inline_img = f"
\n"
+ html = inline_img + (html or escape(text))
+ text = f"Inline image: {text}"
+ return await intent.send_text(self.mxid, text, html=html, relates_to=relates_to)
info = {
"h": largest_size.h,
"w": largest_size.w,