Improve user handling and add link join handling. Fixes #23
This commit is contained in:
+41
-15
@@ -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
@@ -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._)
|
||||
|
||||
Reference in New Issue
Block a user