From 77a2705dd96ea2165c9aac42bbd76b533859ea10 Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Sat, 25 Nov 2017 15:06:02 +0200 Subject: [PATCH] Improve management command output and add user link pills to search output (ref #7) --- src/app.js | 17 +++++++++--- src/commands.js | 64 ++++++++++++++++++++++++++++++---------------- src/matrix-user.js | 11 ++++---- 3 files changed, 61 insertions(+), 31 deletions(-) diff --git a/src/app.js b/src/app.js index d5fc64bc..d030ccb3 100644 --- a/src/app.js +++ b/src/app.js @@ -98,8 +98,15 @@ class MautrixTelegram { * @returns {Intent} The Matrix puppet intent for the given Telegram user. */ getIntentForTelegramUser(id) { - return this.bridge.getIntentFromLocalpart( - this.config.bridge.username_template.replace("${ID}", id)) + return this.bridge.getIntentFromLocalpart(this.getUsernameForTelegramUser(id)) + } + + getUsernameForTelegramUser(id) { + return this.config.bridge.username_template.replace("${ID}", id) + } + + getMatrixToLinkForTelegramUser(id) { + return `https://matrix.to/#/@${this.getUsernameForTelegramUser(id)}:${this.config.homeserver.domain}` } /** @@ -340,11 +347,13 @@ class MautrixTelegram { commands.run(user, command, args, (reply, { allowHTML = false, markdown = true } = {}) => { reply = reply.replace("$cmdprefix", cmdprefix) - if (!allowHTML) { + if (!markdown && !allowHTML) { reply = escapeHTML(reply) } if (markdown) { - reply = marked(reply) + reply = marked(reply, { + sanitize: allowHTML, + }) } this.botIntent.sendMessage( evt.room_id, { diff --git a/src/commands.js b/src/commands.js index 52a9cfdd..cf1a817c 100644 --- a/src/commands.js +++ b/src/commands.js @@ -14,7 +14,6 @@ // You should have received a copy of the GNU General Public License // along with this program. If not, see . const makePasswordHash = require("telegram-mtproto").plugins.makePasswordHash -const escapeHTML = require("escape-html") const commands = {} @@ -30,7 +29,7 @@ function run(sender, command, args, reply, app) { 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 undefined } try { @@ -38,10 +37,11 @@ function run(sender, command, args, reply, app) { } catch (err) { reply(`Error running command: ${err}.`) if (err instanceof Error) { - reply("Check bridge console for stack trace") + reply(["```", err.stack, "```"].join("")) console.error(err.stack) } } + return undefined } commands.cancel = () => "Nothing to cancel." @@ -56,7 +56,7 @@ commands.help = (sender, args, reply) => { **logout** - Log out from Telegram. Currently broken. **api** <_method_> <_args_> - Call a Telegram API method. Args is always a JSON object. Disabled by default. -`, {allowHTML: true}) +`, { allowHTML: true }) } @@ -69,7 +69,7 @@ commands.help = (sender, args, reply) => { */ commands.enterPassword = async (sender, args, reply) => { if (args.length === 0) { - reply("Usage: $cmdprefix ") + reply("**Usage:** `$cmdprefix `") return } @@ -79,8 +79,11 @@ commands.enterPassword = async (sender, args, reply) => { reply(`Logged in successfully as @${sender.telegramPuppet.getDisplayName()}.`) sender.commandStatus = undefined } catch (err) { - reply(`Login failed: ${err}`) - console.log(err) + reply(`**Login failed:** ${err}`) + if (err instanceof Error) { + reply(["```", err.stack, "```"].join("")) + console.error(err.stack) + } } } @@ -89,7 +92,7 @@ commands.enterPassword = async (sender, args, reply) => { */ commands.enterCode = async (sender, args, reply) => { if (args.length === 0) { - reply("Usage: $cmdprefix ") + reply("**Usage:** `$cmdprefix `") return } @@ -100,7 +103,7 @@ commands.enterCode = async (sender, args, reply) => { sender.commandStatus = undefined } else if (data.status === "need-password") { reply(`You have two-factor authentication enabled. Password hint: ${data.hint} -Enter your password using "$cmdprefix "`) +Enter your password using \`$cmdprefix \``) sender.commandStatus = { action: "Two-factor authentication", next: commands.enterPassword, @@ -111,8 +114,11 @@ Enter your password using "$cmdprefix "`) } } catch (err) { // TODO login fails somewhere with TypeError: Cannot read property 'status' of undefined - reply(`Login failed: ${err}`) - console.error(err.stack) + reply(`**Login failed:** ${err}`) + if (err instanceof Error) { + reply(["```", err.stack, "```"].join("")) + console.error(err.stack) + } } } @@ -121,7 +127,7 @@ Enter your password using "$cmdprefix "`) */ commands.login = async (sender, args, reply) => { if (args.length === 0) { - reply("Usage: $cmdprefix login ") + reply("**Usage:** `$cmdprefix login `") return } @@ -134,8 +140,11 @@ commands.login = async (sender, args, reply) => { next: commands.enterCode, } } catch (err) { - reply(`Failed to send code: ${err}`) - console.log(err) + reply(`**Failed to send code:** ${err}`) + if (err instanceof Error) { + reply(["```", err.stack, "```"].join("")) + console.error(err.stack) + } } } @@ -148,7 +157,11 @@ commands.logout = async (sender, args, reply) => { sender.logOutFromTelegram() reply("Logged out successfully.") } catch (err) { - reply(`Failed to log out: ${err}`) + reply(`**Failed to log out:** ${err}`) + if (err instanceof Error) { + reply(["```", err.stack, "```"].join("")) + console.error(err.stack) + } } } @@ -165,10 +178,11 @@ commands.search = async (sender, args, reply, app) => { if (args[0] !== "-r" && args[0] !== "--remote") { const contactResults = await sender.searchContacts(args.join(" ")) if (contactResults.length > 0) { - msg.push("Following results found from local contacts:") + msg.push("**Following results found from local contacts:**") msg.push("") - for (const {match, contact} of contactResults) { - msg.push(`- ${contact.getDisplayName()}: ${contact.id} (${match}% match)`) + for (const { match, contact } of contactResults) { + msg.push(`- ${contact.getDisplayName()}: ${contact.id} (${match}% match)`) } msg.push("") msg.push("To force searching from Telegram servers, add `-r` before the search query.") @@ -180,14 +194,20 @@ commands.search = async (sender, args, reply, app) => { msg.push("-r flag found: forcing remote search") msg.push("") } - const telegramResults = await sender.searchTelegram(args.join(" ")) + const query = args.join(" ") + if (query.length < 5) { + reply("Failed to search server: Query is too short.") + return + } + const telegramResults = await sender.searchTelegram(query) if (telegramResults.length > 0) { - msg.push("Following results received from Telegram server:") + msg.push("**Following results received from Telegram server:**") for (const user of telegramResults) { - msg.push(`- ${user.getDisplayName()}: ${user.id}`) + msg.push(`- ${user.getDisplayName()}: ${user.id}`) } } else { - msg.push("No users found.") + msg.push("**No users found.**") } reply(msg.join("\n")) } diff --git a/src/matrix-user.js b/src/matrix-user.js index 0b0d3fd5..622cc484 100644 --- a/src/matrix-user.js +++ b/src/matrix-user.js @@ -16,7 +16,7 @@ const md5 = require("md5") const TelegramPuppet = require("./telegram-puppet") const TelegramPeer = require("./telegram-peer") -const strSim = require("string-similarity"); +const strSim = require("string-similarity") /** * MatrixUser represents a Matrix user who probably wants to control their @@ -139,10 +139,12 @@ class MatrixUser { return changed } - async searchContacts(query, {maxResults=5, minSimilarity = 0.45} = {}) { + async searchContacts(query, { maxResults = 5, minSimilarity = 0.45 } = {}) { const results = [] for (const contact of this.contacts) { - let displaynameSimilarity = 0, usernameSimilarity = 0, numberSimilarity = 0 + let displaynameSimilarity = 0 + let usernameSimilarity = 0 + let numberSimilarity = 0 if (contact.firstName || contact.lastName) { displaynameSimilarity = strSim.compareTwoStrings(query, contact.getFirstAndLastName()) } @@ -153,7 +155,6 @@ class MatrixUser { numberSimilarity = strSim.compareTwoStrings(query, contact.phoneNumber) } const similarity = Math.max(displaynameSimilarity, usernameSimilarity, numberSimilarity) - console.log(contact.getDisplayName(), similarity, displaynameSimilarity, usernameSimilarity, numberSimilarity) if (similarity >= minSimilarity) { results.push({ similarity, @@ -167,7 +168,7 @@ class MatrixUser { .slice(0, maxResults) } - async searchTelegram(query, {maxResults=5} = {}) { + async searchTelegram(query, { maxResults = 5 } = {}) { const results = await this.telegramPuppet.client("contacts.search", { q: query, limit: maxResults,