Skip to content

Commit

Permalink
Merge pull request #138 from vyneer/feat/phrases
Browse files Browse the repository at this point in the history
DES-167: update banned phrases handling
  • Loading branch information
11k committed Apr 1, 2024
2 parents b816bf7 + d9f0371 commit 31880bd
Show file tree
Hide file tree
Showing 10 changed files with 158 additions and 48 deletions.
3 changes: 2 additions & 1 deletion index.js
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ services
.then(() => {
logger.info(`Configuring for ${chatToConnectTo} chat`);
const commandRouter = new CommandRouter(services);
const messageRouter = new MessageRouter({}, services);
const messageRouter = new MessageRouter({ chatConnectedTo: chatToConnectTo }, services);
let bot = null;

if (chatToConnectTo === 'twitch') {
Expand All @@ -70,6 +70,7 @@ services
services.scheduledCommands,
services.fakeScheduler,
services.messageRelay,
services.bannedPhrases,
);
chatServiceRouter.create();
})
Expand Down
10 changes: 10 additions & 0 deletions lib/chat-utils/parse-commands-from-chat.js
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,14 @@ function parseCommand(message) {
return { commandString: commandString.toLowerCase(), input };
}

function formatAddPhrase(phrase) {
return `ADDPHRASE ${JSON.stringify({ data: phrase })}`;
}

function formatRemovePhrase(phrase) {
return `REMOVEPHRASE ${JSON.stringify({ data: phrase })}`;
}

