@@ -486,7 +486,8 @@ const playVideo = {
}
}
- const clipVideoUrl = `${clip.thumbnailUrl.split("-preview-")[0]}.mp4`;
+ //const clipVideoUrl = `${clip.thumbnailUrl.split("-preview-")[0]}.mp4`;
+ const clipVideoUrl = clip.embedUrl;
const clipDuration = clip.duration;
const volume = parseInt(effect.volume) / 10;
diff --git a/src/backend/effects/queues/effect-queue-runner.js b/src/backend/effects/queues/effect-queue-runner.js
index b274ab262..6c7c0d95d 100644
--- a/src/backend/effects/queues/effect-queue-runner.js
+++ b/src/backend/effects/queues/effect-queue-runner.js
@@ -142,6 +142,10 @@ class EffectQueue {
logger.debug(`Added more effects to queue ${this.id}. Current length=${this._queue.length}`);
+ eventManager.triggerEvent("firebot", "effect-queue-added", {
+ effectQueueId: this.id
+ });
+
this.sendQueueLengthUpdate();
this.processEffectQueue();
@@ -169,11 +173,21 @@ class EffectQueue {
pauseQueue() {
logger.debug(`Pausing queue ${this.id}...`);
+
+ eventManager.triggerEvent("firebot", "effect-queue-status", {
+ effectQueueId: this.id
+ });
+
this._paused = true;
}
resumeQueue() {
logger.debug(`Resuming queue ${this.id}...`);
+
+ eventManager.triggerEvent("firebot", "effect-queue-status", {
+ effectQueueId: this.id
+ });
+
this._paused = false;
this.processEffectQueue();
}
diff --git a/src/backend/events/EventManager.js b/src/backend/events/EventManager.js
index dd350465d..b9594d604 100644
--- a/src/backend/events/EventManager.js
+++ b/src/backend/events/EventManager.js
@@ -124,7 +124,13 @@ ipcMain.on("triggerManualEvent", function(_, data) {
return;
}
- const meta = event.manualMetadata || {};
+ const meta = structuredClone(event.manualMetadata || {});
+ for (const [key, value] of Object.entries(meta)) {
+ if (typeof value !== 'object' || value == null || Array.isArray(value) || value.type == null || value.value == null) {
+ continue;
+ }
+ meta[key] = value.value;
+ }
if (meta.username == null) {
const accountAccess = require("../common/account-access");
meta.username = accountAccess.getAccounts().streamer.username;
diff --git a/src/backend/events/builtin/firebot-event-source.js b/src/backend/events/builtin/firebot-event-source.js
index 3487885fb..41603ab88 100644
--- a/src/backend/events/builtin/firebot-event-source.js
+++ b/src/backend/events/builtin/firebot-event-source.js
@@ -113,6 +113,25 @@ const firebotEventSource = {
queueName: "Just Chatting"
}
},
+ {
+ id: "effect-queue-added",
+ name: "Effect Queue Added",
+ description: "When an new entry added to effect queue.",
+ cached: false,
+ manualMetadata: {
+ queueName: "Just Chatting"
+ }
+ },
+ {
+ id: "effect-queue-status",
+ name: "Effect Queue Status",
+ description: "When an effect queue status changes.",
+ cached: false,
+ manualMetadata: {
+ queueName: "Just Chatting",
+ status: "paused"
+ }
+ },
{
id: "before-firebot-closed",
name: "Before Firebot Closed",
diff --git a/src/backend/events/builtin/twitch-event-source.js b/src/backend/events/builtin/twitch-event-source.js
index 0754c0767..2a258a3ff 100644
--- a/src/backend/events/builtin/twitch-event-source.js
+++ b/src/backend/events/builtin/twitch-event-source.js
@@ -7,7 +7,7 @@ module.exports = {
events: [
{
id: "raid",
- name: "Raid",
+ name: "Incoming Raid",
description: "When someone raids your channel.",
cached: true,
cacheMetaKey: "username",
@@ -18,10 +18,39 @@ module.exports = {
viewerCount: 5
},
activityFeed: {
- icon: "fad fa-siren-on",
+ icon: "fad fa-inbox-in",
getMessage: (eventData) => {
const showUserIdName = eventData.username.toLowerCase() !== eventData.userDisplayName.toLowerCase();
- return `**${eventData.userDisplayName}${showUserIdName ? ` (${eventData.username})` : ""}** raided with **${eventData.viewerCount}** viewer(s)`;
+ return `**${eventData.userDisplayName}${
+ showUserIdName ? ` (${eventData.username})` : ""
+ }** raided with **${eventData.viewerCount}** viewer(s)`;
+ }
+ }
+ },
+ {
+ id: "raid-sent-off",
+ name: "Outgoing Raid",
+ description: "When your outgoing raid is completed.",
+ cached: false,
+ cacheMetaKey: "fromUsername",
+ manualMetadata: {
+ username: "firebot",
+ userId: "",
+ userDisplayName: "Firebot",
+ raidTargetUsername: "user",
+ raidTargetUserId: "",
+ raidTargetUserDisplayName: "User",
+ viewerCount: 5
+ },
+ activityFeed: {
+ icon: "fad fa-inbox-out",
+ getMessage: (eventData) => {
+ const showUserIdName = eventData.username.toLowerCase() !== eventData.userDisplayName.toLowerCase();
+ return `**${eventData.userDisplayName}${
+ showUserIdName ? ` (${eventData.username})` : ""
+ }** raiding user **${eventData.raidTargetUserDisplayName}** with **${
+ eventData.viewerCount
+ }** viewer(s)`;
}
}
},
@@ -40,7 +69,9 @@ module.exports = {
icon: "fas fa-heart",
getMessage: (eventData) => {
const showUserIdName = eventData.username.toLowerCase() !== eventData.userDisplayName.toLowerCase();
- return `**${eventData.userDisplayName}${showUserIdName ? ` (${eventData.username})` : ""}** followed`;
+ return `**${eventData.userDisplayName}${
+ showUserIdName ? ` (${eventData.username})` : ""
+ }** followed`;
}
}
},
@@ -73,8 +104,13 @@ module.exports = {
icon: "fas fa-star",
getMessage: (eventData) => {
const showUserIdName = eventData.username.toLowerCase() !== eventData.userDisplayName.toLowerCase();
- return `**${eventData.userDisplayName}${showUserIdName ? ` (${eventData.username})` : ""}** ${eventData.isResub ? 'resubscribed' : 'subscribed'} for **${eventData.totalMonths} month(s)** ${eventData.subPlan === 'Prime' ?
- "with **Twitch Prime**" : `at **Tier ${eventData.subPlan.replace("000", "")}**`}`;
+ return `**${eventData.userDisplayName}${showUserIdName ? ` (${eventData.username})` : ""}** ${
+ eventData.isResub ? "resubscribed" : "subscribed"
+ } for **${eventData.totalMonths} month(s)** ${
+ eventData.subPlan === "Prime"
+ ? "with **Twitch Prime**"
+ : `at **Tier ${eventData.subPlan.replace("000", "")}**`
+ }`;
}
}
},
@@ -101,7 +137,9 @@ module.exports = {
icon: "fas fa-star",
getMessage: (eventData) => {
const showUserIdName = eventData.username.toLowerCase() !== eventData.userDisplayName.toLowerCase();
- return `**${eventData.userDisplayName}${showUserIdName ? ` (${eventData.username})` : ""}** upgraded their Prime sub at **Tier ${eventData.subPlan.replace("000", "")}!**`;
+ return `**${eventData.userDisplayName}${
+ showUserIdName ? ` (${eventData.username})` : ""
+ }** upgraded their Prime sub at **Tier ${eventData.subPlan.replace("000", "")}!**`;
}
}
},
@@ -129,7 +167,11 @@ module.exports = {
activityFeed: {
icon: "fad fa-gift",
getMessage: (eventData) => {
- return `**${eventData.isAnonymous ? "An Anonymous Gifter" : eventData.gifterUsername}** gifted a ${eventData.giftDuration > 1 ? ` **${eventData.giftDuration} month** ` : ''} **Tier ${eventData.subPlan.replace("000", "")}** sub to **${eventData.gifteeUsername}** (Subbed for ${eventData.giftSubMonths} month${eventData.giftSubMonths > 1 ? 's' : ''} total)`;
+ return `**${eventData.isAnonymous ? "An Anonymous Gifter" : eventData.gifterUsername}** gifted a ${
+ eventData.giftDuration > 1 ? ` **${eventData.giftDuration} month** ` : ""
+ } **Tier ${eventData.subPlan.replace("000", "")}** sub to **${
+ eventData.gifteeUsername
+ }** (Subbed for ${eventData.giftSubMonths} month${eventData.giftSubMonths > 1 ? "s" : ""} total)`;
}
}
},
@@ -165,7 +207,11 @@ module.exports = {
activityFeed: {
icon: "fad fa-gifts",
getMessage: (eventData) => {
- return `**${eventData.isAnonymous ? "An Anonymous Gifter" : eventData.gifterUsername}** gifted **${eventData.subCount} Tier ${eventData.subPlan.replace("000", "")}** sub${eventData.subCount > 1 ? 's' : ''} to the community`;
+ return `**${eventData.isAnonymous ? "An Anonymous Gifter" : eventData.gifterUsername}** gifted **${
+ eventData.subCount
+ } Tier ${eventData.subPlan.replace("000", "")}** sub${
+ eventData.subCount > 1 ? "s" : ""
+ } to the community`;
}
}
},
@@ -194,7 +240,9 @@ module.exports = {
icon: "fas fa-star",
getMessage: (eventData) => {
const showUserIdName = eventData.username.toLowerCase() !== eventData.userDisplayName.toLowerCase();
- return `**${eventData.userDisplayName}${showUserIdName ? ` (${eventData.username})` : ""}** upgraded their gift sub at **Tier ${eventData.subPlan.replace("000", "")}!**`;
+ return `**${eventData.userDisplayName}${
+ showUserIdName ? ` (${eventData.username})` : ""
+ }** upgraded their gift sub at **Tier ${eventData.subPlan.replace("000", "")}!**`;
}
}
},
@@ -216,7 +264,11 @@ module.exports = {
icon: "fad fa-diamond",
getMessage: (eventData) => {
const showUserIdName = eventData.username.toLowerCase() !== eventData.userDisplayName.toLowerCase();
- return `**${eventData.userDisplayName}${showUserIdName ? ` (${eventData.username})` : ""}** cheered **${eventData.bits}** bits. They have cheered a total of **${eventData.totalBits}** in the channel.`;
+ return `**${eventData.userDisplayName}${
+ showUserIdName ? ` (${eventData.username})` : ""
+ }** cheered **${eventData.bits}** bits. They have cheered a total of **${
+ eventData.totalBits
+ }** in the channel.`;
}
}
},
@@ -269,7 +321,9 @@ module.exports = {
icon: "fad fa-diamond",
getMessage: (eventData) => {
const showUserIdName = eventData.username.toLowerCase() !== eventData.userDisplayName.toLowerCase();
- return `**${eventData.userDisplayName}${showUserIdName ? ` (${eventData.username})` : ""}** unlocked the **${eventData.badgeTier}** bits badge in your channel!`;
+ return `**${eventData.userDisplayName}${
+ showUserIdName ? ` (${eventData.username})` : ""
+ }** unlocked the **${eventData.badgeTier}** bits badge in your channel!`;
}
}
},
@@ -288,7 +342,9 @@ module.exports = {
icon: "fad fa-house-return",
getMessage: (eventData) => {
const showUserIdName = eventData.username.toLowerCase() !== eventData.userDisplayName.toLowerCase();
- return `**${eventData.userDisplayName}${showUserIdName ? ` (${eventData.username})` : ""}** arrived`;
+ return `**${eventData.userDisplayName}${
+ showUserIdName ? ` (${eventData.username})` : ""
+ }** arrived`;
}
}
},
@@ -343,7 +399,9 @@ module.exports = {
icon: "fad fa-sparkles",
getMessage: (eventData) => {
const showUserIdName = eventData.username.toLowerCase() !== eventData.userDisplayName.toLowerCase();
- return `**${eventData.userDisplayName}${showUserIdName ? ` (${eventData.username})` : ""}** has chatted in your channel for the very first time`;
+ return `**${eventData.userDisplayName}${
+ showUserIdName ? ` (${eventData.username})` : ""
+ }** has chatted in your channel for the very first time`;
}
}
},
@@ -377,7 +435,9 @@ module.exports = {
icon: "fad fa-gavel",
getMessage: (eventData) => {
const showUserIdName = eventData.username.toLowerCase() !== eventData.userDisplayName.toLowerCase();
- let message = `**${eventData.userDisplayName}${showUserIdName ? ` (${eventData.username})` : ""}** was banned by **${eventData.moderator}**.`;
+ let message = `**${eventData.userDisplayName}${
+ showUserIdName ? ` (${eventData.username})` : ""
+ }** was banned by **${eventData.moderator}**.`;
if (eventData.modReason) {
message = `${message} Reason: **${eventData.modReason}**`;
@@ -402,7 +462,9 @@ module.exports = {
icon: "fad fa-gavel",
getMessage: (eventData) => {
const showUserIdName = eventData.username.toLowerCase() !== eventData.userDisplayName.toLowerCase();
- return `**${eventData.userDisplayName}${showUserIdName ? ` (${eventData.username})` : ""}** was unbanned by **${eventData.moderator}**.`;
+ return `**${eventData.userDisplayName}${
+ showUserIdName ? ` (${eventData.username})` : ""
+ }** was unbanned by **${eventData.moderator}**.`;
}
}
},
@@ -424,7 +486,9 @@ module.exports = {
icon: "fad fa-stopwatch",
getMessage: (eventData) => {
const showUserIdName = eventData.username.toLowerCase() !== eventData.userDisplayName.toLowerCase();
- let message = `**${eventData.userDisplayName}${showUserIdName ? ` (${eventData.username})` : ""}** was timed out for **${eventData.timeoutDuration} sec(s)** by ${eventData.moderator}.`;
+ let message = `**${eventData.userDisplayName}${
+ showUserIdName ? ` (${eventData.username})` : ""
+ }** was timed out for **${eventData.timeoutDuration} sec(s)** by ${eventData.moderator}.`;
if (eventData.modReason) {
message = `${message} Reason: **${eventData.modReason}**`;
@@ -454,7 +518,11 @@ module.exports = {
icon: "fad fa-circle",
getMessage: (eventData) => {
const showUserIdName = eventData.username.toLowerCase() !== eventData.userDisplayName.toLowerCase();
- return `**${eventData.userDisplayName}${showUserIdName ? ` (${eventData.username})` : ""}** redeemed **${eventData.rewardName}**${eventData.messageText && !!eventData.messageText.length ? `: *${eventData.messageText}*` : ''}`;
+ return `**${eventData.userDisplayName}${
+ showUserIdName ? ` (${eventData.username})` : ""
+ }** redeemed **${eventData.rewardName}**${
+ eventData.messageText && !!eventData.messageText.length ? `: *${eventData.messageText}*` : ""
+ }`;
}
}
},
@@ -479,7 +547,11 @@ module.exports = {
icon: "fad fa-circle",
getMessage: (eventData) => {
const showUserIdName = eventData.username.toLowerCase() !== eventData.userDisplayName.toLowerCase();
- return `**${eventData.userDisplayName}${showUserIdName ? ` (${eventData.username})` : ""}**'s redemption of **${eventData.rewardName}** was approved. ${eventData.messageText && !!eventData.messageText.length ? `*${eventData.messageText}*` : ''}`;
+ return `**${eventData.userDisplayName}${
+ showUserIdName ? ` (${eventData.username})` : ""
+ }**'s redemption of **${eventData.rewardName}** was approved. ${
+ eventData.messageText && !!eventData.messageText.length ? `*${eventData.messageText}*` : ""
+ }`;
}
}
},
@@ -504,7 +576,11 @@ module.exports = {
icon: "fad fa-circle",
getMessage: (eventData) => {
const showUserIdName = eventData.username.toLowerCase() !== eventData.userDisplayName.toLowerCase();
- return `**${eventData.userDisplayName}${showUserIdName ? ` (${eventData.username})` : ""}**'s redemption of **${eventData.rewardName}** was rejected. ${eventData.messageText && !!eventData.messageText.length ? `*${eventData.messageText}*` : ''}`;
+ return `**${eventData.userDisplayName}${
+ showUserIdName ? ` (${eventData.username})` : ""
+ }**'s redemption of **${eventData.rewardName}** was rejected. ${
+ eventData.messageText && !!eventData.messageText.length ? `*${eventData.messageText}*` : ""
+ }`;
}
}
},
@@ -531,7 +607,9 @@ module.exports = {
icon: "fad fa-comment-alt",
getMessage: (eventData) => {
const showUserIdName = eventData.username.toLowerCase() !== eventData.userDisplayName.toLowerCase();
- return `**${eventData.userDisplayName}${showUserIdName ? ` (${eventData.username})` : ""}** sent your **${eventData.sentTo}** account the following whisper: ${eventData.message}`;
+ return `**${eventData.userDisplayName}${
+ showUserIdName ? ` (${eventData.username})` : ""
+ }** sent your **${eventData.sentTo}** account the following whisper: ${eventData.message}`;
}
}
},
@@ -545,19 +623,19 @@ module.exports = {
chatMode: {
type: "enum",
options: {
- "emoteonly": "Emote Only",
- "subscribers": "Subscribers Only",
- "followers": "Followers",
- "slow": "Slow",
- "r9kbeta": "Unique Chat"
+ emoteonly: "Emote Only",
+ subscribers: "Subscribers Only",
+ followers: "Followers",
+ slow: "Slow",
+ r9kbeta: "Unique Chat"
},
value: "emoteonly"
},
chatModeState: {
type: "enum",
options: {
- "enabled": "Enabled",
- "disabled": "Disabled"
+ enabled: "Enabled",
+ disabled: "Disabled"
},
value: "enabled"
},
@@ -681,9 +759,13 @@ module.exports = {
getMessage: (eventData) => {
let message;
if (eventData.description) {
- message = `Channel ${eventData.type} goal **${eventData.description}** has ended. Goal **${eventData.isAchieved ? "was" : "was not"}** achieved. (**${eventData.currentAmount}**/**${eventData.targetAmount}**).`;
+ message = `Channel ${eventData.type} goal **${eventData.description}** has ended. Goal **${
+ eventData.isAchieved ? "was" : "was not"
+ }** achieved. (**${eventData.currentAmount}**/**${eventData.targetAmount}**).`;
} else {
- message = `Channel ${eventData.type} goal has ended. Goal **${eventData.isAchieved ? "was" : "was not"}** achieved. (**${eventData.currentAmount}**/**${eventData.targetAmount}**).`;
+ message = `Channel ${eventData.type} goal has ended. Goal **${
+ eventData.isAchieved ? "was" : "was not"
+ }** achieved. (**${eventData.currentAmount}**/**${eventData.targetAmount}**).`;
}
return message;
}
@@ -787,7 +869,9 @@ module.exports = {
activityFeed: {
icon: "fad fa-train",
getMessage: (eventData) => {
- return `Level **${eventData.level}** hype train currently at **${Math.floor((eventData.progress / eventData.goal) * 100)}%**.`;
+ return `Level **${eventData.level}** hype train currently at **${Math.floor(
+ (eventData.progress / eventData.goal) * 100
+ )}%**.`;
}
}
},
@@ -814,7 +898,7 @@ module.exports = {
description: "When your stream starts.",
cached: false,
queued: false,
- manualMetadata: { },
+ manualMetadata: {},
activityFeed: {
icon: "fad fa-play-circle",
getMessage: () => {
@@ -828,7 +912,7 @@ module.exports = {
description: "When your stream ends.",
cached: false,
queued: false,
- manualMetadata: { },
+ manualMetadata: {},
activityFeed: {
icon: "fad fa-stop-circle",
getMessage: () => {
@@ -923,7 +1007,9 @@ module.exports = {
activityFeed: {
icon: "fad fa-ribbon",
getMessage: (eventData) => {
- return `Charity campaign has ended. Goal reached: **${eventData.goalReached ? "Yes" : "No"}**. Total raised: **${eventData.currentTotalAmount} ${eventData.currentTotalCurrency}**.`;
+ return `Charity campaign has ended. Goal reached: **${
+ eventData.goalReached ? "Yes" : "No"
+ }**. Total raised: **${eventData.currentTotalAmount} ${eventData.currentTotalCurrency}**.`;
}
}
},
@@ -944,7 +1030,9 @@ module.exports = {
icon: "fad fa-bullhorn",
getMessage: (eventData) => {
const showUserIdName = eventData.username.toLowerCase() !== eventData.userDisplayName.toLowerCase();
- return `**${eventData.moderator}** sent a shoutout to **${eventData.userDisplayName}${showUserIdName ? ` (${eventData.username})` : ""}**`;
+ return `**${eventData.moderator}** sent a shoutout to **${eventData.userDisplayName}${
+ showUserIdName ? ` (${eventData.username})` : ""
+ }**`;
}
}
},
@@ -964,7 +1052,9 @@ module.exports = {
icon: "fad fa-bullhorn",
getMessage: (eventData) => {
const showUserIdName = eventData.username.toLowerCase() !== eventData.userDisplayName.toLowerCase();
- return `**${eventData.userDisplayName}${showUserIdName ? ` (${eventData.username})` : ""}** shouted out your channel to ${eventData.viewerCount} viewers`;
+ return `**${eventData.userDisplayName}${
+ showUserIdName ? ` (${eventData.username})` : ""
+ }** shouted out your channel to ${eventData.viewerCount} viewers`;
}
}
},
@@ -1013,13 +1103,16 @@ module.exports = {
const mins = Math.floor(eventData.adBreakDuration / 60);
const remainingSecs = eventData.adBreakDuration % 60;
- const friendlyDuration = mins > 0
- ? `${mins}m${remainingSecs > 0 ? ` ${remainingSecs}s` : ""}`
- : `${eventData.adBreakDuration}s`;
+ const friendlyDuration =
+ mins > 0
+ ? `${mins}m${remainingSecs > 0 ? ` ${remainingSecs}s` : ""}`
+ : `${eventData.adBreakDuration}s`;
const minutesUntilNextAdBreak = Math.round(eventData.secondsUntilNextAdBreak / 60);
- return `**${friendlyDuration}** scheduled ad break starting in about **${minutesUntilNextAdBreak}** minute${minutesUntilNextAdBreak !== 1 ? "s" : ""}`;
+ return `**${friendlyDuration}** scheduled ad break starting in about **${minutesUntilNextAdBreak}** minute${
+ minutesUntilNextAdBreak !== 1 ? "s" : ""
+ }`;
}
}
},
@@ -1038,11 +1131,14 @@ module.exports = {
const mins = Math.floor(eventData.adBreakDuration / 60);
const remainingSecs = eventData.adBreakDuration % 60;
- const friendlyDuration = mins > 0
- ? `${mins}m${remainingSecs > 0 ? ` ${remainingSecs}s` : ""}`
- : `${eventData.adBreakDuration}s`;
+ const friendlyDuration =
+ mins > 0
+ ? `${mins}m${remainingSecs > 0 ? ` ${remainingSecs}s` : ""}`
+ : `${eventData.adBreakDuration}s`;
- return `**${friendlyDuration}** **${eventData.isAdBreakScheduled ? "scheduled" : "manual"}** ad break started`;
+ return `**${friendlyDuration}** **${
+ eventData.isAdBreakScheduled ? "scheduled" : "manual"
+ }** ad break started`;
}
}
},
@@ -1061,13 +1157,16 @@ module.exports = {
const mins = Math.floor(eventData.adBreakDuration / 60);
const remainingSecs = eventData.adBreakDuration % 60;
- const friendlyDuration = mins > 0
- ? `${mins}m${remainingSecs > 0 ? ` ${remainingSecs}s` : ""}`
- : `${eventData.adBreakDuration}s`;
+ const friendlyDuration =
+ mins > 0
+ ? `${mins}m${remainingSecs > 0 ? ` ${remainingSecs}s` : ""}`
+ : `${eventData.adBreakDuration}s`;
- return `**${friendlyDuration}** **${eventData.isAdBreakScheduled ? "scheduled" : "manual"}** ad break ended`;
+ return `**${friendlyDuration}** **${
+ eventData.isAdBreakScheduled ? "scheduled" : "manual"
+ }** ad break ended`;
}
}
}
]
-};
\ No newline at end of file
+};
diff --git a/src/backend/events/filters/builtin-filter-loader.js b/src/backend/events/filters/builtin-filter-loader.js
index aa13ef3be..5cfea24cd 100644
--- a/src/backend/events/filters/builtin-filter-loader.js
+++ b/src/backend/events/filters/builtin-filter-loader.js
@@ -13,6 +13,7 @@ exports.loadFilters = () => {
'custom-variable-name',
'donation-amount',
'donation-from',
+ 'effect-queue',
'gift-count',
'gift-duration',
'is-anonymous',
diff --git a/src/backend/events/filters/builtin/effect-queue.js b/src/backend/events/filters/builtin/effect-queue.js
new file mode 100644
index 000000000..b17d9c77a
--- /dev/null
+++ b/src/backend/events/filters/builtin/effect-queue.js
@@ -0,0 +1,46 @@
+"use strict";
+
+module.exports = {
+ id: "firebot:effect-queue",
+ name: "Effect Queue",
+ description: "Filter to a Effect Queue",
+ events: [
+ { eventSourceId: "firebot", eventId: "effect-queue-added" },
+ { eventSourceId: "firebot", eventId: "effect-queue-cleared" },
+ { eventSourceId: "firebot", eventId: "effect-queue-status" }
+ ],
+ comparisonTypes: ["is", "is not"],
+ valueType: "preset",
+ presetValues: (effectQueuesService) => {
+ return effectQueuesService.getEffectQueues().map((c) => ({ value: c.id, display: c.name }));
+ },
+ valueIsStillValid: (filterSettings, effectQueuesService) => {
+ return new Promise((resolve) => {
+ resolve(effectQueuesService.getEffectQueues().some((c) => c.id === filterSettings.value));
+ });
+ },
+ getSelectedValueDisplay: (filterSettings, effectQueuesService) => {
+ return new Promise((resolve) => {
+ resolve(
+ effectQueuesService.getEffectQueues().find((c) => c.id === filterSettings.value)?.name ??
+ "Unknown Effect Queue"
+ );
+ });
+ },
+ predicate: (filterSettings, eventData) => {
+ const { comparisonType, value } = filterSettings;
+ const { eventMeta } = eventData;
+
+ const actual = eventMeta.effectQueueId;
+ const expected = value;
+
+ switch (comparisonType) {
+ case "is":
+ return actual === expected;
+ case "is not":
+ return actual !== expected;
+ default:
+ return false;
+ }
+ }
+};
diff --git a/src/backend/events/filters/builtin/raid-viewer-count.js b/src/backend/events/filters/builtin/raid-viewer-count.js
index d4fc1d3bb..54f76457f 100644
--- a/src/backend/events/filters/builtin/raid-viewer-count.js
+++ b/src/backend/events/filters/builtin/raid-viewer-count.js
@@ -5,9 +5,10 @@ const { ComparisonType } = require("../../../../shared/filter-constants");
module.exports = {
id: "firebot:raid-viewer-count",
name: "Raid Viewer Count",
- description: "Filter by how many viewers have been brought over by the raid.",
+ description: "Filter by how many viewers have been brought or are being sent over by the raid.",
events: [
- { eventSourceId: "twitch", eventId: "raid" }
+ { eventSourceId: "twitch", eventId: "raid" },
+ { eventSourceId: "twitch", eventId: "raid-sent-off" }
],
comparisonTypes: [
ComparisonType.IS,
@@ -19,7 +20,6 @@ module.exports = {
],
valueType: "number",
predicate: (filterSettings, eventData) => {
-
const { comparisonType, value } = filterSettings;
const { eventMeta } = eventData;
@@ -48,4 +48,4 @@ module.exports = {
return false;
}
}
-};
\ No newline at end of file
+};
diff --git a/src/backend/events/twitch-events/raid.ts b/src/backend/events/twitch-events/raid.ts
index 10d582972..89e598213 100644
--- a/src/backend/events/twitch-events/raid.ts
+++ b/src/backend/events/twitch-events/raid.ts
@@ -1,6 +1,6 @@
import eventManager from "../../events/EventManager";
-export function triggerRaid(
+export function triggerIncomingRaid(
username: string,
userId: string,
userDisplayName: string,
@@ -12,4 +12,23 @@ export function triggerRaid(
userDisplayName,
viewerCount
});
+}
+export function triggerRaidSentOff(
+ username: string,
+ userId: string,
+ userDisplayName: string,
+ raidTargetUsername: string,
+ raidTargetUserId: string,
+ raidTargetUserDisplayName: string,
+ viewerCount = 0
+): void {
+ eventManager.triggerEvent("twitch", "raid-sent-off", {
+ username,
+ userId,
+ userDisplayName,
+ raidTargetUsername,
+ raidTargetUserId,
+ raidTargetUserDisplayName,
+ viewerCount
+ });
}
\ No newline at end of file
diff --git a/src/backend/integrations/builtin/obs/effects/transform-obs-source-scale.ts b/src/backend/integrations/builtin/obs/effects/transform-obs-source.ts
similarity index 53%
rename from src/backend/integrations/builtin/obs/effects/transform-obs-source-scale.ts
rename to src/backend/integrations/builtin/obs/effects/transform-obs-source.ts
index b1a02ab1f..dc74ec7c2 100644
--- a/src/backend/integrations/builtin/obs/effects/transform-obs-source-scale.ts
+++ b/src/backend/integrations/builtin/obs/effects/transform-obs-source.ts
@@ -1,7 +1,7 @@
import { EffectType } from "../../../../../types/effects";
import { OBSSceneItem, OBSSourceTransformKeys, transformSceneItem } from "../obs-remote";
-export const TransformSourceScaleEffectType: EffectType<{
+export const TransformSourceEffectType: EffectType<{
sceneName?: string;
sceneItem?: OBSSceneItem;
duration: string | number;
@@ -10,6 +10,7 @@ export const TransformSourceScaleEffectType: EffectType<{
isTransformingPosition: boolean;
isTransformingScale: boolean;
isTransformingRotation: boolean;
+ alignment: number;
startTransform: Record;
endTransform: Record;
}> = {
@@ -52,110 +53,129 @@ export const TransformSourceScaleEffectType: EffectType<{
No transformable sources found. {{ isObsConfigured ? "Is OBS running?" : "Have you configured the OBS integration?" }}
-