diff --git a/package-lock.json b/package-lock.json index 29258a4663bbce1aa0c33fead6966152c1d82ae4..43d224742febb19a6f255f6cf5b925e294b0dffc 100644 --- a/package-lock.json +++ b/package-lock.json @@ -4,12 +4,6 @@ "lockfileVersion": 1, "requires": true, "dependencies": { - "@types/bluebird": { - "version": "3.5.24", - "resolved": "https://registry.npmjs.org/@types/bluebird/-/bluebird-3.5.24.tgz", - "integrity": "sha512-YeQoDpq4Lm8ppSBqAnAeF/xy1cYp/dMTif2JFcvmAbETMRlvKHT2iLcWu+WyYiJO3b3Ivokwo7EQca/xfLVJmg==", - "dev": true - }, "@types/chai": { "version": "3.5.2", "resolved": "https://registry.npmjs.org/@types/chai/-/chai-3.5.2.tgz", @@ -18,7 +12,7 @@ }, "@types/events": { "version": "1.2.0", - "resolved": "http://registry.npmjs.org/@types/events/-/events-1.2.0.tgz", + "resolved": "https://registry.npmjs.org/@types/events/-/events-1.2.0.tgz", "integrity": "sha512-KEIlhXnIutzKwRbQkGWb/I4HFqBuUykAdHgDED6xqwXJfONCjF5VoE0cXEiurh3XauygxzeDzgtXUqvLkxFzzA==", "dev": true }, @@ -29,9 +23,9 @@ "dev": true }, "@types/node": { - "version": "10.12.2", - "resolved": "https://registry.npmjs.org/@types/node/-/node-10.12.2.tgz", - "integrity": "sha512-53ElVDSnZeFUUFIYzI8WLQ25IhWzb6vbddNp8UHlXQyU0ET2RhV5zg0NfubzU7iNMh5bBXb0htCzfvrSVNgzaQ==", + "version": "10.14.6", + "resolved": "https://registry.npmjs.org/@types/node/-/node-10.14.6.tgz", + "integrity": "sha512-Fvm24+u85lGmV4hT5G++aht2C5I4Z4dYlWZIh62FAfFO/TfzXtPpoLI6I7AuBWkIFqZCnhFOoTT7RjjaIL5Fjg==", "dev": true }, "@types/p-queue": { @@ -41,7 +35,7 @@ }, "@types/sqlite3": { "version": "3.1.3", - "resolved": "http://registry.npmjs.org/@types/sqlite3/-/sqlite3-3.1.3.tgz", + "resolved": "https://registry.npmjs.org/@types/sqlite3/-/sqlite3-3.1.3.tgz", "integrity": "sha512-BgGToABnI/8/HnZtZz2Qac6DieU2Dm/j3rtbMmUlDVo4T/uLu8cuVfU/n2UkHowiiwXb6/7h/CmSqBIVKgcTMA==", "dev": true, "requires": { @@ -71,7 +65,7 @@ }, "acorn-jsx": { "version": "3.0.1", - "resolved": "http://registry.npmjs.org/acorn-jsx/-/acorn-jsx-3.0.1.tgz", + "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-3.0.1.tgz", "integrity": "sha1-r9+UiPsezvyDSPb7IvRk4ypYs2s=", "dev": true, "requires": { @@ -80,7 +74,7 @@ "dependencies": { "acorn": { "version": "3.3.0", - "resolved": "http://registry.npmjs.org/acorn/-/acorn-3.3.0.tgz", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-3.3.0.tgz", "integrity": "sha1-ReN/s56No/JbruP/U2niu18iAXo=", "dev": true } @@ -125,7 +119,7 @@ }, "ansi-escapes": { "version": "1.4.0", - "resolved": "http://registry.npmjs.org/ansi-escapes/-/ansi-escapes-1.4.0.tgz", + "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-1.4.0.tgz", "integrity": "sha1-06ioOzGapneTZisT52HHkRQiMG4=", "dev": true }, @@ -422,7 +416,7 @@ }, "chai": { "version": "3.5.0", - "resolved": "http://registry.npmjs.org/chai/-/chai-3.5.0.tgz", + "resolved": "https://registry.npmjs.org/chai/-/chai-3.5.0.tgz", "integrity": "sha1-TQJjewZ/6Vi9v906QOxW/vc3Mkc=", "dev": true, "requires": { @@ -617,7 +611,7 @@ }, "d": { "version": "1.0.0", - "resolved": "http://registry.npmjs.org/d/-/d-1.0.0.tgz", + "resolved": "https://registry.npmjs.org/d/-/d-1.0.0.tgz", "integrity": "sha1-dUu1v+VUUdpppYuU1F9MWwRi1Y8=", "dev": true, "requires": { @@ -642,7 +636,7 @@ }, "deep-eql": { "version": "0.1.3", - "resolved": "http://registry.npmjs.org/deep-eql/-/deep-eql-0.1.3.tgz", + "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-0.1.3.tgz", "integrity": "sha1-71WKyrjeJSBs1xOQbXTlaTDrafI=", "dev": true, "requires": { @@ -759,7 +753,7 @@ }, "enabled": { "version": "1.0.2", - "resolved": "http://registry.npmjs.org/enabled/-/enabled-1.0.2.tgz", + "resolved": "https://registry.npmjs.org/enabled/-/enabled-1.0.2.tgz", "integrity": "sha1-ll9lE9LC0cX0ZStkouM5ZGf8L5M=", "requires": { "env-variable": "0.0.x" @@ -1107,7 +1101,7 @@ }, "fecha": { "version": "2.3.3", - "resolved": "http://registry.npmjs.org/fecha/-/fecha-2.3.3.tgz", + "resolved": "https://registry.npmjs.org/fecha/-/fecha-2.3.3.tgz", "integrity": "sha512-lUGBnIamTAwk4znq5BcqsDaxSmZ9nDVJaij6NvRt/Tg4R69gERA+otPKbS86ROw9nxVMw2/mp1fnaiWqbs6Sdg==" }, "figures": { @@ -1426,7 +1420,7 @@ }, "inquirer": { "version": "0.12.0", - "resolved": "http://registry.npmjs.org/inquirer/-/inquirer-0.12.0.tgz", + "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-0.12.0.tgz", "integrity": "sha1-HvK/1jUE3wvHV4X/+MLEHfEvB34=", "dev": true, "requires": { @@ -1616,7 +1610,7 @@ }, "async": { "version": "1.5.2", - "resolved": "http://registry.npmjs.org/async/-/async-1.5.2.tgz", + "resolved": "https://registry.npmjs.org/async/-/async-1.5.2.tgz", "integrity": "sha1-7GphrlZIDAw8skHJVhjiCJL5Zyo=", "dev": true }, @@ -1839,7 +1833,7 @@ "dependencies": { "bluebird": { "version": "2.11.0", - "resolved": "http://registry.npmjs.org/bluebird/-/bluebird-2.11.0.tgz", + "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-2.11.0.tgz", "integrity": "sha1-U0uQM8AiyVecVro7Plpcqvu2UOE=" } } @@ -1864,7 +1858,7 @@ }, "media-typer": { "version": "0.3.0", - "resolved": "http://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", + "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", "integrity": "sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g=" }, "merge-descriptors": { @@ -1927,7 +1921,7 @@ }, "mkdirp": { "version": "0.5.1", - "resolved": "http://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz", "integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=", "requires": { "minimist": "0.0.8" @@ -2127,7 +2121,7 @@ }, "onetime": { "version": "1.1.0", - "resolved": "http://registry.npmjs.org/onetime/-/onetime-1.1.0.tgz", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-1.1.0.tgz", "integrity": "sha1-ofeDj4MUxRbwXs78vEzP4EtO14k=", "dev": true }, @@ -2278,7 +2272,7 @@ }, "pify": { "version": "2.3.0", - "resolved": "http://registry.npmjs.org/pify/-/pify-2.3.0.tgz", + "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=", "dev": true }, @@ -2344,7 +2338,7 @@ }, "progress": { "version": "1.1.8", - "resolved": "http://registry.npmjs.org/progress/-/progress-1.1.8.tgz", + "resolved": "https://registry.npmjs.org/progress/-/progress-1.1.8.tgz", "integrity": "sha1-4mDHj2Fhzdmw5WzD4Khd4Xx6V74=", "dev": true }, @@ -2633,7 +2627,7 @@ }, "slice-ansi": { "version": "0.0.4", - "resolved": "http://registry.npmjs.org/slice-ansi/-/slice-ansi-0.0.4.tgz", + "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-0.0.4.tgz", "integrity": "sha1-7b+JA/ZvfOL46v1s7tZeJkyDGzU=", "dev": true }, @@ -2748,7 +2742,7 @@ }, "strip-ansi": { "version": "3.0.1", - "resolved": "http://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", "requires": { "ansi-regex": "^2.0.0" @@ -2776,7 +2770,7 @@ }, "table": { "version": "3.8.3", - "resolved": "http://registry.npmjs.org/table/-/table-3.8.3.tgz", + "resolved": "https://registry.npmjs.org/table/-/table-3.8.3.tgz", "integrity": "sha1-K7xULw/amGGnVdOUf+/Ys/UThV8=", "dev": true, "requires": { @@ -2924,7 +2918,7 @@ }, "through": { "version": "2.3.8", - "resolved": "http://registry.npmjs.org/through/-/through-2.3.8.tgz", + "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", "integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=" }, "tough-cookie": { diff --git a/package.json b/package.json index 14c2492963db9bed06f0ee5b4882f568458f1ac9..6339d5b76e3cff94c74b1bacfdf14db74f32dbf0 100644 --- a/package.json +++ b/package.json @@ -36,7 +36,6 @@ "dependencies": { "@types/p-queue": "^3.0.0", "better-sqlite3": "^5.0.1", - "bluebird": "^3.5.1", "command-line-args": "^4.0.1", "command-line-usage": "^4.1.0", "discord-markdown": "^2.0.0", @@ -56,7 +55,6 @@ "winston-daily-rotate-file": "^3.3.0" }, "devDependencies": { - "@types/bluebird": "^3.5.20", "@types/chai": "^3.4.35", "@types/mocha": "^5.2.5", "@types/node": "^10.12.0", diff --git a/src/bot.ts b/src/bot.ts index d2e13e14883faa3d0abe19b3bc5dd1b4fff477b4..83576493bf5692dc0f01b4f2d38e842dd3cc8881 100644 --- a/src/bot.ts +++ b/src/bot.ts @@ -34,7 +34,6 @@ import { ChannelSyncroniser } from "./channelsyncroniser"; import { MatrixRoomHandler } from "./matrixroomhandler"; import { Log } from "./log"; import * as Discord from "discord.js"; -import * as Bluebird from "bluebird"; import * as mime from "mime"; import { IMatrixEvent, IMatrixMediaInfo } from "./matrixtypes"; @@ -186,11 +185,11 @@ export class DiscordBot { }); // Due to messages often arriving before we get a response from the send call, - // messages get delayed from discord. We use Bluebird.delay to handle this. + // messages get delayed from discord. We use Util.Delay to handle this. client.on("messageDelete", async (msg: Discord.Message) => { try { - await Bluebird.delay(this.config.limits.discordSendDelay); + await Util.DelayedPromise(this.config.limits.discordSendDelay); this.discordMessageQueue[msg.channel.id] = (async () => { await (this.discordMessageQueue[msg.channel.id] || Promise.resolve()); try { @@ -205,7 +204,7 @@ export class DiscordBot { }); client.on("messageUpdate", async (oldMessage: Discord.Message, newMessage: Discord.Message) => { try { - await Bluebird.delay(this.config.limits.discordSendDelay); + await Util.DelayedPromise(this.config.limits.discordSendDelay); this.discordMessageQueue[newMessage.channel.id] = (async () => { await (this.discordMessageQueue[newMessage.channel.id] || Promise.resolve()); try { @@ -220,7 +219,7 @@ export class DiscordBot { }); client.on("message", async (msg: Discord.Message) => { try { - await Bluebird.delay(this.config.limits.discordSendDelay); + await Util.DelayedPromise(this.config.limits.discordSendDelay); this.discordMessageQueue[msg.channel.id] = (async () => { await (this.discordMessageQueue[msg.channel.id] || Promise.resolve()); try { diff --git a/src/clientfactory.ts b/src/clientfactory.ts index 8c1f44cab57a3b7f28a0c2b6275aefdcc838abce..84bebbd9aac950fe1a13a51e81a89a830a5cec08 100644 --- a/src/clientfactory.ts +++ b/src/clientfactory.ts @@ -17,8 +17,8 @@ limitations under the License. import { DiscordBridgeConfigAuth } from "./config"; import { DiscordStore } from "./store"; import { Client as DiscordClient } from "discord.js"; -import * as Bluebird from "bluebird"; import { Log } from "./log"; +import { Util } from "./util"; const log = new Log("ClientFactory"); @@ -41,21 +41,19 @@ export class DiscordClientFactory { } // We just need to make sure we have a bearer token. // Create a new Bot client. - this.botClient = Bluebird.promisifyAll(new DiscordClient({ + this.botClient = new DiscordClient({ fetchAllMembers: true, messageCacheLifetime: 5, sync: true, - })); - - return new Bluebird<void>((resolve, reject) => { - this.botClient.on("ready", () => { - resolve(); - }); - this.botClient.login(this.config.botToken).catch(reject); - }).timeout(READY_TIMEOUT).catch((err) => { + }); + + try { + await this.botClient.login(this.config.botToken); + } catch (err) { log.error("Could not login as the bot user. This is bad!", err); throw err; - }); + } + } public async getDiscordId(token: string): Promise<string> { @@ -64,30 +62,26 @@ export class DiscordClientFactory { messageCacheLifetime: 5, sync: false, }); - return new Bluebird<string>((resolve, reject) => { - client.on("ready", async () => { - const id = client.user.id; - await client.destroy(); - resolve(id); - }); - client.login(token).catch(reject); - }).timeout(READY_TIMEOUT).catch((err: Error) => { - log.warn("Could not login as a normal user.", err.message); - throw Error("Could not retrieve ID"); - }); + + await client.login(token); + const id = client.user.id; + client.destroy(); + return id; } public async getClient(userId: string | null = null): Promise<DiscordClient> { if (userId === null) { return this.botClient; } + if (this.clients.has(userId)) { log.verbose("Returning cached user client for", userId); return this.clients.get(userId) as DiscordClient; } + const discordIds = await this.store.get_user_discord_ids(userId); if (discordIds.length === 0) { - return Promise.resolve(this.botClient); + return this.botClient; } // TODO: Select a profile based on preference, not the first one. const token = await this.store.get_token(discordIds[0]); @@ -96,10 +90,12 @@ export class DiscordClientFactory { messageCacheLifetime: 5, sync: true, }); + const jsLog = new Log("discord.js-ppt"); client.on("debug", (msg) => { jsLog.verbose(msg); }); client.on("error", (msg) => { jsLog.error(msg); }); client.on("warn", (msg) => { jsLog.warn(msg); }); + try { await client.login(token); log.verbose("Logged in. Storing ", userId); diff --git a/src/db/schema/v3.ts b/src/db/schema/v3.ts index 3f58e065c38dfbe2923b7a0eab89a2ae22a128da..c879aea95f56ade449161be22bcedc0a0dafbb9b 100644 --- a/src/db/schema/v3.ts +++ b/src/db/schema/v3.ts @@ -77,7 +77,8 @@ directory.`); for (const row of rows) { log.info("Moving ", row.userId); try { - const dId = clientFactory.getDiscordId(row.token); + const client = await clientFactory.getClient(row.token); + const dId = client.user.id; if (dId === null) { continue; } diff --git a/src/discordas.ts b/src/discordas.ts index e395fef41d577bcc3e57c3062c768465bc9ca230..e7f6db7569db71669e700cf10f660118601fff5d 100644 --- a/src/discordas.ts +++ b/src/discordas.ts @@ -15,7 +15,6 @@ limitations under the License. */ import { Cli, Bridge, AppServiceRegistration, ClientFactory, BridgeContext } from "matrix-appservice-bridge"; -import * as Bluebird from "bluebird"; import * as yaml from "js-yaml"; import * as fs from "fs"; import { DiscordBridgeConfig } from "./config"; @@ -23,6 +22,7 @@ import { DiscordBot } from "./bot"; import { DiscordStore } from "./store"; import { Log } from "./log"; import "source-map-support/register"; +import { IRequestPromise } from "./util"; const log = new Log("DiscordAS"); @@ -94,6 +94,10 @@ async function run(port: number, fileConfig: DiscordBridgeConfig) { } catch (err) { log.error("Exception thrown while handling \"onAliasQuery\" event", err); } }, onEvent: async (request) => { + const done = function (resolve, reject) { + (this as Promise<any>).then(resolve); + (this as Promise<any>).then(reject); + }; try { // Build our own context. if (!store.roomStore) { @@ -108,10 +112,14 @@ async function run(port: number, fileConfig: DiscordBridgeConfig) { const entries = await store.roomStore.getEntriesByMatrixId(roomId); context.rooms = entries[0] || {}; } - await request.outcomeFrom(Bluebird.resolve(callbacks.onEvent(request, context))); + + await request.outcomeFrom({ + done, + ...callbacks.onEvent(request, context) + } as IRequestPromise<any>); } catch (err) { log.error("Exception thrown while handling \"onEvent\" event", err); - await request.outcomeFrom(Bluebird.reject("Failed to handle")); + await request.outcomeFrom({done, ...Promise.reject("Failed to handle")}); } }, onLog: (line, isError) => { diff --git a/src/matrixroomhandler.ts b/src/matrixroomhandler.ts index 109a5f4b2f7a9b1d6b2796c4dbb99abb2dd7600b..564fdab9c08ed1d166cf3e644d76be952e3114b1 100644 --- a/src/matrixroomhandler.ts +++ b/src/matrixroomhandler.ts @@ -29,7 +29,6 @@ import { import { DiscordBridgeConfig } from "./config"; import * as Discord from "discord.js"; -import * as Bluebird from "bluebird"; import { Util, ICommandActions, ICommandParameters } from "./util"; import { Provisioner } from "./provisioner"; import { Log } from "./log"; @@ -122,7 +121,7 @@ export class MatrixRoomHandler { continue; } promiseList.push((async () => { - await Bluebird.delay(delay); + await Util.DelayedPromise(delay); log.info(`UserSyncing ${member.id}`); try { // Ensure the profile is up to date. diff --git a/src/util.ts b/src/util.ts index aca4d651a2eb9780ff8d1a5666b389799edb10db..fd3790dd7fe84fdaa88c5594e950e2689a013071 100644 --- a/src/util.ts +++ b/src/util.ts @@ -51,6 +51,10 @@ export interface IPatternMap { [index: string]: string; } +export interface IRequestPromise<T> extends PromiseLike<T> { + done (resolve: (msg: T) => {}, reject: (err: Error) => {}): void; +} + export class Util { /** * downloadFile - This function will take a URL and store the resulting data into diff --git a/test/test_discordbot.ts b/test/test_discordbot.ts index d6dcd1b3a2c1d9484bf60e5daced3b600cf04e14..dc3b79f9bc8e574c4d8344e7183320ffc115753b 100644 --- a/test/test_discordbot.ts +++ b/test/test_discordbot.ts @@ -69,6 +69,7 @@ const modDiscordBot = Proxyquire("../src/bot", { UploadContentFromUrl: async () => { return {mxcUrl: "uploaded"}; }, + DelayedPromise: Util.DelayedPromise, }, }, }); diff --git a/test/test_util.ts b/test/test_util.ts index 88380369b0ce0c8b620be061e30aa155aba227b4..45c39b16755a0869393c7c877f18bb3f61d29cc6 100644 --- a/test/test_util.ts +++ b/test/test_util.ts @@ -179,4 +179,11 @@ describe("Util", () => { expect(reply).to.equal("fox, fox and fox"); }); }); + describe("DelayedPromise", () => { + it("delays for some time", async () => { + const t = Date.now(); + await Util.DelayedPromise(250); + expect(Date.now()).to.be.greaterThan(t + 249); + }); + }); }); diff --git a/tools/chanfix.ts b/tools/chanfix.ts index a7c1904e89111c48a3a6b197626e9f708e5ab88e..8d4f4abf9b8510b3ef666184ee640170836fda11 100644 --- a/tools/chanfix.ts +++ b/tools/chanfix.ts @@ -19,7 +19,6 @@ import * as yaml from "js-yaml"; import * as fs from "fs"; import * as args from "command-line-args"; import * as usage from "command-line-usage"; -import * as Bluebird from "bluebird"; import { ChannelSyncroniser } from "../src/channelsyncroniser"; import { DiscordBridgeConfig } from "../src/config"; import { DiscordBot } from "../src/bot"; @@ -137,7 +136,7 @@ async function run() { let curDelay = config.limits.roomGhostJoinDelay; // we'll just re-use this client.guilds.forEach((guild) => { promiseList2.push((async () => { - await Bluebird.delay(curDelay); + await Util.DelayedPromise(curDelay); try { await discordbot.ChannelSyncroniser.OnGuildUpdate(guild, true); } catch (err) { diff --git a/tools/ghostfix.ts b/tools/ghostfix.ts index 6e9583846046e531706dfa4736be495085e095d0..9ce61d6d6102b4bf61566a0379aaae92b085c884 100644 --- a/tools/ghostfix.ts +++ b/tools/ghostfix.ts @@ -19,7 +19,6 @@ import * as yaml from "js-yaml"; import * as fs from "fs"; import * as args from "command-line-args"; import * as usage from "command-line-usage"; -import * as Bluebird from "bluebird"; import { DiscordBridgeConfig } from "../src/config"; import { Log } from "../src/log"; import { Util } from "../src/util"; @@ -125,7 +124,7 @@ async function run() { return; } promiseList.push((async () => { - await Bluebird.delay(curDelay); + await Util.DelayedPromise(curDelay); let currentSchedule = JOIN_ROOM_SCHEDULE[0]; const doJoin = async () => { await Util.DelayedPromise(currentSchedule); diff --git a/tools/userClientTools.ts b/tools/userClientTools.ts index 0ce5bbacb3d635beab9a6da0cd34a90c5b703003..f043bce3df72c831ab52685e8299e0b92fb63fa0 100644 --- a/tools/userClientTools.ts +++ b/tools/userClientTools.ts @@ -19,7 +19,6 @@ import * as fs from "fs"; import * as args from "command-line-args"; import * as usage from "command-line-usage"; import * as readline from "readline"; -import * as Bluebird from "bluebird"; import * as process from "process"; import { DiscordClientFactory } from "../src/clientfactory"; diff --git a/tslint.json b/tslint.json index 774ccf6b23b76023b827b36c7388a46e59c00ec4..cd7de561c3b3ba02450df7cb5bf011afd9c73be2 100644 --- a/tslint.json +++ b/tslint.json @@ -14,7 +14,7 @@ "typedef": { "severity": "warning" }, - "await-promise": [true, "Bluebird"], + "await-promise": [true], "curly": true, "no-empty": false, "no-invalid-this": true,