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
+36 -10
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,13 +234,25 @@ 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 {
({ info, users } = await this.peer.getInfo(telegramPOV))
if (this.peer.type === "chat") { if (this.peer.type === "chat") {
room = await this.app.botIntent.createRoom({ room = await this.app.botIntent.createRoom({
options: { options: {
@@ -269,10 +287,16 @@ class Portal {
}, },
}) })
} else { } else {
this.creatingMatrixRoom = false
throw new Error(`Unrecognized peer type: ${this.peer.type}`) 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,9 +305,11 @@ class Portal {
await this.updateAvatar(telegramPOV, info) await this.updateAvatar(telegramPOV, info)
} catch (err) { } catch (err) {
console.error(err) console.error(err)
if (err instanceof Error) {
console.error(err.stack) console.error(err.stack)
} }
} }
}
return { return {
created: true, created: true,
roomID: this.roomID, roomID: this.roomID,
+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,