Improve some handlers and auto-create rooms on message

This commit is contained in:
Tulir Asokan
2017-11-30 18:25:02 +02:00
parent 4fca37f4dc
commit 06a1b0a79e
2 changed files with 87 additions and 50 deletions
+73 -47
View File
@@ -143,14 +143,19 @@ class Portal {
async handleTelegramMessage(evt) { async handleTelegramMessage(evt) {
if (!this.isMatrixRoomCreated()) { if (!this.isMatrixRoomCreated()) {
// FIXME room creation is disabled due to possibility of multiple messages causing duplicate rooms try {
// await this.createMatrixRoom(evt.source, { invite: [evt.source.matrixUser.userID] }) const result = await this.createMatrixRoom(evt.source, { invite: [evt.source.matrixUser.userID] })
console.warn("Room not created!", this) if (!result.roomID) {
return return
}
} catch (err) {
console.error("Error creating room:", err)
console.error(err.stack)
}
} }
const sender = await this.app.getTelegramUser(evt.from) const sender = await this.app.getTelegramUser(evt.from)
await sender.intent.sendTyping(this.roomID, false/*, 5500*/) await sender.intent.sendTyping(this.roomID, false)
// TODO handle other content types
if (evt.text.length > 0) { if (evt.text.length > 0) {
if (evt.entities) { if (evt.entities) {
evt.html = formatter.telegramToMatrix(evt.text, evt.entities) evt.html = formatter.telegramToMatrix(evt.text, evt.entities)
@@ -159,6 +164,7 @@ class Portal {
sender.sendText(this.roomID, evt.text) sender.sendText(this.roomID, evt.text)
} }
} }
if (evt.photo) { if (evt.photo) {
const photo = await this.copyTelegramPhoto(evt.source, sender, evt.photo) const photo = await this.copyTelegramPhoto(evt.source, sender, evt.photo)
photo.name = evt.caption || "Uploaded photo" photo.name = evt.caption || "Uploaded photo"
@@ -168,9 +174,9 @@ class Portal {
const file = await this.copyTelegramFile(evt.source, sender, evt.document) const file = await this.copyTelegramFile(evt.source, sender, evt.document)
if (evt.caption) { if (evt.caption) {
file.name = evt.caption file.name = evt.caption
} else if (evt.matrixtype === "m.audio") { } else if (file.matrixtype === "m.audio") {
file.name = "Uploaded audio" file.name = "Uploaded audio"
} else if (evt.matrixtype === "m.video") { } else if (file.matrixtype === "m.video") {
file.name = "Uploaded video" file.name = "Uploaded video"
} else { } else {
file.name = "Uploaded document" file.name = "Uploaded document"
@@ -219,7 +225,7 @@ class Portal {
? (await this.app.getTelegramUser(this.peer.id)).intent ? (await this.app.getTelegramUser(this.peer.id)).intent
: this.app.botIntent : this.app.botIntent
for (const userID of invite) { for (const userID of invite) {
// TODO check membership before inviting // TODO check membership before inviting?
intent.invite(this.roomID, userID) intent.invite(this.roomID, userID)
} }
} }
@@ -228,51 +234,69 @@ class Portal {
roomID: this.roomID, roomID: this.roomID,
} }
} }
if (this.creatingMatrixRoom) {
console.log("Ongoing room creation detected!")
await new Promise(resolve => setTimeout(resolve, 1000))
console.log("Ongoing room creation waited for,", this.roomID)
return {
created: false,
roomID: this.roomID,
}
}
this.creatingMatrixRoom = true
if (!await this.loadAccessHash(telegramPOV)) { if (!await this.loadAccessHash(telegramPOV)) {
this.creatingMatrixRoom = false
throw new Error("Failed to load access hash.") throw new Error("Failed to load access hash.")
} }
let room let room, info, users
const { info, users } = await this.peer.getInfo(telegramPOV) try {
if (this.peer.type === "chat") { ({ info, users } = await this.peer.getInfo(telegramPOV))
room = await this.app.botIntent.createRoom({ if (this.peer.type === "chat") {
options: { room = await this.app.botIntent.createRoom({
name: info.title, options: {
topic: info.about, name: info.title,
visibility: "private", topic: info.about,
invite, visibility: "private",
}, invite,
}) },
} else if (this.peer.type === "channel") { })
room = await this.app.botIntent.createRoom({ } else if (this.peer.type === "channel") {
options: { room = await this.app.botIntent.createRoom({
name: info.title, options: {
topic: info.about, name: info.title,
visibility: info.username ? "public" : "private", topic: info.about,
room_alias_name: info.username visibility: info.username ? "public" : "private",
? this.app.config.bridge.alias_template.replace("${NAME}", info.username) room_alias_name: info.username
: undefined, ? this.app.config.bridge.alias_template.replace("${NAME}", info.username)
invite, : undefined,
}, invite,
}) },
} else if (this.peer.type === "user") { })
const user = await this.app.getTelegramUser(info.id) } else if (this.peer.type === "user") {
await user.updateInfo(telegramPOV, info, { updateAvatar: true }) const user = await this.app.getTelegramUser(info.id)
room = await user.intent.createRoom({ await user.updateInfo(telegramPOV, info, { updateAvatar: true })
createAsClient: true, room = await user.intent.createRoom({
options: { createAsClient: true,
//name: user.getDisplayName(), options: {
topic: "Telegram private chat", //name: user.getDisplayName(),
visibility: "private", topic: "Telegram private chat",
invite, visibility: "private",
}, invite,
}) },
} else { })
throw new Error(`Unrecognized peer type: ${this.peer.type}`) } else {
this.creatingMatrixRoom = false
throw new Error(`Unrecognized peer type: ${this.peer.type}`)
}
} catch (err) {
this.creatingMatrixRoom = false
throw err instanceof Error ? err : new Error(err)
} }
this.roomID = room.room_id this.roomID = room.room_id
this.creatingMatrixRoom = false
this.app.portalsByRoomID.set(this.roomID, this) this.app.portalsByRoomID.set(this.roomID, this)
await this.save() await this.save()
if (this.peer.type !== "user") { if (this.peer.type !== "user") {
@@ -281,7 +305,9 @@ class Portal {
await this.updateAvatar(telegramPOV, info) await this.updateAvatar(telegramPOV, info)
} catch (err) { } catch (err) {
console.error(err) console.error(err)
console.error(err.stack) if (err instanceof Error) {
console.error(err.stack)
}
} }
} }
return { return {
+14 -3
View File
@@ -232,17 +232,28 @@ class TelegramPuppet {
} }
} }
async sendMessage(peer, message, entities = undefined) { async sendMessage(peer, message, entities) {
const result = await this.client("messages.sendMessage", { if (!message) {
throw new Error("Invalid parameter: message is undefined.")
}
const payload = {
peer: peer.toInputPeer(), peer: peer.toInputPeer(),
message, message,
entities, entities,
random_id: ~~(Math.random() * (1 << 30)), random_id: ~~(Math.random() * (1 << 30)),
}) }
if (!payload.entities) {
// Everything breaks if we send undefined things :/
delete payload.entities
}
const result = await this.client("messages.sendMessage", payload)
return result return result
} }
async sendMedia(peer, media) { async sendMedia(peer, media) {
if (!media) {
throw new Error("Invalid parameter: media is undefined.")
}
const result = await this.client("messages.sendMedia", { const result = await this.client("messages.sendMedia", {
peer: peer.toInputPeer(), peer: peer.toInputPeer(),
media, media,