Allow starting private chats by inviting Telegram user. Fixes #13
This commit is contained in:
+2
-1
@@ -168,6 +168,7 @@
|
|||||||
"no-bitwise": "off",
|
"no-bitwise": "off",
|
||||||
"no-case-declarations": "off",
|
"no-case-declarations": "off",
|
||||||
"no-template-curly-in-string": "off",
|
"no-template-curly-in-string": "off",
|
||||||
"no-await-in-loop": "off"
|
"no-await-in-loop": "off",
|
||||||
|
"no-restricted-globals": "off"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+95
-14
@@ -64,6 +64,13 @@ class MautrixTelegram {
|
|||||||
*/
|
*/
|
||||||
this.managementRooms = []
|
this.managementRooms = []
|
||||||
|
|
||||||
|
this.usernameRegex = new RegExp(
|
||||||
|
`^@${
|
||||||
|
this.config.bridge.username_template.replace("${ID}", "([0-9]+)")
|
||||||
|
}:${
|
||||||
|
this.config.homeserver.domain
|
||||||
|
}$`)
|
||||||
|
|
||||||
const self = this
|
const self = this
|
||||||
/**
|
/**
|
||||||
* The matrix-appservice-bridge Bridge instance.
|
* The matrix-appservice-bridge Bridge instance.
|
||||||
@@ -354,11 +361,13 @@ class MautrixTelegram {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the members in the given room.
|
* Get the members in the given room.
|
||||||
* @param {string} roomID The ID of the room to search.
|
*
|
||||||
* @returns {Array} The list of MXIDs who are in the room.
|
* @param {string} roomID The ID of the room to search.
|
||||||
|
* @param {Intent} [intent] The Intent object to use when reading the room state.
|
||||||
|
* @returns {Array} The list of MXIDs who are in the room.
|
||||||
*/
|
*/
|
||||||
async getRoomMembers(roomID) {
|
async getRoomMembers(roomID, intent = this.botIntent) {
|
||||||
const roomState = await this.botIntent.roomState(roomID)
|
const roomState = await intent.roomState(roomID)
|
||||||
const members = []
|
const members = []
|
||||||
for (const event of roomState) {
|
for (const event of roomState) {
|
||||||
if (event.type === "m.room.member" && event.membership === "join") {
|
if (event.type === "m.room.member" && event.membership === "join") {
|
||||||
@@ -368,6 +377,86 @@ class MautrixTelegram {
|
|||||||
return members
|
return members
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async handleInvite(sender, evt) {
|
||||||
|
console.log(evt)
|
||||||
|
const asBotID = this.bridge.getBot().getUserId()
|
||||||
|
if (evt.state_key === asBotID) {
|
||||||
|
// Accept all AS bot invites.
|
||||||
|
try {
|
||||||
|
await this.botIntent.join(evt.room_id)
|
||||||
|
} catch (err) {
|
||||||
|
console.error(`Failed to join room ${evt.room_id}:`, err)
|
||||||
|
if (err instanceof Error) {
|
||||||
|
console.error(err.stack)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check if the invited user is a Telegram user.
|
||||||
|
const capture = this.usernameRegex.exec(evt.state_key)
|
||||||
|
console.log(capture)
|
||||||
|
if (!capture) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
const telegramID = +capture[1]
|
||||||
|
console.log(telegramID)
|
||||||
|
if (!telegramID || isNaN(telegramID)) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
const intent = this.getIntentForTelegramUser(telegramID)
|
||||||
|
try {
|
||||||
|
await intent.join(evt.room_id)
|
||||||
|
const members = await this.getRoomMembers(evt.room_id, intent)
|
||||||
|
if (members.length < 2) {
|
||||||
|
console.warn(`No members in room ${evt.room_id}`)
|
||||||
|
await intent.leave(evt.room_id)
|
||||||
|
} else if (members.length === 2) {
|
||||||
|
const user = await this.getTelegramUser(telegramID)
|
||||||
|
const peer = user.toPeer(sender.telegramPuppet)
|
||||||
|
const portal = await this.getPortalByPeer(peer)
|
||||||
|
if (portal.roomID) {
|
||||||
|
await intent.sendMessage(evt.room_id, {
|
||||||
|
msgtype: "m.notice",
|
||||||
|
body: "You already have a private chat room with me!\nI'll re-invite you to that room.",
|
||||||
|
})
|
||||||
|
try {
|
||||||
|
await intent.invite(portal.roomID, sender.userID)
|
||||||
|
} catch (_) {}
|
||||||
|
await intent.leave(evt.room_id)
|
||||||
|
} else {
|
||||||
|
portal.roomID = evt.room_id
|
||||||
|
await portal.save()
|
||||||
|
await intent.sendMessage(portal.roomID, {
|
||||||
|
msgtype: "m.notice",
|
||||||
|
body: "Portal to Telegram private chat created.",
|
||||||
|
})
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (!members.includes(asBotID)) {
|
||||||
|
await intent.sendMessage(evt.room_id, {
|
||||||
|
msgtype: "m.notice",
|
||||||
|
body: "Inviting additional Telegram users to private chats or non-portal rooms is not supported.",
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
// TODO Allow inviting Telegram users to group/channel portal rooms.
|
||||||
|
await intent.sendMessage(evt.room_id, {
|
||||||
|
msgtype: "m.notice",
|
||||||
|
body: "Inviting Telegram users to portal rooms is not (yet) supported.",
|
||||||
|
})
|
||||||
|
}
|
||||||
|
await intent.leave(evt.room_id)
|
||||||
|
}
|
||||||
|
} catch (err) {
|
||||||
|
console.error(`Failed to process invite to room ${evt.room_id} for Telegram user ${telegramID}: ${err}`)
|
||||||
|
if (err instanceof Error) {
|
||||||
|
console.error(err.stack)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Handle a single received Matrix event.
|
* Handle a single received Matrix event.
|
||||||
*
|
*
|
||||||
@@ -380,16 +469,8 @@ class MautrixTelegram {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const asBotID = this.bridge.getBot().getUserId()
|
const asBotID = this.bridge.getBot().getUserId()
|
||||||
if (evt.type === "m.room.member" && evt.state_key === asBotID && evt.content.membership === "invite") {
|
if (evt.type === "m.room.member" && evt.content.membership === "invite") {
|
||||||
// Accept all invites
|
await this.handleInvite(user, evt)
|
||||||
try {
|
|
||||||
await this.botIntent.join(evt.room_id)
|
|
||||||
} catch (err) {
|
|
||||||
console.error(`Failed to join room ${evt.room_id}:`, err)
|
|
||||||
if (err instanceof Error) {
|
|
||||||
console.error(err.stack)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user