Update JSDocs

This commit is contained in:
Tulir Asokan
2017-12-02 15:47:32 +02:00
parent 2bda80526c
commit cf3f99bd7d
4 changed files with 185 additions and 9 deletions
+24
View File
@@ -33,7 +33,15 @@ class MautrixTelegram {
* @param config The data from the config file.
*/
constructor(config) {
/**
* The app config.
* @type {Object}
*/
this.config = config
/**
* A special-cased {@link TelegramUser} that is used to send broadcasts to a channel.
* @type {TelegramUser}
*/
this.channelTelegramSender = new TelegramUser(this, -1)
/**
@@ -72,6 +80,10 @@ class MautrixTelegram {
*/
this.managementRooms = []
/**
* A regular expression that matches MXIDs of Telegram user bridged by this bridge.
* @type {RegExp}
*/
this.usernameRegex = new RegExp(
`^@${
this.config.bridge.username_template.replace("${ID}", "([0-9]+)")
@@ -111,11 +123,17 @@ class MautrixTelegram {
async run() {
console.log("Appservice listening on port %s", this.config.appservice.port)
await this.bridge.run(this.config.appservice.port, {})
// Load all Matrix users to cache
const userEntries = await this.bridge.getUserStore()
.select({ type: "matrix" })
for (const entry of userEntries) {
const user = MatrixUser.fromEntry(this, entry)
this.matrixUsersByID.set(entry.id, user)
if (user.telegramUserID) {
this.matrixUsersByTelegramID.set(user.telegramUserID, user)
}
}
}
@@ -159,6 +177,12 @@ class MautrixTelegram {
return this.config.bridge.username_template.replace("${ID}", id)
}
/**
* Get the full Matrix ID ({@code @localpart:homeserver.tld}) for the Telegram user with the given ID.
*
* @param {number} id The ID of the Telegram user.
* @returns {string} The full Matrix ID for the given Telegram user.
*/
getMXIDForTelegramUser(id) {
return `@${this.getUsernameForTelegramUser(id)}:${this.config.homeserver.domain}`
}
+21 -2
View File
@@ -36,6 +36,11 @@ class MatrixUser {
this._telegramPuppet = undefined
}
/**
* Get the user ID of the Telegram user this Matrix user controls.
*
* @returns {number|undefined} The Telegram user ID, or undefined if not logged in.
*/
get telegramUserID() {
return this._telegramPuppet
? this._telegramPuppet.userID || undefined
@@ -227,18 +232,32 @@ class MatrixUser {
return changed
}
/**
* Add a {@link Portal} to the chat list of this user.
*
* This should only be used for non-private chat portals.
*
* @param {Portal} portal The portal to add.
*/
async join(portal) {
if (!this.chats.includes(portal.id)) {
this.chats.push(portal.id)
this.save()
await this.save()
}
}
/**
* Remove a {@link Portal} from the chat list of this user.
*
* This should only be used for non-private chat portals.
*
* @param {Portal} portal The portal to remove.
*/
async leave(portal) {
const chatIDIndex = this.chats.indexOf(portal.id)
if (chatIDIndex > -1) {
this.chats.splice(chatIDIndex, 1)
this.save()
await this.save()
}
}
+139 -1
View File
@@ -29,14 +29,31 @@ class Portal {
this.accessHashes = new Map()
}
/**
* Get the peer ID of this portal.
*
* @returns {number} The ID of the peer of the Telegram side of this portal.
*/
get id() {
return this.peer.id
}
/**
* Get the receiver ID of this portal. Only applicable for private chat portals.
*
* @returns {number} The ID of the receiving user of this portal.
*/
get receiverID() {
return this.peer.receiverID
}
/**
* Convert a database entry into a Portal.
*
* @param {MautrixTelegram} app The app main class instance.
* @param {Object} entry The database entry.
* @returns {Portal} The loaded Portal.
*/
static fromEntry(app, entry) {
if (entry.type !== "portal") {
throw new Error("MatrixUser can only be created from entry type \"portal\"")
@@ -51,6 +68,16 @@ class Portal {
return portal
}
/**
* Synchronize the user list of this portal.
*
* @param {TelegramPuppet} telegramPOV The Telegram account whose point of view the data is/should be fetched from.
* @param {UserFull[]} [users] The list of {@link https://tjhorner.com/tl-schema/type/UserFull user info}
* objects.
* @returns {boolean} Whether or not syncing was successful. It can only be unsuccessful if the
* user list was not provided and an access hash was not found for the given
* Telegram user.
*/
async syncTelegramUsers(telegramPOV, users) {
if (!users) {
if (!await this.loadAccessHash(telegramPOV)) {
@@ -68,7 +95,14 @@ class Portal {
return true
}
/**
* Copy a photo from Telegram to Matrix.
*
* @param {TelegramPuppet} telegramPOV The Telegram account whose point of view the image should be downloaded from.
* @param {TelegramUser} sender The user who sent the photo.
* @param {Photo} photo The Telegram {@link https://tjhorner.com/tl-schema/type/Photo Photo} object.
* @returns {Object} The uploaded Matrix photo object.
*/
async copyTelegramPhoto(telegramPOV, sender, photo) {
const size = photo.sizes.slice(-1)[0]
const uploaded = await this.copyTelegramFile(telegramPOV, sender, size.location, photo.id)
@@ -79,6 +113,16 @@ class Portal {
return uploaded
}
/**
* Copy a file from Telegram to Matrix.
*
* @param {TelegramPuppet} telegramPOV The Telegram account whose point of view the file should be downloaded from.
* @param {TelegramUser} sender The user who sent the file.
* @param {FileLocation} location The Telegram {@link https://tjhorner.com/tl-schema/type/FileLocation
* FileLocation}.
* @returns {Object} The uploaded Matrix file object.
*/
async copyTelegramFile(telegramPOV, sender, location, id) {
console.log(JSON.stringify(location, "", " "))
id = id || location.id
@@ -96,6 +140,15 @@ class Portal {
return uploaded
}
/**
* Update the avatar of this portal to the given photo.
*
* @param {TelegramPuppet} telegramPOV The Telegram account whose point of view the avatar should be downloaded
* from, if necessary.
* @param {ChatPhoto} photo The Telegram {@link https://tjhorner.com/tl-schema/type/ChatPhoto ChatPhoto}
* object.
* @returns {boolean} Whether or not the photo was updated.
*/
async updateAvatar(telegramPOV, photo) {
if (!photo || this.peer.type === "user") {
return false
@@ -128,10 +181,24 @@ class Portal {
return true
}
/**
* Load the access hash for the given puppet.
*
* @param {TelegramPuppet} telegramPOV The puppet whose access hash to load.
* @returns {boolean} As specified by {@link TelegramPeer#loadAccessHash(app, telegramPOV)}.
*/
loadAccessHash(telegramPOV) {
return this.peer.loadAccessHash(this.app, telegramPOV, { portal: this })
}
/**
* Handle a Telegram typing event.
*
* @param {Object} evt The custom event object.
* @param {number} evt.from The ID of the Telegram user who is typing.
* @param {TelegramPeer} evt.to The peer where the user is typing.
* @param {TelegramPuppet} evt.source The source where this event was captured.
*/
async handleTelegramTyping(evt) {
if (!this.isMatrixRoomCreated()) {
return
@@ -143,6 +210,16 @@ class Portal {
typer.intent.sendTyping(this.roomID, true/*, 5500*/)
}
/**
* Handle a Telegram service message event.
*
* @param {Object} evt The custom event object.
* @param {number} evt.from The ID of the Telegram user who caused the service message.
* @param {TelegramPeer} evt.to The peer to which the message was sent.
* @param {TelegramPuppet} evt.source The source where this event was captured.
* @param {MessageAction} evt.action The Telegram {@link https://tjhorner.com/tl-schema/type/MessageAction
* MessageAction} object.
*/
async handleTelegramServiceMessage(evt) {
let matrixUser, telegramUser
switch (evt.action._) {
@@ -199,6 +276,22 @@ class Portal {
}
}
/**
* Handle a Telegram service message event.
*
* @param {Object} evt The custom event object.
* @param {number} evt.from The ID of the Telegram user who caused the service message.
* @param {TelegramPeer} evt.to The peer to which the message was sent.
* @param {TelegramPuppet} evt.source The source where this event was captured.
* @param {string} evt.text The text in the message.
* @param {string} [evt.caption] The image/file caption.
* @param {MessageEntity[]} [evt.entities] The Telegram {@link https://tjhorner.com/tl-schema/type/MessageEntity
* formatting entities} in the message.
* @param {messageMediaPhoto} [evt.photo] The Telegram {@link https://tjhorner.com/tl-schema/constructor/messageMediaPhoto Photo} attached to the message.
* @param {messageMediaDocument} [evt.document] The Telegram {@link https://tjhorner.com/tl-schema/constructor/messageMediaDocument Document} attached to the message.
* @param {messageMediaGeo} [evt.geo] The Telegram {@link https://tjhorner.com/tl-schema/constructor/messageMediaGeo Location} attached to the message.
*/
async handleTelegramMessage(evt) {
if (!this.isMatrixRoomCreated()) {
try {
@@ -247,6 +340,13 @@ class Portal {
}
}
/**
* Handle a Matrix event.
*
* @param {MatrixUser} sender The user who sent the message.
* @param {Object} evt The {@link https://matrix.org/docs/spec/client_server/r0.3.0.html#event-structure
* Matrix event}.
*/
async handleMatrixEvent(sender, evt) {
await this.loadAccessHash(sender.telegramPuppet)
switch (evt.content.msgtype) {
@@ -285,16 +385,32 @@ class Portal {
}
}
/**
* @returns {boolean} Whether or not a Matrix room has been created for this Portal.
*/
isMatrixRoomCreated() {
return !!this.roomID
}
/**
* Get the primary intent object for this Portal.
*
* For groups and channels, this is always the AS bot intent.
* For private chats, it is the intent of the other user.
*
* @returns {Intent} The primary intent.
*/
async getMainIntent() {
return this.peer.type === "user"
? (await this.app.getTelegramUser(this.peer.id)).intent
: this.app.botIntent
}
/**
* Invite one or more Matrix users to this Portal.
*
* @param {string[]|string} users The MXID or list of MXIDs to invite.
*/
async invite(users) {
const intent = await this.getMainIntent()
// TODO check membership before inviting?
@@ -309,6 +425,12 @@ class Portal {
}
}
/**
* Kick one or more Matrix users from this 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) {
const intent = await this.getMainIntent()
if (Array.isArray(users)) {
@@ -322,6 +444,14 @@ class Portal {
}
}
/**
* Create a Matrix room for this portal.
*
* @param {TelegramPuppet} telegramPOV
* @param {string|string[] invite
* @param {boolean} inviteEvenIfNotCreated
* @returns {{created: boolean, roomID: string}}
*/
async createMatrixRoom(telegramPOV, { invite = [], inviteEvenIfNotCreated = true } = {}) {
if (this.roomID) {
if (invite && inviteEvenIfNotCreated) {
@@ -445,6 +575,11 @@ class Portal {
return changed
}
/**
* Convert this Portal into a database entry.
*
* @returns {Object} A room store database entry.
*/
toEntry() {
return {
type: this.type,
@@ -462,6 +597,9 @@ class Portal {
}
}
/**
* Save this Portal to the database.
*/
save() {
return this.app.putRoom(this)
}
+1 -6
View File
@@ -64,7 +64,7 @@ class TelegramPeer {
* Only used if {@link #type} is {@code user}.
* @param {TelegramUser} [user] Optional {@link TelegramUser} instance to avoid calling {@link app#getTelegramUser(id)}.
* Only used if {@link #type} is {@code channel}.
* @returns {Promise<boolean>} Whether or not the access hash was found and loaded.
* @returns {boolean} Whether or not the access hash was found and loaded.
*/
async loadAccessHash(app, telegramPOV, { portal, user } = {}) {
if (this.type === "chat") {
@@ -239,11 +239,6 @@ class TelegramPeer {
receiverID: this.receiverID,
}
}
// TODO determine if this is useless and remove if it is.
get key() {
return `${this.type} ${this.id}`
}
}
module.exports = TelegramPeer