Yet another sync commit
This commit is contained in:
+6
-2
@@ -82,10 +82,14 @@ class MautrixTelegram {
|
|||||||
return portal
|
return portal
|
||||||
}
|
}
|
||||||
|
|
||||||
const entries = await this.bridge.getRoomStore().select({
|
const query = {
|
||||||
type: "portal",
|
type: "portal",
|
||||||
id: peer.id,
|
id: peer.id,
|
||||||
})
|
}
|
||||||
|
if (peer.type === "user") {
|
||||||
|
query.receiverID = peer.receiverID
|
||||||
|
}
|
||||||
|
const entries = await this.bridge.getRoomStore().select(query)
|
||||||
|
|
||||||
// Handle possible db query race conditions
|
// Handle possible db query race conditions
|
||||||
portal = this.portalsByPeerID.get(peer.id)
|
portal = this.portalsByPeerID.get(peer.id)
|
||||||
|
|||||||
+13
-13
@@ -18,17 +18,17 @@ const makePasswordHash = require("telegram-mtproto").plugins.makePasswordHash
|
|||||||
const commands = {}
|
const commands = {}
|
||||||
|
|
||||||
function run(sender, command, args, reply, app) {
|
function run(sender, command, args, reply, app) {
|
||||||
if (sender.commandStatus) {
|
|
||||||
if (command === "cancel") {
|
|
||||||
reply(`${sender.commandStatus.action} cancelled.`)
|
|
||||||
sender.commandStatus = undefined
|
|
||||||
return
|
|
||||||
}
|
|
||||||
args.unshift(command)
|
|
||||||
return sender.commandStatus.next(sender, args, reply, app)
|
|
||||||
}
|
|
||||||
command = this.commands[command]
|
command = this.commands[command]
|
||||||
if (!command) {
|
if (!command) {
|
||||||
|
if (sender.commandStatus) {
|
||||||
|
if (command === "cancel") {
|
||||||
|
reply(`${sender.commandStatus.action} cancelled.`)
|
||||||
|
sender.commandStatus = undefined
|
||||||
|
return
|
||||||
|
}
|
||||||
|
args.unshift(command)
|
||||||
|
return sender.commandStatus.next(sender, args, reply, app)
|
||||||
|
}
|
||||||
reply("Unknown command. Try \"$cmdprefix help\" for help.")
|
reply("Unknown command. Try \"$cmdprefix help\" for help.")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@@ -60,7 +60,7 @@ syncUsers <type> <id> - Sync user info and join status in the given portal. Same
|
|||||||
/**
|
/**
|
||||||
* Two-factor authentication handler.
|
* Two-factor authentication handler.
|
||||||
*/
|
*/
|
||||||
const enterPassword = async (sender, args, reply) => {
|
commands.enterPassword = async (sender, args, reply) => {
|
||||||
if (args.length === 0) {
|
if (args.length === 0) {
|
||||||
reply("Usage: $cmdprefix <password>")
|
reply("Usage: $cmdprefix <password>")
|
||||||
return
|
return
|
||||||
@@ -80,7 +80,7 @@ const enterPassword = async (sender, args, reply) => {
|
|||||||
/*
|
/*
|
||||||
* Login code send handler.
|
* Login code send handler.
|
||||||
*/
|
*/
|
||||||
const enterCode = async (sender, args, reply) => {
|
commands.enterCode = async (sender, args, reply) => {
|
||||||
if (args.length === 0) {
|
if (args.length === 0) {
|
||||||
reply("Usage: $cmdprefix <authentication code>")
|
reply("Usage: $cmdprefix <authentication code>")
|
||||||
return
|
return
|
||||||
@@ -95,7 +95,7 @@ const enterCode = async (sender, args, reply) => {
|
|||||||
reply(`You have two-factor authentication enabled. Password hint: ${data.hint}\nEnter your password using "$cmdprefix <password>"`)
|
reply(`You have two-factor authentication enabled. Password hint: ${data.hint}\nEnter your password using "$cmdprefix <password>"`)
|
||||||
sender.commandStatus = {
|
sender.commandStatus = {
|
||||||
action: "Two-factor authentication",
|
action: "Two-factor authentication",
|
||||||
next: enterPassword,
|
next: commands.enterPassword,
|
||||||
salt: data.salt,
|
salt: data.salt,
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@@ -122,7 +122,7 @@ commands.login = async (sender, args, reply) => {
|
|||||||
reply(`Login code sent to ${args[0]}.\nEnter the code using "$cmdprefix <code>"`)
|
reply(`Login code sent to ${args[0]}.\nEnter the code using "$cmdprefix <code>"`)
|
||||||
sender.commandStatus = {
|
sender.commandStatus = {
|
||||||
action: "Phone code authentication",
|
action: "Phone code authentication",
|
||||||
next: enterCode,
|
next: commands.enterCode ,
|
||||||
}
|
}
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
reply(`Failed to send code: ${err}`)
|
reply(`Failed to send code: ${err}`)
|
||||||
|
|||||||
+22
-6
@@ -29,6 +29,10 @@ class Portal {
|
|||||||
return this.peer.id
|
return this.peer.id
|
||||||
}
|
}
|
||||||
|
|
||||||
|
get receiverID() {
|
||||||
|
return this.peer.receiverID
|
||||||
|
}
|
||||||
|
|
||||||
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\"")
|
||||||
@@ -51,7 +55,7 @@ class Portal {
|
|||||||
}
|
}
|
||||||
for (const userData of users) {
|
for (const userData of users) {
|
||||||
const user = await this.app.getTelegramUser(userData.id)
|
const user = await this.app.getTelegramUser(userData.id)
|
||||||
await user.updateInfo(telegramPOV, userData)
|
await user.updateInfo(telegramPOV, userData, true)
|
||||||
await user.intent.join(this.roomID)
|
await user.intent.join(this.roomID)
|
||||||
}
|
}
|
||||||
return true
|
return true
|
||||||
@@ -92,11 +96,20 @@ class Portal {
|
|||||||
return undefined
|
return undefined
|
||||||
}
|
}
|
||||||
|
|
||||||
const {info, users} = await this.peer.getInfo(telegramPOV)
|
let title, info, users
|
||||||
|
if (this.peer.type !== "user") {
|
||||||
|
({info, users} = await this.peer.getInfo(telegramPOV))
|
||||||
|
title = info.title
|
||||||
|
} else {
|
||||||
|
({info} = await this.peer.getInfo(telegramPOV))
|
||||||
|
users = await this.app.getTelegramUser(info.id)
|
||||||
|
await users.updateInfo(telegramPOV, info)
|
||||||
|
title = users.getDisplayName()
|
||||||
|
}
|
||||||
|
|
||||||
const room = await this.app.botIntent.createRoom({
|
const room = await this.app.botIntent.createRoom({
|
||||||
options: {
|
options: {
|
||||||
name: info.title,
|
name: title,
|
||||||
visibility: "private",
|
visibility: "private",
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
@@ -104,9 +117,11 @@ class Portal {
|
|||||||
this.roomID = room.room_id
|
this.roomID = room.room_id
|
||||||
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") {
|
||||||
await this.syncTelegramUsers(telegramPOV, users)
|
await this.syncTelegramUsers(telegramPOV, users)
|
||||||
|
} else {
|
||||||
|
await users.intent.join(this.roomID)
|
||||||
|
}
|
||||||
return this.roomID
|
return this.roomID
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
console.error(err)
|
console.error(err)
|
||||||
@@ -134,6 +149,7 @@ class Portal {
|
|||||||
return {
|
return {
|
||||||
type: this.type,
|
type: this.type,
|
||||||
id: this.id,
|
id: this.id,
|
||||||
|
receiverID: this.receiverID,
|
||||||
data: {
|
data: {
|
||||||
roomID: this.roomID,
|
roomID: this.roomID,
|
||||||
peer: this.peer.toSubentry(),
|
peer: this.peer.toSubentry(),
|
||||||
|
|||||||
+29
-15
@@ -15,20 +15,21 @@
|
|||||||
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
class TelegramPeer {
|
class TelegramPeer {
|
||||||
constructor(type, id, accessHash) {
|
constructor(type, id, accessHash, receiverID) {
|
||||||
this.type = type
|
this.type = type
|
||||||
this.id = id
|
this.id = id
|
||||||
this.accessHash = accessHash
|
this.accessHash = accessHash
|
||||||
|
this.receiverID = receiverID
|
||||||
this.username = undefined
|
this.username = undefined
|
||||||
this.title = undefined
|
this.title = undefined
|
||||||
}
|
}
|
||||||
|
|
||||||
static fromTelegramData(peer) {
|
static fromTelegramData(peer, receiverID) {
|
||||||
switch(peer._) {
|
switch(peer._) {
|
||||||
case "peerChat":
|
case "peerChat":
|
||||||
return new TelegramPeer("chat", peer.chat_id)
|
return new TelegramPeer("chat", peer.chat_id)
|
||||||
case "peerUser":
|
case "peerUser":
|
||||||
return new TelegramPeer("user", peer.user_id, peer.access_hash)
|
return new TelegramPeer("user", peer.user_id, peer.access_hash, receiverID)
|
||||||
case "peerChannel":
|
case "peerChannel":
|
||||||
return new TelegramPeer("channel", peer.channel_id, peer.access_hash)
|
return new TelegramPeer("channel", peer.channel_id, peer.access_hash)
|
||||||
default:
|
default:
|
||||||
@@ -86,7 +87,11 @@ class TelegramPeer {
|
|||||||
let info, users
|
let info, users
|
||||||
switch(this.type) {
|
switch(this.type) {
|
||||||
case "user":
|
case "user":
|
||||||
throw new Error("Can't get chat info of user")
|
info = await telegramPOV.client("users.getFullUser", {
|
||||||
|
id: this.toInputObject()
|
||||||
|
})
|
||||||
|
users = [info.user]
|
||||||
|
info = info.user
|
||||||
case "chat":
|
case "chat":
|
||||||
info = await telegramPOV.client("messages.getFullChat", {
|
info = await telegramPOV.client("messages.getFullChat", {
|
||||||
chat_id: this.id,
|
chat_id: this.id,
|
||||||
@@ -95,10 +100,10 @@ class TelegramPeer {
|
|||||||
break
|
break
|
||||||
case "channel":
|
case "channel":
|
||||||
info = await telegramPOV.client("channels.getFullChannel", {
|
info = await telegramPOV.client("channels.getFullChannel", {
|
||||||
channel: this.toInputChannel(),
|
channel: this.toInputObject(),
|
||||||
})
|
})
|
||||||
const participants = await telegramPOV.client("channels.getParticipants", {
|
const participants = await telegramPOV.client("channels.getParticipants", {
|
||||||
channel: this.toInputChannel(),
|
channel: this.toInputObject(),
|
||||||
filter: { _: "channelParticipantsRecent" },
|
filter: { _: "channelParticipantsRecent" },
|
||||||
offset: 0,
|
offset: 0,
|
||||||
limit: 1000,
|
limit: 1000,
|
||||||
@@ -138,15 +143,22 @@ class TelegramPeer {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
toInputChannel() {
|
toInputObject() {
|
||||||
if (this.type !== "channel") {
|
switch(this.type) {
|
||||||
throw new Error(`Cannot convert peer of type ${this.type} into an inputChannel`)
|
case "user":
|
||||||
}
|
return {
|
||||||
|
_: "inputUser",
|
||||||
return {
|
user_id: this.id,
|
||||||
_: "inputChannel",
|
access_hash: this.accessHash,
|
||||||
channel_id: this.id,
|
}
|
||||||
access_hash: this.accessHash,
|
case "channel":
|
||||||
|
return {
|
||||||
|
_: "inputChannel",
|
||||||
|
channel_id: this.id,
|
||||||
|
access_hash: this.accessHash,
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
throw new Error(`Unrecognized type ${this.type}`)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -154,6 +166,7 @@ class TelegramPeer {
|
|||||||
const peer = new TelegramPeer(entry.type, entry.id)
|
const peer = new TelegramPeer(entry.type, entry.id)
|
||||||
peer.username = entry.username
|
peer.username = entry.username
|
||||||
peer.title = entry.title
|
peer.title = entry.title
|
||||||
|
peer.receiverID = entry.receiverID
|
||||||
return peer
|
return peer
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -163,6 +176,7 @@ class TelegramPeer {
|
|||||||
id: this.id,
|
id: this.id,
|
||||||
username: this.username,
|
username: this.username,
|
||||||
title: this.title,
|
title: this.title,
|
||||||
|
receiverID: this.receiverID,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+21
-12
@@ -56,6 +56,7 @@ class TelegramPuppet {
|
|||||||
return value
|
return value
|
||||||
},
|
},
|
||||||
set: async (key, value) => {
|
set: async (key, value) => {
|
||||||
|
console.warn("SET", key, "=", JSON.stringify(value))
|
||||||
if (this.data[key] === value) {
|
if (this.data[key] === value) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@@ -64,10 +65,12 @@ class TelegramPuppet {
|
|||||||
await this.matrixUser.save()
|
await this.matrixUser.save()
|
||||||
},
|
},
|
||||||
remove: async (...keys) => {
|
remove: async (...keys) => {
|
||||||
|
console.warn("DEL", JSON.stringify(value))
|
||||||
keys.forEach((key) => delete this.data[key])
|
keys.forEach((key) => delete this.data[key])
|
||||||
await this.matrixUser.save()
|
await this.matrixUser.save()
|
||||||
},
|
},
|
||||||
clear: async () => {
|
clear: async () => {
|
||||||
|
console.warn("CLR")
|
||||||
this.data = {}
|
this.data = {}
|
||||||
await this.matrixUser.save()
|
await this.matrixUser.save()
|
||||||
},
|
},
|
||||||
@@ -225,6 +228,7 @@ class TelegramPuppet {
|
|||||||
console.log("Oh noes! Empty update")
|
console.log("Oh noes! Empty update")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
let peer, portal
|
||||||
switch(update._) {
|
switch(update._) {
|
||||||
case "updateUserStatus":
|
case "updateUserStatus":
|
||||||
const user = await this.app.getTelegramUser(update.user_id)
|
const user = await this.app.getTelegramUser(update.user_id)
|
||||||
@@ -237,25 +241,29 @@ class TelegramPuppet {
|
|||||||
default:
|
default:
|
||||||
status = "offline"
|
status = "offline"
|
||||||
}
|
}
|
||||||
user.intent.getClient().setPresence({presence: status})
|
|
||||||
|
await user.intent.getClient().setPresence({presence: status})
|
||||||
break
|
break
|
||||||
case "updateUserTyping":
|
case "updateUserTyping":
|
||||||
console.log(update.user_id, "is typing in a 1-1 chat")
|
peer = new TelegramPeer("user", update.user_id, undefined, this.userID)
|
||||||
break
|
|
||||||
case "updateChatUserTyping":
|
case "updateChatUserTyping":
|
||||||
console.log(update.user_id, "is typing in", update.chat_id)
|
peer = peer || new TelegramPeer("chat", update.chat_id)
|
||||||
|
portal = await this.app.getPortalByPeer(peer)
|
||||||
|
if (portal.isMatrixRoomCreated()) {
|
||||||
|
const sender = await this.app.getTelegramUser(update.user_id)
|
||||||
|
// The Intent API currently doesn't allow you to set the
|
||||||
|
// typing timeout. If it does, we should set it to ~5.5s as
|
||||||
|
// Telegram resends typing notifications every 5 seconds.
|
||||||
|
await sender.intent.sendTyping(portal.roomID, true/*, 5500*/)
|
||||||
|
}
|
||||||
break
|
break
|
||||||
case "updateShortMessage":
|
case "updateShortMessage":
|
||||||
await this.handleMessage({
|
peer = new TelegramPeer("user", update.user_id, undefined, this.userID)
|
||||||
from: update.user_id,
|
|
||||||
to: new TelegramPeer("user", update.user_id),
|
|
||||||
text: update.message,
|
|
||||||
})
|
|
||||||
break
|
|
||||||
case "updateShortChatMessage":
|
case "updateShortChatMessage":
|
||||||
|
peer = peer || new TelegramPeer("chat", update.chat_id)
|
||||||
await this.handleMessage({
|
await this.handleMessage({
|
||||||
from: update.user_id,
|
from: update.user_id,
|
||||||
to: new TelegramPeer("chat", update.chat_id),
|
to: peer,
|
||||||
text: update.message,
|
text: update.message,
|
||||||
})
|
})
|
||||||
break
|
break
|
||||||
@@ -265,7 +273,7 @@ class TelegramPuppet {
|
|||||||
update = update.message // Message defined at message#90dddc11 in layer 71
|
update = update.message // Message defined at message#90dddc11 in layer 71
|
||||||
await this.handleMessage({
|
await this.handleMessage({
|
||||||
from: update.from_id,
|
from: update.from_id,
|
||||||
to: TelegramPeer.fromTelegramData(update.to_id),
|
to: TelegramPeer.fromTelegramData(update.to_id, this.userID),
|
||||||
text: update.message,
|
text: update.message,
|
||||||
})
|
})
|
||||||
break
|
break
|
||||||
@@ -275,6 +283,7 @@ class TelegramPuppet {
|
|||||||
}
|
}
|
||||||
|
|
||||||
handleUpdate(data) {
|
handleUpdate(data) {
|
||||||
|
console.log("UPDATE", data)
|
||||||
try {
|
try {
|
||||||
switch (data._) {
|
switch (data._) {
|
||||||
case "updateShort":
|
case "updateShort":
|
||||||
|
|||||||
@@ -88,10 +88,8 @@ class TelegramUser {
|
|||||||
|
|
||||||
const userInfo = await this.intent.getProfileInfo(this.mxid, "displayname")
|
const userInfo = await this.intent.getProfileInfo(this.mxid, "displayname")
|
||||||
if (userInfo.displayname !== this.getDisplayName()) {
|
if (userInfo.displayname !== this.getDisplayName()) {
|
||||||
console.log(userInfo.displayname)
|
|
||||||
this.intent.setDisplayName(
|
this.intent.setDisplayName(
|
||||||
this.app.config.bridge.displayname_template.replace("${DISPLAYNAME}", this.getDisplayName()))
|
this.app.config.bridge.displayname_template.replace("${DISPLAYNAME}", this.getDisplayName()))
|
||||||
console.log((await this.intent.getProfileInfo(this.mxid, "displayname")).displayname)
|
|
||||||
}
|
}
|
||||||
if (!dontUpdateAvatar && this.updateAvatarImageFrom(telegramPOV, user)) {
|
if (!dontUpdateAvatar && this.updateAvatarImageFrom(telegramPOV, user)) {
|
||||||
changed = true
|
changed = true
|
||||||
|
|||||||
Reference in New Issue
Block a user