Improve and/or break things
This commit is contained in:
@@ -19,6 +19,8 @@ appservice:
|
|||||||
bridge:
|
bridge:
|
||||||
# ${ID} is replaced with the user ID of the Telegram user.
|
# ${ID} is replaced with the user ID of the Telegram user.
|
||||||
username_template: "telegram_${ID}"
|
username_template: "telegram_${ID}"
|
||||||
|
# ${DISPLAYNAME} is replaced with the display name of the Telegram user.
|
||||||
|
displayname_template: "${DISPLAYNAME} (Telegram)"
|
||||||
bot_username: telegrambot
|
bot_username: telegrambot
|
||||||
# The displayname to set to the bot automatically.
|
# The displayname to set to the bot automatically.
|
||||||
bot_displayname: Telegram Bridge
|
bot_displayname: Telegram Bridge
|
||||||
|
|||||||
+21
-13
@@ -56,6 +56,7 @@ class MautrixTelegram {
|
|||||||
const user = MatrixUser.fromEntry(this, entry)
|
const user = MatrixUser.fromEntry(this, entry)
|
||||||
this.matrixUsersByID.set(entry.id, user)
|
this.matrixUsersByID.set(entry.id, user)
|
||||||
}
|
}
|
||||||
|
// FIXME this doesn't work for setting the displayname of the bot.
|
||||||
// .then(() =>
|
// .then(() =>
|
||||||
// this.botIntent.setDisplayName(this.config.bridge.bot_displayname))
|
// this.botIntent.setDisplayName(this.config.bridge.bot_displayname))
|
||||||
}
|
}
|
||||||
@@ -198,13 +199,13 @@ class MautrixTelegram {
|
|||||||
|
|
||||||
putRoom(room) {
|
putRoom(room) {
|
||||||
const entry = room.toEntry()
|
const entry = room.toEntry()
|
||||||
return this.bridge.getUserStore().upsert({
|
return this.bridge.getRoomStore().upsert({
|
||||||
type: entry.type,
|
type: entry.type,
|
||||||
id: entry.id,
|
id: entry.id,
|
||||||
}, entry)
|
}, entry)
|
||||||
}
|
}
|
||||||
|
|
||||||
handleMatrixEvent(evt) {
|
async handleMatrixEvent(evt) {
|
||||||
const asBotID = this.bridge.getBot().getUserId()
|
const asBotID = this.bridge.getBot().getUserId()
|
||||||
if (evt.type === "m.room.member" && evt.state_key === asBotID) {
|
if (evt.type === "m.room.member" && evt.state_key === asBotID) {
|
||||||
if (evt.content.membership === "invite") {
|
if (evt.content.membership === "invite") {
|
||||||
@@ -219,27 +220,34 @@ class MautrixTelegram {
|
|||||||
}
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if (evt.sender === asBotID || evt.type !== "m.room.message" || !evt.content) {
|
if (evt.sender === asBotID || evt.type !== "m.room.message" || !evt.content) {
|
||||||
// Ignore own messages and non-message events.
|
// Ignore own messages and non-message events.
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const cmdprefix = this.config.bridge.command_prefix
|
const cmdprefix = this.config.bridge.command_prefix
|
||||||
if (evt.content.body.startsWith(cmdprefix + " ")) {
|
if (evt.content.body.startsWith(cmdprefix + " ")) {
|
||||||
this.getMatrixUser(evt.sender).then(user => {
|
const user = await this.getMatrixUser(evt.sender)
|
||||||
if (!user.whitelisted) {
|
if (!user.whitelisted) {
|
||||||
this.botIntent.sendText(evt.room_id, "You are not authorized to use this bridge.")
|
this.botIntent.sendText(evt.room_id, "You are not authorized to use this bridge.")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
const prefixLength = cmdprefix.length + 1
|
const prefixLength = cmdprefix.length + 1
|
||||||
const args = evt.content.body.substr(prefixLength).split(" ")
|
const args = evt.content.body.substr(prefixLength).split(" ")
|
||||||
const command = args.shift()
|
const command = args.shift()
|
||||||
commands.run(user, command, args, reply =>
|
commands.run(user, command, args, reply =>
|
||||||
this.botIntent.sendText(
|
this.botIntent.sendText(
|
||||||
evt.room_id,
|
evt.room_id,
|
||||||
reply.replace("$cmdprefix", cmdprefix)),
|
reply.replace("$cmdprefix", cmdprefix)),
|
||||||
this)
|
this)
|
||||||
})
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
const portal = await this.getPortalByRoomID(evt.room_id)
|
||||||
|
if (portal) {
|
||||||
|
portal.handleMatrixEvent(evt)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -113,7 +113,6 @@ commands.login = async (sender, args, reply) => {
|
|||||||
action: "Phone code authentication",
|
action: "Phone code authentication",
|
||||||
next: enterCode,
|
next: enterCode,
|
||||||
}
|
}
|
||||||
console.log(data)
|
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
reply(`Failed to send code: ${err}`)
|
reply(`Failed to send code: ${err}`)
|
||||||
console.log(err)
|
console.log(err)
|
||||||
|
|||||||
@@ -116,13 +116,19 @@ class MatrixUser {
|
|||||||
|
|
||||||
async syncDialogs() {
|
async syncDialogs() {
|
||||||
const dialogs = await this.telegramPuppet.client("messages.getDialogs", {})
|
const dialogs = await this.telegramPuppet.client("messages.getDialogs", {})
|
||||||
|
let changed = false
|
||||||
for (const dialog of dialogs.chats) {
|
for (const dialog of dialogs.chats) {
|
||||||
|
if (dialog._ === "chatForbidden" || dialog.deactivated) {
|
||||||
|
continue
|
||||||
|
}
|
||||||
const peer = new TelegramPeer(dialog._, dialog.id)
|
const peer = new TelegramPeer(dialog._, dialog.id)
|
||||||
const portal = await this.app.getPortalByPeer(peer)
|
const portal = await this.app.getPortalByPeer(peer)
|
||||||
if (portal.updateInfo(this.telegramPuppet, dialog)) {
|
if (portal.updateInfo(this.telegramPuppet, dialog)) {
|
||||||
portal.save()
|
portal.save()
|
||||||
|
changed = true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
return changed
|
||||||
}
|
}
|
||||||
|
|
||||||
async sendTelegramCode(phoneNumber) {
|
async sendTelegramCode(phoneNumber) {
|
||||||
|
|||||||
+52
-17
@@ -25,6 +25,10 @@ class Portal {
|
|||||||
this.accessHashes = new Map()
|
this.accessHashes = new Map()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
get id() {
|
||||||
|
return this.peer.id
|
||||||
|
}
|
||||||
|
|
||||||
static fromEntry(app, entry) {
|
static fromEntry(app, entry) {
|
||||||
if (entry.type !== "portal") {
|
if (entry.type !== "portal") {
|
||||||
throw new Error("MatrixUser can only be created from entry type \"portal\"")
|
throw new Error("MatrixUser can only be created from entry type \"portal\"")
|
||||||
@@ -37,43 +41,74 @@ class Portal {
|
|||||||
return portal
|
return portal
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async syncParticipants(participants) {
|
||||||
|
for (const participant of participants) {
|
||||||
|
const user = this.app.getTelegramUser(participant.id)
|
||||||
|
if (user.updateInfo(participant)) {
|
||||||
|
user.save()
|
||||||
|
}
|
||||||
|
user.intent.join(this.roomID)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
handleMatrixEvent(evt) {
|
||||||
|
console.log("Received message from Matrix to portal with room ID", this.roomID)
|
||||||
|
console.log(evt)
|
||||||
|
}
|
||||||
|
|
||||||
async createMatrixRoom(telegramPOV) {
|
async createMatrixRoom(telegramPOV) {
|
||||||
if (this.roomID) {
|
if (this.roomID) {
|
||||||
return
|
return this.roomID
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
await this.peer.getInfo(telegramPOV)
|
const {info, participants} = await this.peer.getInfo(telegramPOV)
|
||||||
|
console.log(JSON.stringify(info, "", " "))
|
||||||
|
console.log(JSON.stringify(participants, "", " "))
|
||||||
|
|
||||||
|
const room = await this.app.botIntent.createRoom({
|
||||||
|
options: {
|
||||||
|
name: info.title,
|
||||||
|
visibility: "private",
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
this.roomID = room.room_id
|
||||||
|
this.app.portalsByRoomID.set(this.roomID, this)
|
||||||
|
await this.save()
|
||||||
|
|
||||||
|
// TODO other things?
|
||||||
|
|
||||||
|
return this.roomID
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
console.error(err)
|
console.error(err)
|
||||||
console.error(err.stack)
|
console.error(err.stack)
|
||||||
|
return undefined
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
updateInfo(telegramPOV, dialog) {
|
updateInfo(telegramPOV, dialog) {
|
||||||
let changed = false
|
let changed = false
|
||||||
if (this.peer.type === "channel") {
|
if (this.peer.type === "channel") {
|
||||||
|
if (telegramPOV && this.accessHashes.get(telegramPOV.userID) !== +dialog.access_hash) {
|
||||||
|
this.accessHashes.set(telegramPOV.userID, +dialog.access_hash)
|
||||||
|
changed = true
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (telegramPOV && this.accessHashes.get(telegramPOV.userID) !== +dialog.access_hash) {
|
return this.peer.updateInfo(dialog) || changed
|
||||||
this.accessHashes.set(telegramPOV.userID, +dialog.access_hash)
|
|
||||||
changed = true
|
|
||||||
}
|
|
||||||
if (this.title !== dialog.title) {
|
|
||||||
this.title = dialog.title
|
|
||||||
changed = true
|
|
||||||
}
|
|
||||||
return changed
|
|
||||||
}
|
}
|
||||||
|
|
||||||
toEntry() {
|
toEntry() {
|
||||||
return {
|
return {
|
||||||
type: this.type,
|
type: this.type,
|
||||||
id: this.roomID,
|
id: this.id,
|
||||||
peer: this.peer.toSubentry(),
|
data: {
|
||||||
accessHashes: this.peer.type === "channel"
|
roomID: this.roomID,
|
||||||
? Array.from(this.accessHashes)
|
peer: this.peer.toSubentry(),
|
||||||
: undefined,
|
accessHashes: this.peer.type === "channel"
|
||||||
|
? Array.from(this.accessHashes)
|
||||||
|
: undefined,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+24
-3
@@ -19,6 +19,8 @@ class TelegramPeer {
|
|||||||
this.type = type
|
this.type = type
|
||||||
this.id = id
|
this.id = id
|
||||||
this.accessHash = +(accessHash || 0)
|
this.accessHash = +(accessHash || 0)
|
||||||
|
this.username = undefined
|
||||||
|
this.title = undefined
|
||||||
}
|
}
|
||||||
|
|
||||||
static fromTelegramData(peer) {
|
static fromTelegramData(peer) {
|
||||||
@@ -52,7 +54,21 @@ class TelegramPeer {
|
|||||||
}
|
}
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
updateInfo(dialog) {
|
||||||
|
let changed = false
|
||||||
|
if (this.type === "channel") {
|
||||||
|
if (this.username !== dialog.username) {
|
||||||
|
this.username = dialog.username
|
||||||
|
changed = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (this.title !== dialog.title) {
|
||||||
|
this.title = dialog.title
|
||||||
|
changed = true
|
||||||
|
}
|
||||||
|
return changed
|
||||||
}
|
}
|
||||||
|
|
||||||
async getInfo(telegramPOV) {
|
async getInfo(telegramPOV) {
|
||||||
@@ -64,6 +80,7 @@ class TelegramPeer {
|
|||||||
info = await telegramPOV.client("messages.getFullChat", {
|
info = await telegramPOV.client("messages.getFullChat", {
|
||||||
chat_id: this.id,
|
chat_id: this.id,
|
||||||
})
|
})
|
||||||
|
participants = info.users
|
||||||
break
|
break
|
||||||
case "channel":
|
case "channel":
|
||||||
// FIXME I'm broken (Error: CHANNEL_INVALID)
|
// FIXME I'm broken (Error: CHANNEL_INVALID)
|
||||||
@@ -80,8 +97,7 @@ class TelegramPeer {
|
|||||||
default:
|
default:
|
||||||
throw new Error(`Unknown peer type ${this.type}`)
|
throw new Error(`Unknown peer type ${this.type}`)
|
||||||
}
|
}
|
||||||
console.log(JSON.stringify(info, "", " "))
|
return { info, participants }
|
||||||
console.log(JSON.stringify(participants, "", " "))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
toInputPeer() {
|
toInputPeer() {
|
||||||
@@ -121,13 +137,18 @@ class TelegramPeer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static fromSubentry(entry) {
|
static fromSubentry(entry) {
|
||||||
return new TelegramPeer(entry.type, entry.id)
|
const peer = new TelegramPeer(entry.type, entry.id)
|
||||||
|
peer.username = entry.username
|
||||||
|
peer.title = entry.title
|
||||||
|
return peer
|
||||||
}
|
}
|
||||||
|
|
||||||
toSubentry() {
|
toSubentry() {
|
||||||
return {
|
return {
|
||||||
type: this.type,
|
type: this.type,
|
||||||
id: this.id,
|
id: this.id,
|
||||||
|
username: this.username,
|
||||||
|
title: this.title,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+12
-5
@@ -136,7 +136,8 @@ class TelegramPuppet {
|
|||||||
})
|
})
|
||||||
return this.signInComplete(result)
|
return this.signInComplete(result)
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
if (err.message !== "SESSION_PASSWORD_NEEDED") {
|
if (err.type !== "SESSION_PASSWORD_NEEDED" && err.message !== "SESSION_PASSWORD_NEEDED") {
|
||||||
|
console.error("Unknown login error:", JSON.stringify(err, "", " "))
|
||||||
throw err
|
throw err
|
||||||
}
|
}
|
||||||
const password = await
|
const password = await
|
||||||
@@ -156,7 +157,8 @@ class TelegramPuppet {
|
|||||||
|
|
||||||
getDisplayName() {
|
getDisplayName() {
|
||||||
if (this.data.firstName || this.data.lastName) {
|
if (this.data.firstName || this.data.lastName) {
|
||||||
return `${this.data.firstName} ${this.data.lastName}`
|
return [this.firstName, this.lastName].filter(s => !!s)
|
||||||
|
.join(" ")
|
||||||
} else if (this.data.username) {
|
} else if (this.data.username) {
|
||||||
return this.data.username
|
return this.data.username
|
||||||
}
|
}
|
||||||
@@ -285,10 +287,15 @@ class TelegramPuppet {
|
|||||||
console.error("Failed to update contacts:", err)
|
console.error("Failed to update contacts:", err)
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
console.log("Syncing dialogs...")
|
console.log("Updating dialogs...")
|
||||||
await this.matrixUser.syncDialogs()
|
const changed = await this.matrixUser.syncDialogs()
|
||||||
|
if (!changed) {
|
||||||
|
console.log("Dialogs were up-to-date")
|
||||||
|
} else {
|
||||||
|
console.log("Dialogs updated")
|
||||||
|
}
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
console.error("Failed to sync dialogs:", err)
|
console.error("Failed to update dialogs:", err)
|
||||||
}
|
}
|
||||||
setInterval(async () => {
|
setInterval(async () => {
|
||||||
try {
|
try {
|
||||||
|
|||||||
Reference in New Issue
Block a user