diff --git a/src/discordbot.ts b/src/discordbot.ts index e9b385adffdd1e7723317688429357a0c564c1bb..cc5ac86881a1012b9facca2129755634e0a8a483 100644 --- a/src/discordbot.ts +++ b/src/discordbot.ts @@ -3,6 +3,7 @@ import * as Discord from "discord.js"; import * as log from "npmlog"; import { MatrixUser, RemoteUser } from "matrix-appservice-bridge"; import { Util } from "./util"; +import * as mime from "mime"; export class DiscordBot { private config: DiscordBridgeConfig; @@ -23,19 +24,7 @@ export class DiscordBot { this.bot.on("typingStart", (c, u) => { this.OnTyping(c, u, true); }); this.bot.on("typingStop", (c, u) => { this.OnTyping(c, u, false); }); - // create an event listener for messages - this.bot.on("message", (msg) => { - if (msg.author.id === this.bot.user.id) { - return; // Skip *our* messages - } - this.UpdateUser(msg.author).then(() => { - return this.GetRoomIdFromChannel(msg.channel); - }).then((room) => { - const intent = this.bridge.getIntentFromLocalpart(`_discord_${msg.author.id}`); - intent.sendText(room, msg.content); - }); - }); - + this.bot.on("message", this.OnMessage.bind(this)); this.bot.login(this.config.auth.botToken); } @@ -46,27 +35,28 @@ export class DiscordBot { public LookupRoom (server: string, room: string): Promise<Discord.TextChannel> { const guild = this.bot.guilds.find((g) => { - return (g.id === server || g.name.replace(" ", "-") === server); + return (g.id === server || g.name.toLowerCase().replace(/ /g, '-') === server.toLowerCase()); }); if (guild === null) { - return Promise.reject("Guild not found"); + return Promise.reject(`Guild '${server}' not found`); } const channel = guild.channels.find((c) => { - return ((c.id === room || c.name.replace(" ", "-") === room ) && c.type === "text"); + return ((c.id === room || c.name.toLowerCase().replace(/ /g, '-') === room.toLowerCase() ) && c.type === "text"); }); if (channel === null) { - return Promise.reject("Channel not found"); + return Promise.reject(`Channel '${room}' not found`); } return Promise.resolve(channel); } public ProcessMatrixMsgEvent(event, guild_id: string, channel_id: string): Promise<any> { - if (event.content.msgtype !== "m.text") { + if (["m.text", "m.image"].indexOf(event.content.msgtype) === -1) { return Promise.reject("The AS doesn't support non m.text messages"); } let chan; + let embed; const mxClient = this.bridge.getClientFactory().getClientAs(); this.LookupRoom(guild_id, channel_id).then((channel) => { chan = channel; @@ -78,7 +68,7 @@ export class DiscordBot { if (profile.avatar_url) { profile.avatar_url = mxClient.mxcUrlToHttp(profile.avatar_url); } - const embed = new Discord.RichEmbed({ + embed = new Discord.RichEmbed({ author: { name: profile.displayname, icon_url: profile.avatar_url, @@ -87,8 +77,25 @@ export class DiscordBot { }, description: event.content.body, }); - log.info("DiscordBot", "Outgoing Message ", embed) - chan.sendEmbed(embed); + if (event.content.msgtype === "m.image") { + return Util.DownloadFile(mxClient.mxcUrlToHttp(event.content.url)); + } + else { + return Promise.resolve(null); + } + }).then(img_buffer => { + if(img_buffer !== null) { + return { + file : { + name: event.content.body, + attachment: img_buffer, + } + }; + } + return {} + }).then((opts) => { + chan.sendEmbed(embed, opts); + log.info("DiscordBot", "Outgoing Message ", embed); }).catch((err) => { log.error("DiscordBot", "Couldn't send message. ", err); }); @@ -140,7 +147,7 @@ export class DiscordBot { }).then(() => { console.log(remoteUser.get("avatarurl"), "!==", discordUser.avatarURL); if (remoteUser.get("avatarurl") !== discordUser.avatarURL && discordUser.avatarURL !== null) { - return Util.uploadContentFromUrl(this.bridge, discordUser.avatarURL, intent, discordUser.avatar).then((avatar) => { + return Util.UploadContentFromUrl(this.bridge, discordUser.avatarURL, intent, discordUser.avatar).then((avatar) => { intent.setAvatarUrl(avatar.mxc_url).then(() => { remoteUser.set("avatarurl", discordUser.avatarURL); return userStore.setRemoteUser(remoteUser); @@ -157,4 +164,41 @@ export class DiscordBot { intent.sendTyping(room, isTyping); }); } + + private OnMessage(msg: Discord.Message) { + if (msg.author.id === this.bot.user.id) { + return; // Skip *our* messages + } + this.UpdateUser(msg.author).then(() => { + return this.GetRoomIdFromChannel(msg.channel); + }).then((room) => { + const intent = this.bridge.getIntentFromLocalpart(`_discord_${msg.author.id}`); + // Check Attachements + msg.attachments.forEach(attachment => { + Util.UploadContentFromUrl(this.bridge, attachment.url, intent, attachment.filename).then(content => { + const file_mime = mime.lookup(attachment.filename); + const msgtype = attachment.height ? "m.image" : "m.file"; + const info = { + mimetype: file_mime, + size: attachment.filesize, + w: null, + h: null, + }; + if (msgtype == "m.image") { + info.w = attachment.width; + info.h = attachment.height; + } + intent.sendMessage(room, { + body: attachment.filename, + info, + msgtype, + "url": content.mxc_url, + }); + }); + }); + if(msg.content !== null && msg.content !== "") { + intent.sendText(room, msg.content); + } + }); + } } diff --git a/src/matrixroomhandler.ts b/src/matrixroomhandler.ts index e4d3f4f5ec1453d0ece87c6fd8741fde062e5b84..a42e966ffc06ea85d6719015570301181fe267bc 100644 --- a/src/matrixroomhandler.ts +++ b/src/matrixroomhandler.ts @@ -37,8 +37,8 @@ export class MatrixRoomHandler { } public OnEvent (request, context) { - console.log(context); const event = request.getData(); + console.log("New Event:", event); if (event.type === "m.room.message" && context.rooms.remote) { let srvChanPair = context.rooms.remote.roomId.substr("_discord".length).split("_", 2); this.discord.ProcessMatrixMsgEvent(event, srvChanPair[0], srvChanPair[1]); @@ -46,7 +46,7 @@ export class MatrixRoomHandler { } public OnAliasQuery (alias: string, aliasLocalpart: string): Promise<any> { - let srvChanPair = aliasLocalpart.substr("_discord_".length).split("_", 2); + let srvChanPair = aliasLocalpart.substr("_discord_".length).split("#", 2); if (srvChanPair.length < 2 || srvChanPair[0] === "" || srvChanPair[1] === "") { log.warn("MatrixRoomHandler", `Alias '${aliasLocalpart}' was missing a server and/or a channel`); return; @@ -74,10 +74,10 @@ export class MatrixRoomHandler { const cname = channel.name.replace(" ", "-"); this.alias_list[alias] = [ - `#_discord_${channel.guild.id}_${channel.id}:${this.config.bridge.domain}`, - `#_discord_${channel.guild.id}_${cname}:${this.config.bridge.domain}`, - `#_discord_${gname}_${channel.id}:${this.config.bridge.domain}`, - `#_discord_${gname}_${cname}:${this.config.bridge.domain}`, + `#_discord_${channel.guild.id}#${channel.id}:${this.config.bridge.domain}`, + `#_discord_${channel.guild.id}#${cname}:${this.config.bridge.domain}`, + `#_discord_${gname}#${channel.id}:${this.config.bridge.domain}`, + `#_discord_${gname}#${cname}:${this.config.bridge.domain}`, ]; const creationOpts = {