`;
+ return buf;
+ }
+ randomize() {
+ const rearranged: string[] = [];
+ const keys = Object.keys(channelData);
+ while (keys.length > 1) {
+ const item = keys[Math.floor(Math.random() * keys.length)];
+ if (rearranged.includes(item)) continue;
+ const index = keys.indexOf(item);
+ if (index > -1) {
+ keys.splice(index, 1);
+ }
+ rearranged.push(item);
+ }
+ if (rearranged.length !== keys.length) {
+ for (const key of keys) {
+ if (!rearranged.includes(key)) rearranged.push(key);
+ }
+ }
+ return rearranged;
+ }
+};
+
+export const commands: ChatCommands = {
+ randchannel(target, room, user) {
+ if (room.roomid !== 'youtube') return this.errorReply(`This command can only be used in the YouTube room.`);
+ this.runBroadcast();
+ if (this.broadcasting) {
+ if (!this.can('broadcast', null, room)) return false;
+ return YouTube.randChannel().then(res => {
+ this.addBox(res);
+ room.update();
+ });
+ } else {
+ return YouTube.randChannel().then(res => this.sendReplyBox(res));
+ }
+ },
+ randchannelhelp: [`/randchannel - View data of a random channel from the YouTube database.`],
+
+ yt: 'youtube',
+ youtube: {
+ async addchannel(target, room, user) {
+ if (room.roomid !== 'youtube') return this.errorReply(`This command can only be used in the YouTube room.`);
+ let [id, name] = target.split(',');
+ if (id.includes('youtu')) id = id.split('channel/')[1];
+ if (!id) return this.errorReply('Specify a channel ID.');
+ if (!(await YouTube.getChannelData(id, name))) {
+ return this.errorReply(`Error in retrieving channel data.`);
+ }
+ this.modlog('ADDCHANNEL', null, `${id} ${name ? `username: ${name}` : ''}`);
+ this.privateModAction(`(${user.name} added channel with ID ${id} to the random channel pool.)`);
+ return this.sendReply(`Added channel with id ${id} ${name ? `and username (${name}) ` : ''} to the random channel pool.`);
+ },
+ addchannelhelp: [`/addchannel - Add channel data to the Youtube database. Requires: % @ # ~`],
+
+ removechannel(target, room, user) {
+ if (room.roomid !== 'youtube') return this.errorReply(`This command can only be used in the YouTube room.`);
+ if (!this.can('ban', null, room)) return false;
+ const id = YouTube.channelSearch(target);
+ if (!id) return this.errorReply(`Channel with ID or name ${target} not found.`);
+ delete channelData[id];
+ this.privateModAction(`(${user.name} deleted channel with ID or name ${target}.)`);
+ return this.modlog(`REMOVECHANNEL`, null, id);
+ },
+ removechannelhelp: [`/youtube removechannel - Delete channel data from the YouTube database. Requires: % @ # ~`],
+
+ channel(target, room, user) {
+ if (room.roomid !== 'youtube') return this.errorReply(`This command can only be used in the YouTube room.`);
+ const channel = YouTube.channelSearch(target);
+ if (!channel) return this.errorReply(`No channels with ID or name ${target} found.`);
+ this.runBroadcast();
+ if (this.broadcasting) {
+ return YouTube.generateChannelDisplay(channel).then(res => {
+ this.addBox(res);
+ room.update();
+ });
+ } else {
+ return YouTube.generateChannelDisplay(channel).then(res => this.sendReplyBox(res));
+ }
+ },
+ channelhelp: [
+ '/youtube channel - View the data of a specified channel. Can be either channel ID or channel name.',
+ ],
+ async video(target, room, user) {
+ if (room.roomid !== 'youtube') return this.errorReply(`This command can only be used in the YouTube room.`);
+ if (!target) return this.errorReply(`Provide a valid youtube link.`);
+ const html = await YouTube.generateVideoDisplay(target);
+ if (!html) return this.errorReply(`No such video found.`);
+ this.runBroadcast();
+ if (this.broadcasting) {
+ this.addBox(html);
+ return room.update();
+ } else {
+ return this.sendReplyBox(html);
+ }
+ },
+ videohelp: [`/youtube video - View data of a specified video. Can be either channel ID or channel name`],
+
+ channels(target, room, user) {
+ let all;
+ if (toID(target) === 'all') all = true;
+ return this.parse(`/j view-channels${all ? '-all' : ''}`);
+ },
+ help(target, room, user) {
+ const buf = (
+ `YouTube plugin commands: ` +
+ `/randchannel - View data of a random channel from the YouTube database. ` +
+ `/youtube addchannel [channel[- Add channel data to the Youtube database. Requires: % @ # ~ ` +
+ `/youtube removechannel [channel]- Delete channel data from the YouTube database. Requires: % @ # ~ ` +
+ `/youtube channel [channel] - View the data of a specified channel. Can be either channel ID or channel name. ` +
+ `/youtube video [video] - View data of a specified video. Can be either channel ID or channel name. ` +
+ `/youtube update [channel], [name] - sets a channel's PS username to [name]. Requires: % @ # ~ ` +
+ `/youtube repeat [time] - Sets an interval for [time] minutes, showing a random channel each time. Requires: # & ~ `
+ );
+ this.runBroadcast();
+ if (this.broadcasting) {
+ return this.add(`|html|
${buf}
`);
+ }
+ return this.sendReplyBox(buf);
+ },
+ update(target, room, user) {
+ if (room.roomid !== 'youtube') return this.errorReply(`This command can only be used in the YouTube room.`);
+ if (!this.can('ban', null, room)) return false;
+ const [channel, name] = target.split(',');
+ const id = YouTube.channelSearch(channel);
+ if (!id) return this.errorReply(`Channel ${channel} is not in the database.`);
+ channelData[id].username = name;
+ this.modlog(`UPDATECHANNEL`, null, name);
+ this.privateModAction(`(${user.name} updated channel ${id}'s username to ${name}.)`);
+ return FS(STORAGE_PATH).writeUpdate(() => JSON.stringify(channelData));
+ },
+ repeat(target, room, user) {
+ if (room.roomid !== 'youtube') return this.errorReply(`This command can only be used in the YouTube room.`);
+ if (!this.can('declare', null, room)) return false;
+ if (!target || isNaN(parseInt(target))) return this.errorReply(`Specify a number (in minutes) for the interval.`);
+ let interval = Number(target);
+ if (interval < 10) return this.errorReply(`${interval} is too low - set it above 10 minutes.`);
+ interval = interval * 60 * 1000;
+ if (YouTube.interval) clearInterval(YouTube.interval);
+ YouTube.interval = setInterval(
+ () => void YouTube.randChannel().then(data => {
+ this.addBox(data);
+ room.update();
+ }),
+ interval
+ );
+ this.privateModAction(`(${user.name} set a randchannel interval to ${target} minutes)`);
+ return this.modlog(`CHANNELINTERVAL`, null, `${target} minutes`);
+ },
+ },
+ requestapproval(target, room, user) {
+ if (!this.canTalk()) return false;
+ if (this.can('mute', null, room)) return this.errorReply(`Use !link instead.`);
+ if (room.pendingApprovals.has(user.id)) return this.errorReply('You have a request pending already.');
+ if (!toID(target)) return this.parse(`/help requestapproval`);
+ if (!/^https?:\/\//.test(target)) target = `http://${target}`;
+ room.pendingApprovals.set(user.id, target);
+ this.sendReply(`You have requested for the link ${target} to be displayed.`);
+ room.sendMods(
+ `|uhtml|request-${user.id}|
${user.name} has requested approval to show media. ` +
+ ` ` +
+ `
`
+ );
+ return room.update();
+ },
+ requestapprovalhelp: [`/requestapproval [link], [comment] - Requests permission to show media in the room.`],
+
+ approvelink(target, room, user) {
+ if (!this.can('mute', null, room)) return false;
+ target = toID(target);
+ if (!target) return this.parse(`/help approvelink`);
+ const id = room.pendingApprovals.get(target);
+ if (!id) return this.errorReply(`${target} has no pending request.`);
+ this.privateModAction(`(${user.name} approved ${target}'s media display request.)`);
+ this.modlog(`APPROVELINK`, null, `${target} (${id})`);
+ room.pendingApprovals.delete(target);
+ if (id.includes('youtu')) {
+ return YouTube.generateVideoDisplay(id).then(res => {
+ room.add(`|uhtmlchange|request-${target}|`).update();
+ res += `
(Suggested by ${target})
`;
+ this.addBox(res as string);
+ room.update();
+ });
+ } else {
+ void Chat.fitImage(id).then(([width, height]) => {
+ this.addBox(Chat.html``);
+ room.add(`|uhtmlchange|request-${target}|`);
+ room.update();
+ });
+ }
+ },
+ approvelinkhelp: [`/approvelink [user] - Approves the media display request of [user]. Requires: % @ # & ~`],
+
+ denylink(target, room, user) {
+ if (!this.can('mute', null, room)) return false;
+ target = toID(target);
+ if (!target) return this.parse(`/help denylink`);
+ const id = room.pendingApprovals.get(target);
+ if (!id) return this.errorReply(`${target} has no pending request.`);
+ room.pendingApprovals.delete(target);
+ room.add(`|uhtmlchange|request-${target}|`).update();
+ this.privateModAction(`(${user.name} denied ${target}'s media display request.)`);
+ this.modlog(`DENYLINK`, null, `${target} (${id})`);
+ },
+ denylinkhelp: [`/denylink [user] - Denies the media display request of [user]. Requires: % @ # & ~`],
+
+ link(target, room, user) {
+ if (!this.can('mute', null, room) && !(user.id in room.chatRoomData!.whitelist)) return false;
+ if (!toID(target).trim()) return this.parse(`/help link`);
+ const [link, comment] = target.split(',');
+ this.runBroadcast();
+ if (target.includes('youtu')) {
+ return YouTube.generateVideoDisplay(link).then(res => {
+ let buf = res;
+ buf += `
(Suggested by ${user.name})
`;
+ if (comment) buf += ` (${comment})`;
+ this.addBox(buf as string);
+ room.update();
+ });
+ } else {
+ void Chat.fitImage(link).then(([width, height]) => {
+ let buf = Chat.html``;
+ if (comment) buf += ` (${comment})`;
+ if (!this.broadcasting) return this.sendReplyBox(buf);
+ this.addBox(buf);
+ room.update();
+ });
+ }
+ },
+ linkhelp: [`/link [url] - shows an image or video url in chat. Requires: whitelist % @ # & ~`],
+
+ whitelist(target, room, user) {
+ if (!this.can('ban', null, room)) return false;
+ target = toID(target);
+ if (!target) return this.parse(`/help whitelist`);
+ if (!Users.get(target)) return this.errorReply(`User not found.`);
+ if (target in room.auth! && room.auth![target] !== '+' || Users.get(target)!.isStaff) {
+ return this.errorReply(`You don't need to whitelist staff - they can just use !link.`);
+ }
+ if (!room.whitelistUser(target)) return this.errorReply(`${target} is already whitelisted.`);
+ if (Users.get(target)) Users.get(target)?.popup(`You have been whitelisted for linking in ${room}.`);
+ this.privateModAction(`(${user.name} whitelisted ${target} for links.)`);
+ this.modlog(`WHITELIST`, target);
+ },
+ whitelisthelp: [`/whitelist [user] - Whitelists [user] to post media in the room. Requires: % @ & # ~`],
+
+ unwhitelist(target, room, user) {
+ if (!this.can('mute', null, room)) return false;
+ target = toID(target);
+ if (Users.get(target)) Users.get(target)?.popup(`You have been removed from the link whitelist in ${room}.`);
+ if (!target) return this.parse(`/help unwhitelist`);
+ if (!room.unwhitelistUser(target)) return this.errorReply(`${target} is not whitelisted.`);
+ this.sendReply(`Unwhitelisted ${target} for linking.`);
+ this.modlog(`UNWHITELIST`, target);
+ this.privateModAction(`(${user} removed ${target} from the link whitelist.)`);
+ return Rooms.global.writeChatRoomData();
+ },
+};
+
+export const pages: PageTable = {
+ async channels(args, user) {
+ const all = toID(args[0]) === 'all';
+ this.title = `[Channels] ${all ? 'All' : ''}`;
+ let buffer = `
Channels in the Youtube database:`;
+ buffer += ` `;
+ if (all) buffer += `(All)`;
+ buffer += `
`;
+ const isStaff = user.can('mute', null, Rooms.get('youtube'));
+ for (const id of YouTube.randomize()) {
+ const name = YouTube.get(id).name;
+ const psid = YouTube.get(id).username;
+ if (!all && !psid) continue;
+ buffer += `${name}`;
+ if (isStaff) buffer += ` (Channel ID: ${id})`;
+ if (psid) buffer += ` (PS name: ${psid})`;
+ buffer += ``;
+ buffer += await YouTube.generateChannelDisplay(id);
+ if (!isStaff) buffer += `(Channel ID: ${id})`;
+ buffer += ``;
+ }
+ buffer += `
`;
+ return buffer;
+ },
+};
From e6e5220851de802d90c03ea1af5b0673fc12c766 Mon Sep 17 00:00:00 2001
From: Mia <49593536+mia-pi-git@users.noreply.github.com>
Date: Sun, 24 May 2020 11:23:58 -0500
Subject: [PATCH 02/11] make necessary rooms changes
---
server/rooms.ts | 19 +++++++++++++++++++
1 file changed, 19 insertions(+)
diff --git a/server/rooms.ts b/server/rooms.ts
index 406f1436a0f7..d4d61b76aa53 100644
--- a/server/rooms.ts
+++ b/server/rooms.ts
@@ -1080,6 +1080,8 @@ export class BasicChatRoom extends BasicRoom {
game: RoomGame | null;
battle: RoomBattle | null;
tour: Tournament | null;
+ pendingApprovals: Map;
+ whitelist: AnyObject;
constructor(roomid: RoomID, title?: string, options: AnyObject = {}) {
super(roomid, title);
@@ -1111,6 +1113,7 @@ export class BasicChatRoom extends BasicRoom {
this.chatRoomData = (options.isPersonal ? null : options);
this.minorActivity = null;
+ this.whitelist = {};
Object.assign(this, options);
if (this.auth) Object.setPrototypeOf(this.auth, null);
this.parent = null;
@@ -1147,6 +1150,8 @@ export class BasicChatRoom extends BasicRoom {
this.tour = null;
this.game = null;
this.battle = null;
+ this.pendingApprovals = new Map();
+ this.whitelist = this.chatRoomData!.whitelist || {};
}
/**
@@ -1428,6 +1433,20 @@ export class BasicChatRoom extends BasicRoom {
return this.log.rename(newID);
}
+ whitelistUser(userid: string) {
+ if (userid in this.whitelist) return false;
+ this.whitelist[userid] = true;
+ this.chatRoomData!.whitelist = this.whitelist;
+ Rooms.global.writeChatRoomData();
+ return true;
+ }
+ unwhitelistUser(userid: string) {
+ if (!(userid in this.whitelist)) return false;
+ delete this.whitelist[userid];
+ this.chatRoomData!.whitelist = this.whitelist;
+ Rooms.global.writeChatRoomData();
+ return true;
+ }
destroy() {
// deallocate ourself
From 26180556485fb8181493a8b01230e43822063ca5 Mon Sep 17 00:00:00 2001
From: Mia <49593536+mia-pi-git@users.noreply.github.com>
Date: Sun, 24 May 2020 11:25:23 -0500
Subject: [PATCH 03/11] doesnt need to be an anyobject
---
server/rooms.ts | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/server/rooms.ts b/server/rooms.ts
index d4d61b76aa53..6d227555d1a4 100644
--- a/server/rooms.ts
+++ b/server/rooms.ts
@@ -1081,7 +1081,7 @@ export class BasicChatRoom extends BasicRoom {
battle: RoomBattle | null;
tour: Tournament | null;
pendingApprovals: Map;
- whitelist: AnyObject;
+ whitelist: {[k: string]: boolean};
constructor(roomid: RoomID, title?: string, options: AnyObject = {}) {
super(roomid, title);
From 7c3d2d737006c84fa721bef99e4729c517bf7889 Mon Sep 17 00:00:00 2001
From: Mia <49593536+mia-pi-git@users.noreply.github.com>
Date: Sun, 24 May 2020 13:53:32 -0500
Subject: [PATCH 04/11] update help / perms
---
server/chat-plugins/youtube.ts | 31 +++++++++++++++----------------
1 file changed, 15 insertions(+), 16 deletions(-)
diff --git a/server/chat-plugins/youtube.ts b/server/chat-plugins/youtube.ts
index 4c8e46d9a217..35f7a8e65874 100644
--- a/server/chat-plugins/youtube.ts
+++ b/server/chat-plugins/youtube.ts
@@ -240,22 +240,9 @@ export const commands: ChatCommands = {
return this.parse(`/j view-channels${all ? '-all' : ''}`);
},
help(target, room, user) {
- const buf = (
- `YouTube plugin commands: ` +
- `/randchannel - View data of a random channel from the YouTube database. ` +
- `/youtube addchannel [channel[- Add channel data to the Youtube database. Requires: % @ # ~ ` +
- `/youtube removechannel [channel]- Delete channel data from the YouTube database. Requires: % @ # ~ ` +
- `/youtube channel [channel] - View the data of a specified channel. Can be either channel ID or channel name. ` +
- `/youtube video [video] - View data of a specified video. Can be either channel ID or channel name. ` +
- `/youtube update [channel], [name] - sets a channel's PS username to [name]. Requires: % @ # ~ ` +
- `/youtube repeat [time] - Sets an interval for [time] minutes, showing a random channel each time. Requires: # & ~ `
- );
- this.runBroadcast();
- if (this.broadcasting) {
- return this.add(`|html|
${buf}
`);
- }
- return this.sendReplyBox(buf);
+ return this.parse('/help youtube')
},
+
update(target, room, user) {
if (room.roomid !== 'youtube') return this.errorReply(`This command can only be used in the YouTube room.`);
if (!this.can('ban', null, room)) return false;
@@ -286,6 +273,18 @@ export const commands: ChatCommands = {
return this.modlog(`CHANNELINTERVAL`, null, `${target} minutes`);
},
},
+
+ youtubehelp: [
+ `YouTube commands:`,
+ `/randchannel - View data of a random channel from the YouTube database.`,
+ `/youtube addchannel [channel[- Add channel data to the Youtube database. Requires: % @ # ~`,
+ `/youtube removechannel [channel]- Delete channel data from the YouTube database. Requires: % @ # ~`,
+ `/youtube channel [channel] - View the data of a specified channel. Can be either channel ID or channel name.`,
+ `/youtube video [video] - View data of a specified video. Can be either channel ID or channel name.`,
+ `/youtube update [channel], [name] - sets a channel's PS username to [name]. Requires: % @ # ~`,
+ `/youtube repeat [time] - Sets an interval for [time] minutes, showing a random channel each time. Requires: # & ~`,
+ ],
+
requestapproval(target, room, user) {
if (!this.canTalk()) return false;
if (this.can('mute', null, room)) return this.errorReply(`Use !link instead.`);
@@ -383,7 +382,7 @@ export const commands: ChatCommands = {
whitelisthelp: [`/whitelist [user] - Whitelists [user] to post media in the room. Requires: % @ & # ~`],
unwhitelist(target, room, user) {
- if (!this.can('mute', null, room)) return false;
+ if (!this.can('ban', null, room)) return false;
target = toID(target);
if (Users.get(target)) Users.get(target)?.popup(`You have been removed from the link whitelist in ${room}.`);
if (!target) return this.parse(`/help unwhitelist`);
From 6a8308a7b84c7bb469e2f17bcd525a4c0b318aac Mon Sep 17 00:00:00 2001
From: Mia <49593536+mia-pi-git@users.noreply.github.com>
Date: Sun, 24 May 2020 13:57:09 -0500
Subject: [PATCH 05/11] semicolon
---
server/chat-plugins/youtube.ts | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/server/chat-plugins/youtube.ts b/server/chat-plugins/youtube.ts
index 35f7a8e65874..89e2ebd0a29c 100644
--- a/server/chat-plugins/youtube.ts
+++ b/server/chat-plugins/youtube.ts
@@ -240,7 +240,7 @@ export const commands: ChatCommands = {
return this.parse(`/j view-channels${all ? '-all' : ''}`);
},
help(target, room, user) {
- return this.parse('/help youtube')
+ return this.parse('/help youtube');
},
update(target, room, user) {
From bfa70001fd4832696619f6301c3e5c3833a2f4d1 Mon Sep 17 00:00:00 2001
From: Mia <49593536+mia-pi-git@users.noreply.github.com>
Date: Sun, 24 May 2020 15:22:11 -0500
Subject: [PATCH 06/11] Apply suggestions from code review
Co-authored-by: Kris Johnson <11083252+KrisXV@users.noreply.github.com>
---
server/chat-plugins/youtube.ts | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/server/chat-plugins/youtube.ts b/server/chat-plugins/youtube.ts
index 89e2ebd0a29c..9eaeaefa2d35 100644
--- a/server/chat-plugins/youtube.ts
+++ b/server/chat-plugins/youtube.ts
@@ -14,12 +14,12 @@ const STORAGE_PATH = 'config/chat-plugins/youtube.json';
let channelData: AnyObject;
try {
- channelData = JSON.parse(FS(STORAGE_PATH).readSync()) || {};
+ channelData = JSON.parse(FS(STORAGE_PATH).readIfExistsSync() || "{}");
} catch (e) {
channelData = {};
}
-export const YouTube = new class {
+export class Youtube {
interval: NodeJS.Timeout | null;
constructor() {
this.interval = null;
@@ -76,7 +76,7 @@ export const YouTube = new class {
}
randChannel() {
const keys = Object.keys(channelData);
- const id = keys[Math.floor(Math.random() * keys.length)].trim();
+ const id = Dex.shuffle(keys)[0].trim();
return this.generateChannelDisplay(id);
}
get(id: string, username?: string) {
From e69ed12cd9570762d15ae4d7740948cad3dc43f2 Mon Sep 17 00:00:00 2001
From: Mia <49593536+mia-pi-git@users.noreply.github.com>
Date: Sun, 24 May 2020 15:24:35 -0500
Subject: [PATCH 07/11] Update youtube.ts
---
server/chat-plugins/youtube.ts | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/server/chat-plugins/youtube.ts b/server/chat-plugins/youtube.ts
index 9eaeaefa2d35..4f04085e808e 100644
--- a/server/chat-plugins/youtube.ts
+++ b/server/chat-plugins/youtube.ts
@@ -19,7 +19,7 @@ try {
channelData = {};
}
-export class Youtube {
+export class YoutubeInterface {
interval: NodeJS.Timeout | null;
constructor() {
this.interval = null;
@@ -159,6 +159,7 @@ export class Youtube {
}
};
+const YouTube = new YoutubeInterface();
export const commands: ChatCommands = {
randchannel(target, room, user) {
if (room.roomid !== 'youtube') return this.errorReply(`This command can only be used in the YouTube room.`);
From 981b0df637f126cd3da09a1efabccf72c778897b Mon Sep 17 00:00:00 2001
From: Mia <49593536+mia-pi-git@users.noreply.github.com>
Date: Sun, 24 May 2020 15:29:46 -0500
Subject: [PATCH 08/11] Update youtube.ts
---
server/chat-plugins/youtube.ts | 5 +++--
1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/server/chat-plugins/youtube.ts b/server/chat-plugins/youtube.ts
index 4f04085e808e..e771a9a139c1 100644
--- a/server/chat-plugins/youtube.ts
+++ b/server/chat-plugins/youtube.ts
@@ -20,7 +20,7 @@ try {
}
export class YoutubeInterface {
- interval: NodeJS.Timeout | null;
+ interval: NodeJS.Timer | null;
constructor() {
this.interval = null;
}
@@ -157,9 +157,10 @@ export class YoutubeInterface {
}
return rearranged;
}
-};
+}
const YouTube = new YoutubeInterface();
+
export const commands: ChatCommands = {
randchannel(target, room, user) {
if (room.roomid !== 'youtube') return this.errorReply(`This command can only be used in the YouTube room.`);
From 51bc3286e4ab9664df07f84333ddf201ed65983d Mon Sep 17 00:00:00 2001
From: Mia <49593536+mia-pi-git@users.noreply.github.com>
Date: Mon, 25 May 2020 16:01:10 -0500
Subject: [PATCH 09/11] remove approvals/link
will be in a different commit
---
server/chat-plugins/youtube.ts | 113 +--------------------------------
1 file changed, 3 insertions(+), 110 deletions(-)
diff --git a/server/chat-plugins/youtube.ts b/server/chat-plugins/youtube.ts
index e771a9a139c1..4c3d59be9442 100644
--- a/server/chat-plugins/youtube.ts
+++ b/server/chat-plugins/youtube.ts
@@ -129,12 +129,13 @@ export class YoutubeInterface {
buf += ``;
buf += `