Add provisioning API for listing contacts and starting DMs

This commit is contained in:
Tulir Asokan
2022-04-06 12:40:55 +03:00
parent 61f3c39cc2
commit 261f99ac82
4 changed files with 87 additions and 9 deletions
+60 -2
View File
@@ -21,7 +21,7 @@ import json
import logging
from aiohttp import web
from telethon.tl.types import ChannelForbidden, ChatForbidden, TypeChat
from telethon.tl.types import ChannelForbidden, ChatForbidden, TypeChat, User as TLUser
from telethon.utils import get_peer_id, resolve_id
from mautrix.appservice import AppService
@@ -65,6 +65,8 @@ class ProvisioningAPI(AuthAPI):
user_prefix = "/user/{mxid:@[^:]*:[^/]+}"
self.app.router.add_route("GET", f"{user_prefix}", self.get_user_info)
self.app.router.add_route("GET", f"{user_prefix}/chats", self.get_chats)
self.app.router.add_route("GET", f"{user_prefix}/contacts", self.get_contacts)
self.app.router.add_route("POST", f"{user_prefix}/pm/{{identifier}}", self.start_dm)
self.app.router.add_route("POST", f"{user_prefix}/logout", self.logout)
self.app.router.add_route("POST", f"{user_prefix}/login/bot_token", self.send_bot_token)
@@ -393,6 +395,62 @@ class ProvisioningAPI(AuthAPI):
]
)
async def get_contacts(self, request: web.Request) -> web.Response:
data, user, err = await self.get_user_request_info(request, expect_logged_in=True)
if err is not None:
return err
return web.json_response(data=await user.sync_contacts())
async def start_dm(self, request: web.Request) -> web.Response:
data, user, err = await self.get_user_request_info(request, expect_logged_in=True)
if err is not None:
return err
try:
identifier: str | int = request.match_info["identifier"]
if isinstance(identifier, str) and identifier.isdecimal():
identifier = int(identifier)
target = await user.client.get_entity(identifier)
except ValueError:
return web.json_response(
{
"error": "Invalid user identifier or user not found.",
"errcode": "M_NOT_FOUND",
},
status=404,
)
if not target:
return web.json_response(
{
"error": "User not found.",
"errcode": "M_NOT_FOUND",
},
status=404,
)
elif not isinstance(target, TLUser):
return web.json_response(
{
"error": "Identifier is not a user.",
},
status=400,
)
portal = await Portal.get_by_entity(target, tg_receiver=user.tgid)
puppet = await portal.get_dm_puppet()
if portal.mxid:
just_created = False
else:
await portal.create_matrix_room(user, target, [user.mxid])
just_created = True
return web.json_response(
{
"room_id": portal.mxid,
"just_created": just_created,
"id": portal.tgid,
"contact_info": puppet.contact_info,
},
status=201 if just_created else 200,
)
async def send_bot_token(self, request: web.Request) -> web.Response:
data, user, err = await self.get_user_request_info(request)
if err is not None:
@@ -574,7 +632,7 @@ class ProvisioningAPI(AuthAPI):
data = None
if want_data and (request.method == "POST" or request.method == "PUT"):
data = await self.get_data(request)
if not data:
if data is None:
return (
None,
None,