Merge remote-tracking branch 'maltee1/auto_create_group'

This commit is contained in:
Tulir Asokan
2022-07-17 16:04:56 +03:00
7 changed files with 80 additions and 8 deletions
+1 -1
View File
@@ -54,7 +54,7 @@
* [x] Automatic portal creation
* [x] At startup
* [x] When receiving invite or message
* [x] Private chat creation by inviting Matrix puppet of Telegram user to new room
* [x] Portal creation by inviting Matrix puppet of Telegram user to new room
* [x] Option to use bot to relay messages for unauthenticated Matrix users (relaybot)
* [x] Option to use own Matrix account for messages sent from other Telegram clients (double puppeting)
* [ ] ‡ Calls (hard, not yet supported by Telethon)
@@ -81,4 +81,3 @@ async def create(evt: CommandEvent) -> EventID:
except ValueError as e:
await portal.delete()
return await evt.reply(e.args[0])
return await evt.reply(f"Telegram chat created. ID: {portal.tgid}")
+1
View File
@@ -130,6 +130,7 @@ class Config(BaseBridgeConfig):
copy("bridge.sync_direct_chat_list")
copy("bridge.double_puppet_server_map")
copy("bridge.double_puppet_allow_discovery")
copy("bridge.create_group_on_invite")
if "bridge.login_shared_secret" in self:
base["bridge.login_shared_secret_map"] = {
base["homeserver.domain"]: self["bridge.login_shared_secret"]
+3
View File
@@ -312,6 +312,9 @@ bridge:
kick_on_logout: true
# Should the "* user joined Telegram" notice always be marked as read automatically?
always_read_joined_telegram_notice: true
# auto-create group chat portals by inviting Matrix puppet of Telegram user to a room
# requires double-puppeting to be enabled
create_group_on_invite: true
# Settings for backfilling messages from Telegram.
backfill:
# Whether or not the Telegram ghosts of logged in Matrix users should be
+69 -5
View File
@@ -42,6 +42,8 @@ from mautrix.types import (
)
from . import commands as com, portal as po, puppet as pu, user as u
from .commands.portal.util import get_initial_state, user_has_power_level, warn_missing_power
from .types import TelegramID
if TYPE_CHECKING:
from .__main__ import TelegramBridge
@@ -69,16 +71,78 @@ class MatrixHandler(BaseMatrixHandler):
evt: StateEvent,
members: list[UserID],
) -> None:
if self.az.bot_mxid not in members:
if not invited_by.is_logged_in:
await puppet.default_mxid_intent.leave_room(
room_id, reason="This ghost does not join multi-user rooms without the bridge bot."
room_id, reason="You are not logged into this Telegram bridge"
)
else:
await puppet.default_mxid_intent.send_notice(
return
double_puppet = await pu.Puppet.get_by_custom_mxid(invited_by.mxid)
if not double_puppet or self.az.bot_mxid in members:
if self.az.bot_mxid not in members:
await puppet.default_mxid_intent.leave_room(
room_id,
reason="This ghost does not join multi-user rooms without the bridge bot.",
)
else:
await puppet.default_mxid_intent.send_notice(
room_id,
"This ghost will remain inactive until a Telegram chat is created for this room.",
)
return
elif not await user_has_power_level(
evt.room_id, double_puppet.intent, invited_by, "bridge"
):
await puppet.default_mxid_intent.leave_room(
room_id, reason="You do not have the permissions to bridge this room."
)
return
elif not self.config["bridge.create_group_on_invite"]:
return
await double_puppet.intent.invite_user(room_id, self.az.bot_mxid)
title, about, levels, encrypted = await get_initial_state(double_puppet.intent, room_id)
if not title:
await puppet.default_mxid_intent.leave_room(
room_id, reason="Please set a title before inviting Telegram puppets."
)
return
portal = po.Portal(
tgid=TelegramID(0),
tg_receiver=TelegramID(0),
peer_type="channel",
mxid=evt.room_id,
title=title,
about=about,
encrypted=encrypted,
)
await portal.az.intent.ensure_joined(room_id)
levels = await portal.az.intent.get_power_levels(room_id)
invited_by_level = levels.get_user_level(invited_by.mxid)
if invited_by_level > levels.get_user_level(self.az.bot_mxid):
levels.users[self.az.bot_mxid] = 100 if invited_by_level >= 100 else invited_by_level
await double_puppet.intent.set_power_levels(room_id, levels)
invites, errors = await portal.get_telegram_users_in_matrix_room(
invited_by, pre_create=True
)
if len(errors) > 0:
error_list = "\n".join(f"* [{mxid}](https://matrix.to/#/{mxid})" for mxid in errors)
await portal.az.intent.send_notice(
room_id,
"This ghost will remain inactive until a Telegram chat is created for this room.",
f"Failed to add the following users to the chat:\n\n{error_list}\n\n"
"You can try `$cmdprefix+sp search -r <username>` to help the bridge find "
"those users.",
)
try:
await portal.create_telegram_chat(invited_by, invites=invites, supergroup=True)
except ValueError as e:
await portal.delete()
return await portal.az.intent.send_notice(room_id, e.args[0])
async def handle_invite(
self, room_id: RoomID, user_id: UserID, inviter: u.User, event_id: EventID
) -> None:
+1
View File
@@ -567,6 +567,7 @@ class Portal(DBPortal, BasePortal):
await self.main_intent.set_power_levels(self.mxid, levels)
await self.handle_matrix_power_levels(source, levels.users, {}, None)
await self.update_bridge_info()
await self.main_intent.send_notice(self.mxid, f"Telegram chat created. ID: {self.tgid}")
async def handle_matrix_invite(
self, invited_by: u.User, puppet: p.Puppet | au.AbstractUser
+5 -1
View File
@@ -85,7 +85,11 @@ def get_base_power_levels(
)
for evt_type, value in overrides.get("events", {}).items():
levels.events[EventType.find(evt_type)] = value
levels.users = overrides.get("users", {})
userlevel_overrides = overrides.get("users", {})
bot_level = levels.get_user_level(portal.main_intent.mxid)
for user, user_level in levels.users.items():
if user_level < bot_level:
levels.users[user] = userlevel_overrides.get(user, 0)
if portal.main_intent.mxid not in levels.users:
levels.users[portal.main_intent.mxid] = 100
return levels