Add Telegram->Matrix presence and typing notifications

This commit is contained in:
Tulir Asokan
2018-01-21 21:50:56 +02:00
parent a8359441b0
commit af9d38c534
4 changed files with 50 additions and 9 deletions
+2 -2
View File
@@ -83,8 +83,8 @@ does not do this automatically.
* [ ] Video messages * [ ] Video messages
* [ ] Documents * [ ] Documents
* [ ] Message deletions * [ ] Message deletions
* [ ] Presence * [x] Presence
* [ ] Typing notifications * [x] Typing notifications
* [ ] Pinning messages * [ ] Pinning messages
* [ ] Admin status * [ ] Admin status
* [ ] Membership actions * [ ] Membership actions
+25 -1
View File
@@ -76,6 +76,22 @@ class HTTPAPI(MatrixHttpApi):
return self._send("POST", "/createRoom", content) return self._send("POST", "/createRoom", content)
def set_presence(self, status="online", user=None):
content = {
"presence": status
}
user = user or self.identity
return self._send("PUT", f"/presence/{user}/status", content)
def set_typing(self, room_id, is_typing=True, timeout=5000, user=None):
content = {
"typing": is_typing
}
if is_typing:
content["timeout"] = timeout
user = user or self.identity
return self._send("PUT", f"/rooms/{room_id}/typing/{user}", content)
class ChildHTTPAPI(HTTPAPI): class ChildHTTPAPI(HTTPAPI):
def __init__(self, user, parent): def __init__(self, user, parent):
@@ -137,6 +153,14 @@ class IntentAPI:
self._ensure_registered() self._ensure_registered()
return self.client.set_display_name(self.mxid, name) return self.client.set_display_name(self.mxid, name)
def set_presence(self, status="online"):
self._ensure_registered()
return self.client.set_presence(status)
def set_typing(self, room_id, is_typing=True, timeout=5000):
self._ensure_joined(room_id)
return self.client.set_typing(room_id, is_typing, timeout)
def create_room(self, alias=None, is_public=False, name=None, topic=None, is_direct=False, def create_room(self, alias=None, is_public=False, name=None, topic=None, is_direct=False,
invitees=()): invitees=()):
self._ensure_registered() self._ensure_registered()
@@ -181,7 +205,7 @@ class IntentAPI:
membership["content"]["membership"] == "join"] membership["content"]["membership"] == "join"]
def _ensure_joined(self, room_id, ignore_cache=False): def _ensure_joined(self, room_id, ignore_cache=False):
if ignore_cache and self.memberships.get(room_id, "") == "join": if not ignore_cache and self.memberships.get(room_id, "") == "join":
return return
self._ensure_registered() self._ensure_registered()
try: try:
+3
View File
@@ -85,6 +85,9 @@ class Portal:
else: else:
sender.send_message(self.peer, message["body"]) sender.send_message(self.peer, message["body"])
def handle_telegram_typing(self, user, event):
user.intent.set_typing(self.mxid, is_typing=True)
def handle_telegram_message(self, sender, evt): def handle_telegram_message(self, sender, evt):
self.log.debug("Sending %s to %s by %d", evt.message, self.mxid, sender.id) self.log.debug("Sending %s to %s by %d", evt.message, self.mxid, sender.id)
if evt.message: if evt.message:
+20 -6
View File
@@ -15,8 +15,7 @@
# along with this program. If not, see <http://www.gnu.org/licenses/>. # along with this program. If not, see <http://www.gnu.org/licenses/>.
import traceback import traceback
from telethon import TelegramClient from telethon import TelegramClient
from telethon.tl.types import User as UserEntity, Chat as ChatEntity, Channel as ChannelEntity, \ from telethon.tl.types import *
UpdateShortMessage, UpdateShortChatMessage, Message, UpdateShortSentMessage
from telethon.tl.functions.messages import SendMessageRequest from telethon.tl.functions.messages import SendMessageRequest
from .db import User as DBUser from .db import User as DBUser
from . import portal as po, puppet as pu from . import portal as po, puppet as pu
@@ -118,9 +117,9 @@ class User:
dialogs = self.client.get_dialogs(limit=30) dialogs = self.client.get_dialogs(limit=30)
for dialog in dialogs: for dialog in dialogs:
entity = dialog.entity entity = dialog.entity
if isinstance(entity, UserEntity): if isinstance(entity, User):
continue continue
elif isinstance(entity, ChatEntity) and entity.deactivated: elif isinstance(entity, Chat) and entity.deactivated:
continue continue
portal = po.Portal.get_by_entity(entity) portal = po.Portal.get_by_entity(entity)
portal.create_room(self, entity, invites=[self.mxid]) portal.create_room(self, entity, invites=[self.mxid])
@@ -133,12 +132,27 @@ class User:
self.log.exception("Failed to handle Telegram update") self.log.exception("Failed to handle Telegram update")
def update(self, update): def update(self, update):
if isinstance(update, UpdateShortChatMessage): update_type = type(update)
if update_type == UpdateShortChatMessage:
portal = po.Portal.get_by_tgid(update.chat_id, "chat") portal = po.Portal.get_by_tgid(update.chat_id, "chat")
sender = pu.Puppet.get(update.from_id) sender = pu.Puppet.get(update.from_id)
elif isinstance(update, UpdateShortMessage): elif update_type == UpdateShortMessage:
portal = po.Portal.get_by_tgid(update.user_id, "user") portal = po.Portal.get_by_tgid(update.user_id, "user")
sender = pu.Puppet.get(self.tgid if update.out else update.user_id) sender = pu.Puppet.get(self.tgid if update.out else update.user_id)
elif update_type == UpdateChatUserTyping or update_type == UpdateUserTyping:
if update_type == UpdateUserTyping:
portal = po.Portal.get_by_tgid(update.user_id, "user")
else:
portal = po.Portal.get_by_tgid(update.chat_id, "chat")
sender = pu.Puppet.get(update.user_id)
return portal.handle_telegram_typing(sender, update)
elif update_type == UpdateUserStatus:
puppet = pu.Puppet.get(update.user_id)
if isinstance(update.status, UserStatusOnline):
puppet.intent.set_presence("online")
elif isinstance(update.status, UserStatusOffline):
puppet.intent.set_presence("offline")
return
else: else:
self.log.debug("Unhandled update: %s", update) self.log.debug("Unhandled update: %s", update)
return return