@rocket.chat/forked-matrix-bot-sdk
Version:
TypeScript/JavaScript SDK for Matrix bots and appservices
125 lines (124 loc) • 5.52 kB
JavaScript
;
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.RichRepliesPreprocessor = void 0;
const __1 = require("..");
/**
* Processes rich replies found in events. This automatically strips
* the fallback representation from events, providing the information
* as a top level "mx_richreply" key. The "mx_richreply" property may
* be casted to the type IRichReplyMetadata.
* @category Preprocessors
*/
class RichRepliesPreprocessor {
/**
* Creates a new rich replies preprocessor.
* @param fetchRealEventContents If enabled, this preprocessor will
* attempt to get the real event contents and append them to the event
* information.
*/
constructor(fetchRealEventContents = false) {
this.fetchRealEventContents = fetchRealEventContents;
}
getSupportedEventTypes() {
return ["m.room.message"];
}
processEvent(event, client, kind) {
return __awaiter(this, void 0, void 0, function* () {
if (kind && kind !== __1.EventKind.RoomEvent)
return;
if (!event["content"])
return;
if (!event["content"]["m.relates_to"])
return;
if (!event["content"]["m.relates_to"]["m.in_reply_to"])
return;
const parentEventId = event["content"]["m.relates_to"]["m.in_reply_to"]["event_id"];
if (!parentEventId)
return;
let fallbackHtml = "";
let fallbackText = "";
let fallbackSender = "";
let realHtml = event["content"]["formatted_body"];
let realText = event["content"]["body"];
let lenient = false;
if (event["content"]["format"] !== "org.matrix.custom.html" || !event["content"]["formatted_body"]) {
lenient = true; // Not safe to parse: probably not HTML
}
else {
const formattedBody = event["content"]["formatted_body"];
if (!formattedBody.startsWith("<mx-reply>") || formattedBody.indexOf("</mx-reply>") === -1) {
lenient = true; // Doesn't look like a reply
}
else {
const parts = formattedBody.split("</mx-reply>");
const fbHtml = parts[0];
realHtml = parts[1];
const results = fbHtml.match(/<br[ ]*[\/]{0,2}>(.*)<\/blockquote>\s*$/i);
if (!results) {
lenient = true;
}
else {
fallbackHtml = results[1];
}
}
}
let lastLine = "";
let processedFallback = false;
const body = event["content"]["body"] || "";
for (const line of body.split("\n")) {
if (line.startsWith("> ") && !processedFallback) {
fallbackText += line.substring(2) + "\n";
lastLine = line;
}
else if (!processedFallback) {
lastLine = line;
realText = "";
processedFallback = true;
}
else {
realText += line + "\n";
}
}
const firstFallbackLine = fallbackText.split("\n")[0];
const matches = firstFallbackLine.match(/<(@.*:.*)>/);
if (!matches) {
lenient = true;
}
else {
fallbackSender = matches[1];
}
const metadata = {
wasLenient: lenient,
fallbackHtmlBody: fallbackHtml ? fallbackHtml.trim() : "",
fallbackPlainBody: fallbackText ? fallbackText.trim() : "",
fallbackSender: fallbackSender ? fallbackSender.trim() : "",
parentEventId: parentEventId ? parentEventId.trim() : "",
realEvent: null,
};
if (this.fetchRealEventContents) {
try {
metadata.realEvent = yield client.getEvent(event["room_id"], parentEventId);
}
catch (e) {
__1.LogService.error("RichRepliesPreprocessor", "Failed to fetch real event:");
__1.LogService.error("RichRepliesPreprocessor", (0, __1.extractRequestError)(e));
metadata.wasLenient = true; // failed to fetch event
}
}
event["mx_richreply"] = metadata;
event["content"]["body"] = realText.trim();
event["content"]["formatted_body"] = realHtml.trim();
return event;
});
}
}
exports.RichRepliesPreprocessor = RichRepliesPreprocessor;