module.exports = {
parseMessage,
parseCommand,
Expand All @@ -71,4 +79,6 @@ module.exports = {
formatPoll,
parseWhisper,
formatWhisper,
formatAddPhrase,
formatRemovePhrase,
};
28 changes: 25 additions & 3 deletions lib/commands/implementations/banphrase.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ const Command = require('../command-interface');
const CommandOutput = require('../command-output');
const parseDurationToSeconds = require('../../chat-utils/duration-parser');

function banphrase(defaultPunishmentDuration, punishmentType) {
function banPhraseTwitch(defaultPunishmentDuration, punishmentType) {
return (input, services) => {
const matched = /(\d+[HMDSWwhmds])?\s?(.*)/.exec(input);
const duration = _.get(matched, 1, '');
Expand Down Expand Up @@ -50,7 +50,29 @@ function banphrase(defaultPunishmentDuration, punishmentType) {
};
}

function banPhraseDGG() {
return (input, services) => {
const matched = /(\d+[HMDSWwhmds])?\s?(.*)/.exec(input);
const bannedPhrase = _.get(matched, 2, '').toLowerCase();
services.bannedPhrases.addBannedPhrase(bannedPhrase);
return new CommandOutput(null, 'Phrase banned!');
};
}

module.exports = {
addban: new Command(banphrase(1800, 'ban'), true, true, /(\d+[HMDSWwhmds])?\s?(.*)/, false),
addmute: new Command(banphrase(600, 'mute'), true, true, /(\d+[HMDSWwhmds])?\s?(.*)/, false),
addbanTwitch: new Command(
banPhraseTwitch(1800, 'ban'),
true,
true,
/(\d+[HMDSWwhmds])?\s?(.*)/,
false,
),
addmuteTwitch: new Command(
banPhraseTwitch(600, 'mute'),
true,
true,
/(\d+[HMDSWwhmds])?\s?(.*)/,
false,
),
addbanDGG: new Command(banPhraseDGG(), false, true, /(\d+[HMDSWwhmds])?\s?(.*)/, false),
};
41 changes: 27 additions & 14 deletions lib/commands/implementations/unbanphrase.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,19 +2,32 @@ const _ = require('lodash');
const Command = require('../command-interface');
const CommandOutput = require('../command-output');

function banphrase(input, services) {
const matched = /(.*)/.exec(input);
const phraseToUnban = _.get(matched, 1, '').toLowerCase();
if (services.spamDetection.hasBannedPhrase(phraseToUnban) === false) {
return Promise.resolve(new CommandOutput(null, 'Phrase is not registered! Did nothing.'));
}
return services.sql
.deleteBannedPhrase(phraseToUnban)
.then(() => {
services.spamDetection.removeBannedPhrase(phraseToUnban);
return new CommandOutput(null, 'Phrase unbanned! AngelThump');
})
.catch((err) => new CommandOutput(err, 'Oops. Something did not work. Check the logs.'));
function unbanPhraseTwitch() {
return (input, services) => {
const matched = /(.*)/.exec(input);
const phraseToUnban = _.get(matched, 1, '').toLowerCase();
if (services.spamDetection.hasBannedPhrase(phraseToUnban) === false) {
return Promise.resolve(new CommandOutput(null, 'Phrase is not registered! Did nothing.'));
}
return services.sql
.deleteBannedPhrase(phraseToUnban)
.then(() => {
services.spamDetection.removeBannedPhrase(phraseToUnban);
return new CommandOutput(null, 'Phrase unbanned! AngelThump');
})
.catch((err) => new CommandOutput(err, 'Oops. Something did not work. Check the logs.'));
};
}

module.exports = new Command(banphrase, true, true, /(.*)/, false);
function unbanPhraseDGG() {
return (input, services) => {
const bannedPhrase = input;
services.bannedPhrases.removeBannedPhrase(bannedPhrase);
return new CommandOutput(null, 'Phrase unbanned! AngelThump');
};
}

module.exports = {
unbanphraseTwitch: new Command(unbanPhraseTwitch(), true, true, /(.*)/, false),
unbanphraseDGG: new Command(unbanPhraseDGG(), false, true),
};
27 changes: 22 additions & 5 deletions lib/configuration/configure-commands.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,8 @@ const song = require('../commands/implementations/song');
const earlierSong = require('../commands/implementations/earliersong');
const youtube = require('../commands/implementations/youtube');
const schedule = require('../commands/implementations/schedule');
const { addban, addmute } = require('../commands/implementations/banphrase');
const unbanphrase = require('../commands/implementations/unbanphrase');
const { addbanDGG, addbanTwitch, addmuteTwitch } = require('../commands/implementations/banphrase');
const { unbanphraseDGG, unbanphraseTwitch } = require('../commands/implementations/unbanphrase');
const live = require('../commands/implementations/live');
const restart = require('../commands/implementations/restart');
const love = require('../commands/implementations/love');
Expand Down Expand Up @@ -66,9 +66,6 @@ function registerCommandsFromFiles(commandRegistry, chatConnectedTo, config) {
}
commandRegistry.registerCommand('!youtube', youtube, ['!video', '!lastvideo', '!yt']);
commandRegistry.registerCommand('!schedule', schedule, ['!sch']);
commandRegistry.registerCommand('!addban', addban);
commandRegistry.registerCommand('!addmute', addmute);
commandRegistry.registerCommand('!deleteban', unbanphrase, ['!deletemute', '!dmute', '!dban']);
commandRegistry.registerCommand('!live', live, ['!uptime']);
commandRegistry.registerCommand('!restart', restart);
commandRegistry.registerCommand('!love', love);
Expand All @@ -85,6 +82,14 @@ function registerCommandsFromFiles(commandRegistry, chatConnectedTo, config) {
commandRegistry.registerCommand('!breakingnews', breakingNews, ['!breaking', '!bn']);

if (chatConnectedTo === 'dgg') {
commandRegistry.registerCommand('!addban', addbanDGG, ['!addmute']);
commandRegistry.registerCommand('!deleteban', unbanphraseDGG, [
'!deletemute',
'!removeban',
'!removemute',
'!dmute',
'!dban',
]);
commandRegistry.registerCommand('!voteban', voteBan);
commandRegistry.registerCommand('!voteipban', voteIpban);
commandRegistry.registerCommand('!svoteban', svoteBan);
Expand All @@ -105,6 +110,18 @@ function registerCommandsFromFiles(commandRegistry, chatConnectedTo, config) {
]);
commandRegistry.registerCommand('!gulag', gulag);
}

if (chatConnectedTo === 'twitch') {
commandRegistry.registerCommand('!addban', addbanTwitch);
commandRegistry.registerCommand('!addmute', addmuteTwitch);
commandRegistry.registerCommand('!deleteban', unbanphraseTwitch, [
'!deletemute',
'!removeban',
'!removemute',
'!dmute',
'!dban',
]);
}
}

async function setupCommandsAndCachesFromDb(
Expand Down
15 changes: 15 additions & 0 deletions lib/message-routing/chat-service-router.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ class ChatServiceRouter {
messageSchedulerStream,
fakeScheduler,
messageRelay,
bannedPhrases,
) {
this.messageRouter = messageRouter;
this.commandRouter = commandRouter;
Expand All @@ -22,6 +23,7 @@ class ChatServiceRouter {
this.fakeScheduler = fakeScheduler;
// TODO just refactor other things to use the message relay
this.messageRelay = messageRelay;
this.bannedPhrases = bannedPhrases;
}

create() {
Expand Down Expand Up @@ -160,6 +162,19 @@ class ChatServiceRouter {
this.bot.sendMessage(punishmentObject.reason);
}
});

this.bannedPhrases.on('data', (obj) => {
switch (obj.action) {
case 'add':
this.bot.sendAddPhrase(obj.phrase);
break;
case 'remove':
this.bot.sendRemovePhrase(obj.phrase);
break;
default:
break;
}
})
}
}

Expand Down
53 changes: 28 additions & 25 deletions lib/message-routing/message-router.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ class MessageRouter {
this.spamDetection = services.spamDetection;
this.roleCache = services.roleCache;
this.messageRelay = services.messageRelay;
this.chatConnectedTo = config.chatConnectedTo;
}

routeIncomingMessages(newMessage) {
Expand All @@ -36,32 +37,34 @@ class MessageRouter {
return;
}

const bannedPhrase = this.spamDetection.checkAgainstBannedPhrases(messageContent);

if (bannedPhrase !== false) {
if (bannedPhrase.type === 'mute') {
this.punishmentStream.write(
makeMute(
user,
bannedPhrase.duration,
`${user} muted for using banned phrase(${bannedPhrase.text}).`,
true,
),
);
} else if (bannedPhrase.type === 'ban') {
this.punishmentStream.write(
makeBan(
user,
bannedPhrase.duration,
null,
null,
`${user} banned for using banned phrase(${bannedPhrase.text}).`,
true,
),
);
if (this.chatConnectedTo === 'twitch') {
const bannedPhrase = this.spamDetection.checkAgainstBannedPhrases(messageContent);

if (bannedPhrase !== false) {
if (bannedPhrase.type === 'mute') {
this.punishmentStream.write(
makeMute(
user,
bannedPhrase.duration,
`${user} muted for using banned phrase(${bannedPhrase.text}).`,
true,
),
);
} else if (bannedPhrase.type === 'ban') {
this.punishmentStream.write(
makeBan(
user,
bannedPhrase.duration,
null,
null,
`${user} banned for using banned phrase(${bannedPhrase.text}).`,
true,
),
);
}
this.chatCache.addMessageToRunningList(user, messageContent);
return;
}
this.chatCache.addMessageToRunningList(user, messageContent);
return;
}

const nukedPhrases = this.punishmentCache.getNukedPhrases();
Expand Down
17 changes: 17 additions & 0 deletions lib/services/banned-phrase-emitter.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
const EventEmitter = require('events');

class BannedPhrases extends EventEmitter {
constructor() {
super();
}

addBannedPhrase(phrase) {
this.emit('data', { action: 'add', phrase });
}

removeBannedPhrase(phrase) {
this.emit('data', { action: 'remove', phrase });
}
}

module.exports = BannedPhrases;
10 changes: 10 additions & 0 deletions lib/services/destinychat.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@ const {
formatUnmute,
formatBan,
formatUnban,
formatAddPhrase,
formatRemovePhrase,
formatPoll,
} = require('../chat-utils/parse-commands-from-chat');

Expand Down Expand Up @@ -119,6 +121,14 @@ class DestinyChat extends EventEmitter {
});
}

sendAddPhrase(phrase) {
this.ws.send(formatAddPhrase(phrase));
}

sendRemovePhrase(phrase) {
this.ws.send(formatRemovePhrase(phrase));
}

handleError(event) {
this.emit('error', event);
}
Expand Down
2 changes: 2 additions & 0 deletions lib/services/service-index.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ const RedditVote = require('./reddit-vote');
const MessageRelay = require('./message-relay');
const messageMatchingService = require('./message-matching');
const HTMLMetadata = require('./html-metadata');
const BannedPhrases = require('./banned-phrase-emitter')

class Services {
constructor(serviceConfigurations, chatConnectedTo) {
Expand Down Expand Up @@ -49,6 +50,7 @@ class Services {
if (chatConnectedTo === 'dgg') {
this.redditVote = new RedditVote(serviceConfigurations.redditVote, this.logger);
}
this.bannedPhrases = new BannedPhrases();
}

prepareAsyncServices() {
Expand Down

0 comments on commit 31880bd

Please sign in to comment.