diff --git a/main.js b/main.js index 85d1778..93deff7 100644 --- a/main.js +++ b/main.js @@ -21,6 +21,7 @@ import request from 'request'; import FileType from 'file-type'; import express from 'express'; import bodyParser from 'body-parser'; +import fetch from 'node-fetch'; // Save script start time for ignoring older messages var boottimestamp = Date.now(); @@ -112,6 +113,25 @@ function checkSMS() { req.end(); } +/** + * Connect to the server and get the room ID and stuff + * @param {type} alias + * @returns {undefined} + */ +async function getRoomIDFromAlias(alias) { + var info = await client.getRoomIdForAlias(alias); + if (typeof info.room_id != "undefined") { + return info; + } + + var response = await fetch(settings.homeserver + "/_matrix/client/v3/directory/room/" + encodeURIComponent(alias)); + if (response.status != 200) { + throw new Error("Fetch returned invalid status code " + response.status); + } + var json = await response.json(); + return json; +} + /** * Join or create+join a room with alias #SMS_{tel}. If already joined, do nothing. @@ -120,17 +140,21 @@ function checkSMS() { * @param {function} callback function with the room ID as an argument. * @returns {undefined} */ -function createOrJoinSMSRoom(tel, ournumber, callback) { +async function createOrJoinSMSRoom(tel, ournumber, callback) { var roomName = "#SMS_" + tel + "_" + ournumber + ":" + settings.matrixdomain; logger.debug("Checking if room " + roomName + " exists."); - client.getRoomIdForAlias(roomName).then((res) => { + try { + var res = await getRoomIDFromAlias(roomName); + logger.info(JSON.stringify(res)); logger.debug("Room " + roomName + " exists!"); var inRoom = false; - var rooms = client.getRooms(); - for (var i = 0; i < rooms.length; i++) { - if (rooms[i].roomId == res.room_id) { - inRoom = true; - break; + if (!res.error) { + var rooms = (await client.getJoinedRooms()).joined_rooms; + for (var i = 0; i < rooms.length; i++) { + if (rooms[i] == res.room_id) { + inRoom = true; + break; + } } } if (inRoom) { @@ -143,11 +167,11 @@ function createOrJoinSMSRoom(tel, ournumber, callback) { client.joinRoom(res.room_id).then((room) => { logger.debug("Room " + roomName + " joined."); client.setRoomTag(room.room_id, "u.matrix-bridge-voxtelesys-sms", {tel: tel, ournumber: ournumber, order: 0.5}); - callback(room.room_id); + callback(res.room_id); }); } return; - }).catch((err) => { + } catch (err) { // room doesn't exist, create it logger.debug(err); logger.debug("Room " + roomName + " does not exist. Creating it now."); @@ -156,41 +180,42 @@ function createOrJoinSMSRoom(tel, ournumber, callback) { userPowerLevels[settings.inviteusers[i]] = 50; } userPowerLevels[settings["matrixuser"]] = 100; - client.createRoom({ - room_alias_name: "SMS_" + tel + "_" + ournumber, - preset: "trusted_private_chat", - visibility: "private", - invite: settings.inviteusers, - power_level_content_override: { - "events": { - "m.room.name": 50, - "m.room.power_levels": 50, - "m.room.canonical_alias": 100 - }, - "events_default": 0, - "invite": 50, - "kick": 50, - "notifications": { - "room": 50 + try { + var room = await client.createRoom({ + room_alias_name: "SMS_" + tel + "_" + ournumber, + preset: "trusted_private_chat", + visibility: "private", + invite: settings.inviteusers, + power_level_content_override: { + "events": { + "m.room.name": 50, + "m.room.power_levels": 50, + "m.room.canonical_alias": 100 + }, + "events_default": 0, + "invite": 50, + "kick": 50, + "notifications": { + "room": 50 + }, + "redact": 50, + "state_default": 50, + "users": userPowerLevels, + "users_default": 50 }, - "redact": 50, - "state_default": 50, - "users": userPowerLevels, - "users_default": 50 - }, - is_direct: true, - name: formatPhoneNumber(tel, "(NNN) NNN-NNNN"), - topic: "SMS conversation with " + formatPhoneNumber(tel, "(NNN) NNN-NNNN") + " (using " + formatPhoneNumber(ournumber, "(NNN) NNN-NNNN") + ")" - }).then((room) => { + is_direct: true, + name: formatPhoneNumber(tel, "(NNN) NNN-NNNN"), + topic: "SMS conversation with " + formatPhoneNumber(tel, "(NNN) NNN-NNNN") + " (using " + formatPhoneNumber(ournumber, "(NNN) NNN-NNNN") + ")" + }); logger.debug("Room" + roomName + " created with ID " + room.room_id); // The first message or two we send doesn't go through unless we do this. // It just spits out "Error sending event M_FORBIDDEN: Unknown room" instead. createOrJoinSMSRoom(tel, ournumber, callback); - }).catch((err) => { + } catch (errr) { logger.error("Could not create " + roomName + "."); - logger.error(err); - }); - }); + logger.error(errr); + } + } } function getAndUploadFile(url, callback) { @@ -229,16 +254,24 @@ function getAndUploadFile(url, callback) { /** * Send a message to a Matrix room. - * @param {string} roomid the room to post the message in. + * @param {string} room the room to post the message in. * @param {string} body message content. * @param {array} media Array of media URLs to download via HTTP(s) and send to Matrix. - * @param {function|undefined} callback passes true when successful, false on failure. * @returns {undefined} */ -function sendMatrix(roomid, body, media, callback) { +async function sendMatrix(room, body, media) { + var roomid = room; + if (room.startsWith("#")) { + try { + roomid = (await getRoomIDFromAlias()).room_id; + logger.info("Translated alias " + room + " to room ID " + roomid); + } catch (err) { + logger.error(err); + } + } if (Array.isArray(media)) { for (var i = 0; i < media.length; i++) { - getAndUploadFile(media[i], function (uri, mimetype) { + getAndUploadFile(media[i], async function (uri, mimetype) { if (mimetype == "image/jpg" || mimetype == "image/jpeg" || mimetype == "image/png" || mimetype == "image/gif") { var content = { body: "Image", @@ -258,13 +291,16 @@ function sendMatrix(roomid, body, media, callback) { } }; } - client.sendEvent(roomid, "m.room.message", content, "").then((res) => { - }).catch((err) => { + + try { + await client.sendEvent(roomid, "m.room.message", content, ""); + return true; + } catch (err) { if (err.data.error == "Unknown room") { return; } logger.error(err); - }); + } }); } } @@ -274,23 +310,17 @@ function sendMatrix(roomid, body, media, callback) { body: body, msgtype: "m.text" }; - client.sendEvent(roomid, "m.room.message", content, "").then((res) => { - if (typeof callback == "function") { - callback(true); - } - }).catch((err) => { - if (typeof callback == "function") { - callback(false); - } + try { + await client.sendEvent(roomid, "m.room.message", content, ""); + return true; + } catch (err) { if (err.data.error == "Unknown room") { - return; + return false; } logger.error(err); - }); - } else { - if (typeof callback == "function") { - callback(true); } + } else { + return true; } } @@ -448,6 +478,7 @@ function handleHTTPRequest(req, res) { if (settings.smsonlyto.length > 0 && settings.smsonlyto.indexOf(msg.to) != -1) { logger.info("Received SMS from " + msg.from + " for " + msg.to + ": " + msg.body); createOrJoinSMSRoom(msg.from, msg.to, function (roomid) { + logger.info("Sending to room " + roomid); sendMatrix(roomid, msg.body, msg.media); }); res.sendStatus(204); @@ -520,7 +551,7 @@ if (settings.matrixaccesstoken == false) { client.startClient({initialSyncLimit: 10}); logger.info("Plugged into the matrix."); - client.once('sync', function (state, prevState, res) { + client.once("sync", function (state, prevState, res) { logger.debug("Initial sync complete (" + state + ")"); initialsynccomplete = true; httpserver.post("*", jsonParser, (req, res) => { @@ -630,7 +661,6 @@ if (settings.matrixaccesstoken == false) { } var matches = room.name.match(/SMS_([1-9][0-9]+)(?:_([1-9][0-9]+))?/g); - console.log(event.getRoomId()); if (matches == null || (matches.length != 1 && matches.length != 2)) { client.getRoomTags(event.getRoomId()).then((response) => { console.log(response); diff --git a/package-lock.json b/package-lock.json index f535864..85572ee 100644 --- a/package-lock.json +++ b/package-lock.json @@ -13,7 +13,8 @@ "express": "^4.17.2", "file-type": "^16.5.0", "log4js": "^6.3.0", - "matrix-js-sdk": "^17.2.0", + "matrix-js-sdk": "^19.7.0", + "node-fetch": "^3.3.2", "request": "^2.88.2" } }, @@ -129,12 +130,9 @@ "integrity": "sha512-NmWvPnx0F1SfrQbYwOi7OeaNGokp9XhzNioJ/CSBs8Qa4vxug81mhJEAVZwxXuBmYB5KDRfMq/F3RR0BIU7sWg==" }, "node_modules/base-x": { - "version": "3.0.9", - "resolved": "https://registry.npmjs.org/base-x/-/base-x-3.0.9.tgz", - "integrity": "sha512-H7JU6iBHTal1gp56aKoaa//YUxEaAOUiydvrV/pILqIHXTtqxSkATOnDA2u+jZ/61sD+L/412+7kzXRtWukhpQ==", - "dependencies": { - "safe-buffer": "^5.0.1" - } + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/base-x/-/base-x-4.0.0.tgz", + "integrity": "sha512-FuwxlW4H5kh37X/oW59pwTzzTKRzfrrQwhmyspRM7swOEZcHtDZSCt45U6oKgtuFE+WYPblePMVIPR4RZrh/hw==" }, "node_modules/bcrypt-pbkdf": { "version": "1.0.2", @@ -197,11 +195,11 @@ ] }, "node_modules/bs58": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/bs58/-/bs58-4.0.1.tgz", - "integrity": "sha512-Ok3Wdf5vOIlBrgCvTq96gBkJw+JUEzdBgyaza5HLtPm7yTHkjRy8+JzNyHF7BHa0bNWOQIp3m5YF0nnFcOIKLw==", + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/bs58/-/bs58-5.0.0.tgz", + "integrity": "sha512-r+ihvQJvahgYT50JD05dyJNKlmmSlMoOGwn1lCcEzanPglg7TxYjioQUYehQ9mAR/+hOSd2jRc/Z2y5UxBymvQ==", "dependencies": { - "base-x": "^3.0.2" + "base-x": "^4.0.0" } }, "node_modules/bytes": { @@ -288,6 +286,14 @@ "node": ">=0.10" } }, + "node_modules/data-uri-to-buffer": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/data-uri-to-buffer/-/data-uri-to-buffer-4.0.1.tgz", + "integrity": "sha512-0R9ikRb668HB7QDxT1vkpuUBtqc53YyAwMwGeUFKRojY/NWKvdZ+9UYtRfGmhqNbRkTSVpMbmyhXipFFv2cb/A==", + "engines": { + "node": ">= 12" + } + }, "node_modules/date-format": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/date-format/-/date-format-3.0.0.tgz", @@ -456,6 +462,28 @@ "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==" }, + "node_modules/fetch-blob": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/fetch-blob/-/fetch-blob-3.2.0.tgz", + "integrity": "sha512-7yAQpD2UMJzLi1Dqv7qFYnPbaPx7ZfFK6PiIxQ4PfkGPyNyl2Ugx+a/umUonmKqjhM4DnfbMvdX6otXq83soQQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/jimmywarting" + }, + { + "type": "paypal", + "url": "https://paypal.me/jimmywarting" + } + ], + "dependencies": { + "node-domexception": "^1.0.0", + "web-streams-polyfill": "^3.0.3" + }, + "engines": { + "node": "^12.20 || >= 14.13" + } + }, "node_modules/file-type": { "version": "16.5.0", "resolved": "https://registry.npmjs.org/file-type/-/file-type-16.5.0.tgz", @@ -528,6 +556,17 @@ "node": ">= 0.12" } }, + "node_modules/formdata-polyfill": { + "version": "4.0.10", + "resolved": "https://registry.npmjs.org/formdata-polyfill/-/formdata-polyfill-4.0.10.tgz", + "integrity": "sha512-buewHzMvYL29jdeQTVILecSaZKnt/RJWjoZCF5OW60Z67/GmSLBkOFM7qh1PI3zFNtJbaZL5eQu1vLfazOwj4g==", + "dependencies": { + "fetch-blob": "^3.1.2" + }, + "engines": { + "node": ">=12.20.0" + } + }, "node_modules/forwarded": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz", @@ -800,18 +839,18 @@ "integrity": "sha512-1QEOsXO+bhyCroIe2/A5OwaxHvBm7EsSQ46DEDn8RBIfQwN5HWBpFvyWWR4QY0KHPPnnJdI99wgRiAl7Ad5qaA==" }, "node_modules/matrix-js-sdk": { - "version": "17.2.0", - "resolved": "https://registry.npmjs.org/matrix-js-sdk/-/matrix-js-sdk-17.2.0.tgz", - "integrity": "sha512-/IrgHCSVUZNVcKoPO20OF9Xog9X79a1ckmR7FwF5lSTNdmC7eQvU0XcFYCi5IXo57du+im69lEw8dLbPngZhoQ==", + "version": "19.7.0", + "resolved": "https://registry.npmjs.org/matrix-js-sdk/-/matrix-js-sdk-19.7.0.tgz", + "integrity": "sha512-mFN1LBmEpYHCH6II1F8o7y8zJr0kn1yX7ga7tRXHbLJAlBS4bAXRsEoAzdv6OrV8/dS325JlVUYQLHFHQWjYxg==", "dependencies": { "@babel/runtime": "^7.12.5", "another-json": "^0.2.0", "browser-request": "^0.3.3", - "bs58": "^4.0.1", + "bs58": "^5.0.0", "content-type": "^1.0.4", "loglevel": "^1.7.1", "matrix-events-sdk": "^0.0.1-beta.7", - "p-retry": "^4.5.0", + "p-retry": "4", "qs": "^6.9.6", "request": "^2.88.2", "unhomoglyph": "^1.0.6" @@ -898,6 +937,41 @@ "node": ">= 0.6" } }, + "node_modules/node-domexception": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/node-domexception/-/node-domexception-1.0.0.tgz", + "integrity": "sha512-/jKZoMpw0F8GRwl4/eLROPA3cfcXtLApP0QzLmUT/HuPCZWyB7IY9ZrMeKw2O/nFIqPQB3PVM9aYm0F312AXDQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/jimmywarting" + }, + { + "type": "github", + "url": "https://paypal.me/jimmywarting" + } + ], + "engines": { + "node": ">=10.5.0" + } + }, + "node_modules/node-fetch": { + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-3.3.2.tgz", + "integrity": "sha512-dRB78srN/l6gqWulah9SrxeYnxeddIG30+GOqK/9OlLVyLg3HPnr6SqOWTWOXKRwC2eGYCkZ59NNuSgvSrpgOA==", + "dependencies": { + "data-uri-to-buffer": "^4.0.0", + "fetch-blob": "^3.1.4", + "formdata-polyfill": "^4.0.10" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/node-fetch" + } + }, "node_modules/oauth-sign": { "version": "0.9.0", "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.9.0.tgz", @@ -1410,6 +1484,14 @@ "core-util-is": "1.0.2", "extsprintf": "^1.2.0" } + }, + "node_modules/web-streams-polyfill": { + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/web-streams-polyfill/-/web-streams-polyfill-3.3.3.tgz", + "integrity": "sha512-d2JWLCivmZYTSIoge9MsgFCZrt571BikcWGYkjC1khllbTeDlGqZ2D8vD8E/lJa8WGWbb7Plm8/XJYV7IJHZZw==", + "engines": { + "node": ">= 8" + } } }, "dependencies": { @@ -1509,12 +1591,9 @@ "integrity": "sha512-NmWvPnx0F1SfrQbYwOi7OeaNGokp9XhzNioJ/CSBs8Qa4vxug81mhJEAVZwxXuBmYB5KDRfMq/F3RR0BIU7sWg==" }, "base-x": { - "version": "3.0.9", - "resolved": "https://registry.npmjs.org/base-x/-/base-x-3.0.9.tgz", - "integrity": "sha512-H7JU6iBHTal1gp56aKoaa//YUxEaAOUiydvrV/pILqIHXTtqxSkATOnDA2u+jZ/61sD+L/412+7kzXRtWukhpQ==", - "requires": { - "safe-buffer": "^5.0.1" - } + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/base-x/-/base-x-4.0.0.tgz", + "integrity": "sha512-FuwxlW4H5kh37X/oW59pwTzzTKRzfrrQwhmyspRM7swOEZcHtDZSCt45U6oKgtuFE+WYPblePMVIPR4RZrh/hw==" }, "bcrypt-pbkdf": { "version": "1.0.2", @@ -1567,11 +1646,11 @@ "integrity": "sha512-YyNI4qJJ+piQG6MMEuo7J3Bzaqssufx04zpEKYfSrl/1Op59HWali9zMtBpXnkmqMcOuWJPZvudrm9wISmnCbg==" }, "bs58": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/bs58/-/bs58-4.0.1.tgz", - "integrity": "sha512-Ok3Wdf5vOIlBrgCvTq96gBkJw+JUEzdBgyaza5HLtPm7yTHkjRy8+JzNyHF7BHa0bNWOQIp3m5YF0nnFcOIKLw==", + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/bs58/-/bs58-5.0.0.tgz", + "integrity": "sha512-r+ihvQJvahgYT50JD05dyJNKlmmSlMoOGwn1lCcEzanPglg7TxYjioQUYehQ9mAR/+hOSd2jRc/Z2y5UxBymvQ==", "requires": { - "base-x": "^3.0.2" + "base-x": "^4.0.0" } }, "bytes": { @@ -1637,6 +1716,11 @@ "assert-plus": "^1.0.0" } }, + "data-uri-to-buffer": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/data-uri-to-buffer/-/data-uri-to-buffer-4.0.1.tgz", + "integrity": "sha512-0R9ikRb668HB7QDxT1vkpuUBtqc53YyAwMwGeUFKRojY/NWKvdZ+9UYtRfGmhqNbRkTSVpMbmyhXipFFv2cb/A==" + }, "date-format": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/date-format/-/date-format-3.0.0.tgz", @@ -1771,6 +1855,15 @@ "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==" }, + "fetch-blob": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/fetch-blob/-/fetch-blob-3.2.0.tgz", + "integrity": "sha512-7yAQpD2UMJzLi1Dqv7qFYnPbaPx7ZfFK6PiIxQ4PfkGPyNyl2Ugx+a/umUonmKqjhM4DnfbMvdX6otXq83soQQ==", + "requires": { + "node-domexception": "^1.0.0", + "web-streams-polyfill": "^3.0.3" + } + }, "file-type": { "version": "16.5.0", "resolved": "https://registry.npmjs.org/file-type/-/file-type-16.5.0.tgz", @@ -1830,6 +1923,14 @@ "mime-types": "^2.1.12" } }, + "formdata-polyfill": { + "version": "4.0.10", + "resolved": "https://registry.npmjs.org/formdata-polyfill/-/formdata-polyfill-4.0.10.tgz", + "integrity": "sha512-buewHzMvYL29jdeQTVILecSaZKnt/RJWjoZCF5OW60Z67/GmSLBkOFM7qh1PI3zFNtJbaZL5eQu1vLfazOwj4g==", + "requires": { + "fetch-blob": "^3.1.2" + } + }, "forwarded": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz", @@ -2028,18 +2129,18 @@ "integrity": "sha512-1QEOsXO+bhyCroIe2/A5OwaxHvBm7EsSQ46DEDn8RBIfQwN5HWBpFvyWWR4QY0KHPPnnJdI99wgRiAl7Ad5qaA==" }, "matrix-js-sdk": { - "version": "17.2.0", - "resolved": "https://registry.npmjs.org/matrix-js-sdk/-/matrix-js-sdk-17.2.0.tgz", - "integrity": "sha512-/IrgHCSVUZNVcKoPO20OF9Xog9X79a1ckmR7FwF5lSTNdmC7eQvU0XcFYCi5IXo57du+im69lEw8dLbPngZhoQ==", + "version": "19.7.0", + "resolved": "https://registry.npmjs.org/matrix-js-sdk/-/matrix-js-sdk-19.7.0.tgz", + "integrity": "sha512-mFN1LBmEpYHCH6II1F8o7y8zJr0kn1yX7ga7tRXHbLJAlBS4bAXRsEoAzdv6OrV8/dS325JlVUYQLHFHQWjYxg==", "requires": { "@babel/runtime": "^7.12.5", "another-json": "^0.2.0", "browser-request": "^0.3.3", - "bs58": "^4.0.1", + "bs58": "^5.0.0", "content-type": "^1.0.4", "loglevel": "^1.7.1", "matrix-events-sdk": "^0.0.1-beta.7", - "p-retry": "^4.5.0", + "p-retry": "4", "qs": "^6.9.6", "request": "^2.88.2", "unhomoglyph": "^1.0.6" @@ -2098,6 +2199,21 @@ "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz", "integrity": "sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==" }, + "node-domexception": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/node-domexception/-/node-domexception-1.0.0.tgz", + "integrity": "sha512-/jKZoMpw0F8GRwl4/eLROPA3cfcXtLApP0QzLmUT/HuPCZWyB7IY9ZrMeKw2O/nFIqPQB3PVM9aYm0F312AXDQ==" + }, + "node-fetch": { + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-3.3.2.tgz", + "integrity": "sha512-dRB78srN/l6gqWulah9SrxeYnxeddIG30+GOqK/9OlLVyLg3HPnr6SqOWTWOXKRwC2eGYCkZ59NNuSgvSrpgOA==", + "requires": { + "data-uri-to-buffer": "^4.0.0", + "fetch-blob": "^3.1.4", + "formdata-polyfill": "^4.0.10" + } + }, "oauth-sign": { "version": "0.9.0", "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.9.0.tgz", @@ -2479,6 +2595,11 @@ "core-util-is": "1.0.2", "extsprintf": "^1.2.0" } + }, + "web-streams-polyfill": { + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/web-streams-polyfill/-/web-streams-polyfill-3.3.3.tgz", + "integrity": "sha512-d2JWLCivmZYTSIoge9MsgFCZrt571BikcWGYkjC1khllbTeDlGqZ2D8vD8E/lJa8WGWbb7Plm8/XJYV7IJHZZw==" } } } diff --git a/package.json b/package.json index 257a73b..2b23f23 100644 --- a/package.json +++ b/package.json @@ -19,6 +19,7 @@ "file-type": "^16.5.0", "log4js": "^6.3.0", "matrix-js-sdk": "^19.7.0", + "node-fetch": "^3.3.2", "request": "^2.88.2" } -} \ No newline at end of file +}