Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { ReplaceVariable } from "../../../../../../types/variables";
import { EffectTrigger } from "../../../../../../shared/effect-constants";
import { OutputDataType, VariableCategory } from "../../../../../../shared/variable-constants";
import { FirebotParsedMessagePart } from "../../../../../../types/chat";
import { ReplaceVariable } from "../../../../../../types/variables";

const triggers = {};
triggers[EffectTrigger.MANUAL] = true;
Expand All @@ -15,22 +16,67 @@ triggers[EffectTrigger.EVENT] = [
const model: ReplaceVariable = {
definition: {
handle: "chatMessageTextOnly",
description: "Outputs the chat message from the associated command or event, with any emotes or URLs trimmed out",
description: "Outputs the chat message text from the associated command or chat event, with any emotes, URLs, or cheermotes removed",
usage: "chatMessageTextOnly[trimCommandTriggerDefaultTrue]",
examples: [
{
usage: "chatMessageTextOnly",
description: "Gets the message text with the command trigger removed, and with any emotes, URLs, or cheermotes removed."
},
{
usage: "chatMessageTextOnly[true]",
description: "Gets the message text with the command trigger removed, and with any emotes, URLs, or cheermotes removed."
},
{
usage: "chatMessageTextOnly[false]",
description: "Gets the message text (including command trigger) with any emotes, URLS, or cheermotes removed."
}
],
triggers: triggers,
categories: [VariableCategory.COMMON, VariableCategory.TRIGGER],
possibleDataOutput: [OutputDataType.TEXT]
},
evaluator: (trigger) => {
let messageParts = [];
if (trigger.type === EffectTrigger.COMMAND) {
evaluator: (trigger, ...args: unknown[]) => {
let messageParts: FirebotParsedMessagePart[] = [];
if (trigger?.type === EffectTrigger.COMMAND && trigger.metadata?.chatMessage?.parts) {
messageParts = trigger.metadata.chatMessage.parts;
} else if (trigger.type === EffectTrigger.EVENT) {
} else if (trigger?.type === EffectTrigger.EVENT && trigger.metadata?.eventData?.chatMessage?.parts) {
messageParts = trigger.metadata.eventData.chatMessage.parts;
}

const textParts = messageParts.filter(p => p.type === "text").map(p => p.text);
return textParts.join(" ").trim();
// Get all text parts trimmed into a flat array. None /should/ ever be null, but defensively filter, then filter out empties trim created.
// e.g: "!trigger bleedPurple bleedPurple" maps to ["!trigger ", " "], trims to ["!trigger", ""], filters again to ["!trigger"]
const textParts = messageParts
.filter(mp => mp.type === "text" && mp.text !== null)
.map(mp => mp.text.trim())
.filter(tp => tp !== "");

// Trim the command trigger if this was a command, unless an optional argument of false was provided.
if (trigger?.type === EffectTrigger.COMMAND && trigger?.metadata?.command?.trigger !== null &&
(args.length < 1 || !(args[0] === false || `${args[0]}`.toLowerCase() === "false"))) {

const triggerRegex = new RegExp(trigger.metadata.command.trigger, "i");
const triggerIndex = textParts.findIndex(tp => triggerRegex.test(tp));

if (triggerIndex >= 0) {
// A trigger /could/ greedy include white space, and be in the middle of a part, but most triggers likely won't.
// So replace it with "text" that DOES have whitespace around it, and greedily replace /that/ with a single space.
textParts[triggerIndex] = textParts[triggerIndex]
.replace(triggerRegex, " \x1A ")
// eslint-disable-next-line no-control-regex
.replace(/\s+\x1A\s+/, " ")
.trim();

// Remove the entire text portion if it's now empty, such as with: "!trigger bleedPurple foo bar"
if (textParts[triggerIndex] === "") {
textParts.splice(triggerIndex, 1);
}
}
}

// Return the array concatenated with spaces, or an empty string.
return textParts.join(" ");
}
};

export default model;
export default model;