Sélectionner une révision Git
-
hsellambin a rédigéhsellambin a rédigé
matrixeventprocessor.ts 5,37 Kio
import * as Discord from "discord.js";
import {MessageProcessorOpts, MessageProcessor} from "./messageprocessor";
import {DiscordBot} from "./bot";
import {DiscordBridgeConfig} from "./config";
import * as escapeStringRegexp from "escape-string-regexp";
import {Util} from "./util";
import * as path from "path";
import * as mime from "mime";
import * as log from "npmlog";
const MaxFileSize = 8000000;
const MIN_NAME_LENGTH = 2;
const MAX_NAME_LENGTH = 32;
const DISCORD_EMOJI_REGEX = /:(\w+):/g;
export class MatrixEventProcessorOpts {
constructor(
readonly config: DiscordBridgeConfig,
readonly bridge: any,
) {
}
}
export class MatrixEventProcessor {
private config: DiscordBridgeConfig;
private bridge: any;
constructor (opts: MatrixEventProcessorOpts) {
this.config = opts.config;
this.bridge = opts.bridge;
}
public EventToEmbed(event: any, profile: any|null, channel: Discord.TextChannel): Discord.RichEmbed {
let body = this.config.bridge.disableDiscordMentions ? event.content.body :
this.FindMentionsInPlainBody(
event.content.body,
channel.members.array(),
);
// Replace @everyone
if (this.config.bridge.disableEveryoneMention) {
body = body.replace(new RegExp(`@everyone`, "g"), "@ everyone");
}
// Replace @here
if (this.config.bridge.disableHereMention) {
body = body.replace(new RegExp(`@here`, "g"), "@ here");
}
// Handle discord custom emoji
body = this.ReplaceDiscordEmoji(body, channel.guild);
let displayName = event.sender;
let avatarUrl = undefined;
if (profile) {
if (profile.displayname &&
profile.displayname.length >= MIN_NAME_LENGTH &&
profile.displayname.length <= MAX_NAME_LENGTH) {
displayName = profile.displayname;
}
if (profile.avatar_url) {
const mxClient = this.bridge.getClientFactory().getClientAs();
avatarUrl = mxClient.mxcUrlToHttp(profile.avatar_url);
}
/* See issue #82
const isMarkdown = (event.content.format === "org.matrix.custom.html");
if (!isMarkdown) {
body = "\\" + body;
}
if (event.content.msgtype === "m.emote") {
body = `*${body}*`;
}
*/
}
return new Discord.RichEmbed({
author: {
name: displayName.substr(0, MAX_NAME_LENGTH),
icon_url: avatarUrl,
url: `https://matrix.to/#/${event.sender}`,
},
description: body,
});
}
public FindMentionsInPlainBody(body: string, members: Discord.GuildMember[]): string {
const WORD_BOUNDARY = "(^|\:|\#|```|\\s|$|,)";
for (const member of members) {
const matcher = escapeStringRegexp(member.user.username + "#" + member.user.discriminator) + "|" +
escapeStringRegexp(member.displayName);
const regex = new RegExp(
`(${WORD_BOUNDARY})(@?(${matcher}))(?=${WORD_BOUNDARY})`
, "igmu");
body = body.replace(regex, `$1<@!${member.id}>`);
}
return body;
}
public ReplaceDiscordEmoji(content: string, guild: Discord.Guild): string {
let results = DISCORD_EMOJI_REGEX.exec(content);
while (results !== null) {
const emojiName = results[1];
const emojiNameWithColons = results[0];
// Check if this emoji exists in the guild
const emoji = guild.emojis.find((e) => e.name === emojiName);
if (emoji) {
// Replace :a: with <:a:123ID123>
content = content.replace(emojiNameWithColons, `<${emojiNameWithColons}${emoji.id}>`);
}
results = DISCORD_EMOJI_REGEX.exec(content);
}
return content;
}
public async HandleAttachment(event: any, mxClient: any): Promise<string|Discord.FileOptions> {
const hasAttachment = [
"m.image",
"m.audio",
"m.video",
"m.file",
"m.sticker",
].indexOf(event.content.msgtype) !== -1;
if (!hasAttachment) {
return "";
}
if (event.content.info == null) {
log.info("Event was an attachment type but was missing a content.info");
return "";
}
let size = event.content.info.size || 0;
const url = mxClient.mxcUrlToHttp(event.content.url);
const name = this.GetFilenameForMediaEvent(event.content);
if (size < MaxFileSize) {
const attachment = await Util.DownloadFile(url);
size = attachment.byteLength;
if (size < MaxFileSize) {
return {
name,
attachment,
};
}
}
return `[${name}](${url})`;
}
private GetFilenameForMediaEvent(content: any): string {
if (content.body) {
if (path.extname(content.body) !== "") {
return content.body;
}
return path.basename(content.body) + "." + mime.extension(content.info.mimetype);
}
return "matrix-media." + mime.extension(content.info.mimetype);
}
}