diff --git a/package.json b/package.json index c9af63d94d57dc5cccc655bd6a3471f5968131e8..82e8725659b312fed1f981c073df3510d6905ba1 100644 --- a/package.json +++ b/package.json @@ -33,6 +33,7 @@ "bluebird": "^3.4.7", "discord.js": "^11.0.0", "js-yaml": "^3.8.1", + "mime": "^1.3.4", "npmlog": "^4.0.2", "tslint": "^4.4.2", "typescript": "^2.1.6" diff --git a/src/util.ts b/src/util.ts new file mode 100644 index 0000000000000000000000000000000000000000..1cb4b3695cb908ee2779bb581d0d5d7ce0f34d03 --- /dev/null +++ b/src/util.ts @@ -0,0 +1,73 @@ +import * as http from "http"; +import * as https from "https"; +import { Bridge, Intent } from "matrix-appservice-bridge"; +import { Buffer } from "buffer"; +import * as log from "npmlog"; +import * as mime from "mime"; + +export class Util { + /** + * uploadContentFromUrl - Upload content from a given URL to the homeserver + * and return a MXC URL. + */ + public static uploadContentFromUrl(bridge: Bridge, url: string, id: string | Intent, name: string): Promise<any> { + let contenttype; + let size; + id = id || null; + name = name || null; + return new Promise((resolve, reject) => { + let ht; + if (url.startsWith("https")) { + ht = https; + } else { + ht = http; + } + const req = ht.get( url, (res) => { + let buffer = Buffer.alloc(0); + + if (res.headers.hasOwnProperty("content-type")) { + contenttype = res.headers["content-type"]; + } else { + log.verbose("UploadContent", "No content-type given by server, guessing based on file name."); + contenttype = mime.lookup(url); + } + + if (name === null) { + let names = url.split("/"); + name = names[names.length - 1]; + } + + res.on("data", (d) => { + buffer = Buffer.concat([buffer, d]); + }); + + res.on("end", () => { + resolve(buffer); + }); + }); + req.on("error", (err) => { + reject(`Failed to download. ${err.code}`); + }); + }).then((buffer: Buffer) => { + size = buffer.length; + if (id === null || typeof id === "string") { + id = bridge.getIntent(id); + } + return id.getClient().uploadContent(buffer, { + name, + type: contenttype, + onlyContentUri: true, + rawResponse: false, + }); + }).then((contentUri) => { + log.verbose("UploadContent", "Media uploaded to %s", contentUri); + return { + mxc_url: contentUri, + size, + }; + }).catch((reason) => { + log.error("UploadContent", "Failed to upload content:\n%s", reason); + throw reason; + }); + } +}