Add support for Matrix->Telegram invites

This commit is contained in:
Tulir Asokan
2017-12-03 13:12:44 +02:00
parent 00c26eef86
commit b203f3b182
3 changed files with 60 additions and 18 deletions
+9 -4
View File
@@ -60,9 +60,12 @@ does not do this automatically.
* [ ] Typing notifications (may not be possible)
* [ ] Pinning messages
* [ ] Power level
* [ ] Membership actions (invite, kick, join, leave)
* [ ] Membership actions
* [x] Inviting
* [ ] Kicking
* [ ] Joining/leaving
* [ ] Room metadata changes
* [ ] Room invites
* [x] Room invites
* Telegram → Matrix
* [x] Plaintext messages
* [x] Formatted messages
@@ -79,11 +82,13 @@ does not do this automatically.
* [x] Typing notifications
* [ ] Pinning messages
* [ ] Admin status
* [x] Membership actions (invite, kick, join, leave)
* [x] Membership actions
* [x] Inviting
* [x] Kicking
* [x] Joining/leaving
* [x] Chat metadata changes
* [x] Initial chat metadata
* [ ] Message edits
* [x] Chat invites
* Initiating chats
* [x] Automatic portal creation for groups/channels at startup
* [x] Automatic portal creation for groups/channels when receiving invite/message
+13 -9
View File
@@ -523,11 +523,11 @@ class MautrixTelegram {
try {
await intent.join(evt.room_id)
const members = await this.getRoomMembers(evt.room_id, intent)
const user = await this.getTelegramUser(telegramID)
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) {
@@ -546,21 +546,25 @@ class MautrixTelegram {
msgtype: "m.notice",
body: "Portal to Telegram private chat created.",
})
await user.updateInfo(sender.telegramPuppet, undefined, { updateAvatar: true })
}
} 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.",
})
await intent.leave(evt.room_id)
} else {
if (!members.includes(asBotID)) {
const portal = await this.getPortalByRoomID(evt.room_id)
if (!portal) {
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)
return
}
await intent.leave(evt.room_id)
await portal.inviteTelegram(sender.telegramPuppet, user)
}
} catch (err) {
console.error(`Failed to process invite to room ${evt.room_id} for Telegram user ${telegramID}: ${err}`)
+38 -5
View File
@@ -240,7 +240,7 @@ class Portal {
matrixUser = await this.app.getMatrixUserByTelegramID(userID)
if (matrixUser) {
matrixUser.join(this)
this.invite(matrixUser.userID)
this.inviteMatrix(matrixUser.userID)
}
telegramUser = await this.app.getTelegramUser(userID)
telegramUser.intent.join(this.roomID)
@@ -267,7 +267,7 @@ class Portal {
matrixUser = await this.app.getMatrixUserByTelegramID(evt.action.user_id)
if (matrixUser) {
matrixUser.leave(this)
this.kick(matrixUser.userID, "Left Telegram chat")
this.kickMatrix(matrixUser.userID, "Left Telegram chat")
}
telegramUser = await this.app.getTelegramUser(evt.action.user_id)
telegramUser.intent.leave(this.roomID)
@@ -428,12 +428,45 @@ class Portal {
: this.app.botIntent
}
async inviteTelegram(telegramPOV, user) {
if (this.peer.type === "chat") {
const updates = await telegramPOV.client("messages.addChatUser", {
chat_id: this.peer.id,
user_id: user.toPeer(telegramPOV).toInputObject(),
fwd_limit: 50,
})
console.log("Chat invite result:", updates)
} else if (this.peer.type === "channel") {
const updates = await telegramPOV.client("channels.inviteToChannel", {
channel: this.peer.toInputObject(),
users: [user.toPeer(telegramPOV).toInputObject()],
})
console.log("Channel invite result:", updates)
} else {
throw new Error(`Can't invite user to peer type ${this.peer.type}`)
}
}
async kickTelegram(telegramPOV, user) {
if (this.peer.type === "chat") {
const updates = await telegramPOV.client("messages.deleteChatUser", {
chat_id: this.peer.id,
user_id: user.toPeer(telegramPOV).toInputObject(),
})
console.log("Chat kick result:", updates)
} else if (this.peer.type === "channel") {
throw new Error("I don't know how to kick users from channels :(")
} else {
throw new Error(`Can't invite user to peer type ${this.peer.type}`)
}
}
/**
* Invite one or more Matrix users to this Portal.
*
* @param {string[]|string} users The MXID or list of MXIDs to invite.
*/
async invite(users) {
async inviteMatrix(users) {
const intent = await this.getMainIntent()
// TODO check membership before inviting?
if (Array.isArray(users)) {
@@ -453,7 +486,7 @@ class Portal {
* @param {string[]|string} users The MXID or list of MXIDs to kick.
* @param {string} reason The reason for kicking the user(s).
*/
async kick(users, reason) {
async kickMatrix(users, reason) {
const intent = await this.getMainIntent()
if (Array.isArray(users)) {
for (const userID of users) {
@@ -477,7 +510,7 @@ class Portal {
async createMatrixRoom(telegramPOV, { invite = [], inviteEvenIfNotCreated = true } = {}) {
if (this.roomID) {
if (invite && inviteEvenIfNotCreated) {
await this.invite(invite)
await this.inviteMatrix(invite)
}
return {
created: false,