Add supergroup upgrade handling and experimental updatesTooLong handling

This commit is contained in:
Tulir Asokan
2017-12-03 11:29:32 +02:00
parent 70075352d2
commit 00c26eef86
5 changed files with 95 additions and 7 deletions
+1 -1
View File
@@ -94,5 +94,5 @@ does not do this automatically.
* [ ] Creating Telegram chats for existing Matrix rooms
* Misc
* [ ] Use optional bot to relay messages for unauthenticated Matrix users
* [ ] Properly handle upgrading groups to supergroups
* [x] Properly handle upgrading groups to supergroups
* [ ] Handle public channel username changes
+24 -2
View File
@@ -221,10 +221,19 @@ class Portal {
* MessageAction} object.
*/
async handleTelegramServiceMessage(evt) {
if (!this.isMatrixRoomCreated()) {
if (evt.action._ === "messageActionChatDeleteUser") {
// We don't care about user deletions on chats without portals
return
}
console.log("Service message received, creating room for", evt.to.id)
await this.createMatrixRoom(evt.source, { invite: [evt.source.matrixUser.userID] })
return
}
let matrixUser, telegramUser
switch (evt.action._) {
case "messageActionChatCreate":
await this.createMatrixRoom(evt.source, { invite: [evt.source.matrixUser.userID] })
// 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) {
@@ -238,8 +247,21 @@ class Portal {
}
break
case "messageActionChannelCreate":
// Portal gets created at beginning if it doesn't exist
// Channels don't send initial user lists 3:<
await this.createMatrixRoom(evt.source, { invite: [evt.source.matrixUser.userID] })
break
case "messageActionChatMigrateTo":
this.peer.id = evt.action.channel_id
this.peer.type = "channel"
const accessHash = await this.peer.fetchAccessHashFromServer(evt.source)
if (!accessHash) {
console.error("Failed to fetch access hash for mirgrated channel!")
break
}
this.accessHashes.set(evt.source.userID, accessHash)
await this.save()
const sender = await this.app.getTelegramUser(evt.from)
await sender.sendEmote(this.roomID, "upgraded this group to a supergroup.")
break
case "messageActionChatDeleteUser":
matrixUser = await this.app.getMatrixUserByTelegramID(evt.action.user_id)
+27
View File
@@ -108,6 +108,33 @@ class TelegramPeer {
return changed
}
async fetchAccessHashFromServer(telegramPOV) {
const data = await this.getInfoFromDialogs(telegramPOV)
if (!data) {
return undefined
}
this.accessHash = data.access_hash
return this.accessHash
}
async getInfoFromDialogs(telegramPOV) {
const dialogs = await telegramPOV.client("messages.getDialogs", {})
if (this.type === "user") {
for (const user of dialogs.users) {
if (user.id === this.id) {
return user
}
}
} else {
for (const chat of dialogs.chats) {
if (chat.id === this.id) {
return chat
}
}
}
return undefined
}
/**
* Get info about this peer from the Telegram servers.
*
+29 -4
View File
@@ -96,6 +96,9 @@ class TelegramPuppet {
this.apiHash = api_hash
this.apiID = api_id
this.pts = 0
this.date = 0
this.puppetStorage = {
get: async (key) => {
let value = this.data[key]
@@ -108,7 +111,6 @@ class TelegramPuppet {
if (Array.isArray(value)) {
value = `b64:${Buffer.from(value).toString("base64")}`
}
console.warn("SET", key, "=", JSON.stringify(value))
if (this.data[key] === value) {
return
}
@@ -117,12 +119,10 @@ class TelegramPuppet {
await this.matrixUser.save()
},
remove: async (...keys) => {
console.warn("DEL", JSON.stringify(keys))
keys.forEach((key) => delete this.data[key])
await this.matrixUser.save()
},
clear: async () => {
console.warn("CLR")
this.data = {}
await this.matrixUser.save()
},
@@ -322,19 +322,32 @@ class TelegramPuppet {
// TODO figure out how channel message signing works
from = -1
case "updateNewMessage":
this.pts = update.pts
update = update.message // Message defined at message#90dddc11 in layer 71
from = update.from_id || from
to = TelegramPeer.fromTelegramData(update.to_id, update.from_id, this.userID)
break
case "updateReadMessages":
case "updateDeleteMessages":
case "updateRestoreMessages":
this.pts = update.pts
break
default:
// Unknown update type
console.log(`Update of unknown type ${update._} received:\n${JSON.stringify(update, "", " ")}`)
return
}
if (!to) {
// This shouldn't happen
console.warn("No target found for update", update)
return
}
if (update._ === "messageService" && update.action._ === "messageActionChannelMigrateFrom") {
return
}
portal = await this.app.getPortalByPeer(to)
if (update._ === "messageService") {
await portal.handleTelegramServiceMessage({
from,
@@ -344,6 +357,7 @@ class TelegramPuppet {
})
return
}
console.log(update)
await portal.handleTelegramMessage({
from,
to,
@@ -369,9 +383,11 @@ class TelegramPuppet {
try {
switch (data._) {
case "updateShort":
this.date = data.date
this.onUpdate(data.update)
break
case "updates":
this.date = data.date
for (const update of data.updates) {
this.onUpdate(update)
}
@@ -380,6 +396,15 @@ class TelegramPuppet {
case "updateShortChatMessage":
this.onUpdate(data)
break
case "updatesTooLong":
console.log("Handling updatesTooLong")
this.client("updates.getDifference", {
pts: this.pts,
date: this.date,
qts: -1,
}).then(dat => console.log("getDifference", dat),
err => console.error("getDifferenceFail", err))
break
default:
console.log("Unrecognized update type:", data._)
}
+14
View File
@@ -153,6 +153,20 @@ class TelegramUser {
})
}
sendNotice(roomID, text) {
return this.intent.sendMessage(roomID, {
msgtype: "m.notice",
body: text,
})
}
sendEmote(roomID, text) {
return this.intent.sendMessage(roomID, {
msgtype: "m.emote",
body: text,
})
}
sendText(roomID, text) {
return this.intent.sendText(roomID, text)
}