Improve user handling and add link join handling. Fixes #23

This commit is contained in:
Tulir Asokan
2018-01-14 19:45:58 +02:00
parent 9b4af60830
commit a49407e358
2 changed files with 91 additions and 45 deletions
+41 -15
View File
@@ -214,6 +214,42 @@ class Portal {
typer.intent.sendTyping(this.roomID, true/*, 5500*/)
}
/**
* Add a Telegram user to this room.
*
* This makes the Matrix puppet of that Telegram user join this room. If the Telegram user is also a puppet
* controlled by a Matrix user, that Matrix user is invited as well.
*
* @param {number} userID The Telegram ID of the user to add.
*/
async addUser(userID) {
const matrixUser = await this.app.getMatrixUserByTelegramID(userID)
if (matrixUser) {
matrixUser.join(this)
this.inviteMatrix(matrixUser.userID)
}
const telegramUser = await this.app.getTelegramUser(userID)
await telegramUser.intent.join(this.roomID)
}
/**
* Remove a Telegram user from this room.
*
* This makes the Matrix puppet of the given Telegram user leave this room. If the Telegram user is also a puppet
* controlled by a Matrix user, that Matrix user is kicked with the message "Left Telegram chat".
*
* @param {number} userID The Telegram ID of the user to remove.
*/
async deleteUser(userID) {
const matrixUser = await this.app.getMatrixUserByTelegramID(userID)
if (matrixUser) {
matrixUser.leave(this)
this.kickMatrix(matrixUser.userID, "Left Telegram chat")
}
const telegramUser = await this.app.getTelegramUser(userID)
telegramUser.intent.leave(this.roomID)
}
/**
* Handle a Telegram service message event.
*
@@ -242,22 +278,18 @@ class Portal {
}
}
this.lastMessageIDs.set(evt.source.userID, evt.id)
let matrixUser, telegramUser
switch (evt.action._) {
case "messageActionChatCreate":
// Portal gets created at beginning if it doesn't exist
// Falls through to invite everyone in initial user list
case "messageActionChatAddUser":
for (const userID of evt.action.users) {
matrixUser = await this.app.getMatrixUserByTelegramID(userID)
if (matrixUser) {
matrixUser.join(this)
this.inviteMatrix(matrixUser.userID)
}
telegramUser = await this.app.getTelegramUser(userID)
telegramUser.intent.join(this.roomID)
await this.addUser(userID)
}
break
case "messageActionChatJoinedByLink":
await this.addUser(evt.from)
break
case "messageActionChannelCreate":
// Portal gets created at beginning if it doesn't exist
// Channels don't send initial user lists 3:<
@@ -276,13 +308,7 @@ class Portal {
await sender.sendEmote(this.roomID, "upgraded this group to a supergroup.")
break
case "messageActionChatDeleteUser":
matrixUser = await this.app.getMatrixUserByTelegramID(evt.action.user_id)
if (matrixUser) {
matrixUser.leave(this)
this.kickMatrix(matrixUser.userID, "Left Telegram chat")
}
telegramUser = await this.app.getTelegramUser(evt.action.user_id)
telegramUser.intent.leave(this.roomID)
await this.deleteUser(evt.action.user_id)
break
case "messageActionChatEditPhoto":
const sizes = evt.action.photo.sizes
+50 -30
View File
@@ -386,7 +386,53 @@ class TelegramPuppet {
})
}
async receiveUsers(users) {
this.app.debug("green", "Handling received users:", JSON.stringify(users, "", " "))
for (const user of users) {
const telegramUser = await this.app.getTelegramUser(user.id)
await telegramUser.updateInfo(this, user, true)
}
}
async receiveChats(chats) {
this.app.debug("green", "Handling received chats:", JSON.stringify(chats, "", " "))
for (const chat of chats) {
const peer = new TelegramPeer(chat._, chat.id, {
accessHash: chat.access_hash,
})
const portal = await this.app.getPortalByPeer(peer)
await portal.updateInfo(this, chat)
}
}
async handleUpdatesTooLong() {
this.app.debug("magenta", "Handling updatesTooLong", this.pts, this.date)
const dat = await this.client("updates.getDifference", {
pts: this.pts,
date: this.date,
qts: -1,
})
if (dat._ === "updates.differenceEmpty") {
this.date = dat.date
return
}
this.app.debug("magenta", `updates.getDifference: ${JSON.stringify(dat, "", " ")}`)
// TODO use dat.users and dat.chats
await this.receiveUsers(dat.users)
await this.receiveChats(dat.chats)
this.pts = dat.state.pts
this.date = dat.state.date
for (const message of dat.new_messages) {
await this.onUpdate({
_: "updateNewMessage",
pts: this.pts,
message,
})
}
for (const update of dat.other_updates) {
await this.onUpdate(update)
}
}
async handleUpdate(data) {
if (!data.update || data.update._ !== "updateUserStatus") {
@@ -399,15 +445,12 @@ class TelegramPuppet {
await this.onUpdate(data.update)
break
case "updates":
// TODO use data.users and data.chats
this.app.debug("green", "Received updates users:", JSON.stringify(data.users, "", " "))
this.app.debug("green", "Received updates chats:", JSON.stringify(data.chats, "", " "))
this.date = data.date
const updateHandlers = []
await this.receiveUsers(data.users)
await this.receiveChats(data.chats)
for (const update of data.updates) {
updateHandlers.push(this.onUpdate(update))
await this.onUpdate(update)
}
await Promise.all(updateHandlers)
break
case "updateShortMessage":
case "updateShortChatMessage":
@@ -418,30 +461,7 @@ class TelegramPuppet {
this.app.warn("updatesTooLong received, but we don't have a persistent timestamp :(")
break
}
this.app.debug("magenta", "Handling updatesTooLong", this.pts, this.date)
const dat = await this.client("updates.getDifference", {
pts: this.pts,
date: this.date,
qts: -1,
})
if (dat._ === "updates.differenceEmpty") {
this.date = dat.date
break
}
this.app.debug("magenta", `updates.getDifference: ${JSON.stringify(dat, "", " ")}`)
// TODO use dat.users and dat.chats
this.pts = dat.state.pts
this.date = dat.state.date
for (const message of dat.new_messages) {
this.onUpdate({
_: "updateNewMessage",
pts: this.pts,
message,
})
}
for (const update of dat.other_updates) {
this.onUpdate(update)
}
await this.handleUpdatesTooLong()
break
default:
this.app.warn("Unrecognized update type:", data._)