Skip to content

Commit

Permalink
fix(Banphrase): DRY and move to a separate file.
Browse files Browse the repository at this point in the history
  • Loading branch information
KararTY committed Aug 17, 2022
1 parent fc00b14 commit a977209
Show file tree
Hide file tree
Showing 8 changed files with 75 additions and 76 deletions.
23 changes: 6 additions & 17 deletions index.ts
Original file line number Diff line number Diff line change
@@ -1,23 +1,16 @@
// Load env variables
import { Logger } from '@adonisjs/logger'
import { PajbotAPI, TwitchAuth } from 'befriendlier-shared'
import env from './env'
import logger from './logger'

import { TwitchAuth } from 'befriendlier-shared'
import { readdirSync } from 'fs'
import path from 'path'
import PajbotConfig from './config/Pajbot'
import TwitchConfig from './config/Twitch'
import WSConfig from './config/Ws'
import env from './env'
import packageJSON from './package.json'
import Twitch from './src/Twitch'
import Ws from './src/Ws'

const logger = new Logger({
name: 'befriendlier-bot',
enabled: true,
level: typeof env.get('LOG_LEVEL') === 'string' ? String(env.get('LOG_LEVEL')) : 'info',
prettyPrint: env.get('NODE_ENV') === 'development'
})

// Initialize config values for WS.
const wsConfig = new WSConfig(env)
const server = new Ws(wsConfig, logger)
Expand All @@ -26,12 +19,8 @@ const server = new Ws(wsConfig, logger)
const apiConfig = new TwitchConfig(env)
const api = new TwitchAuth(apiConfig, logger.level)

// Initialize Pajbot.
const pajAPIConfig = new PajbotConfig()
const pajbotAPI = new PajbotAPI(pajAPIConfig, logger.level)

// Start Twitch client.
const twitch = new Twitch(apiConfig, server, api, pajbotAPI, packageJSON, logger)
const twitch = new Twitch(apiConfig, server, api, packageJSON, logger)

// Add command handlers
const commandDirectory = path.join(__dirname, 'src', 'Handlers')
Expand All @@ -48,7 +37,7 @@ void (async function loadHandlers (): Promise<void> {

// Import
const Command = (await import(fullFileName)).default
twitch.handlers.push(new Command(twitch, server, pajbotAPI, logger))
twitch.handlers.push(new Command(twitch, server, logger))
}

server.connect()
Expand Down
11 changes: 11 additions & 0 deletions logger.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import { Logger } from '@adonisjs/logger'
import env from './env'

const logger = new Logger({
name: 'befriendlier-bot',
enabled: true,
level: typeof env.get('LOG_LEVEL') === 'string' ? String(env.get('LOG_LEVEL')) : 'info',
prettyPrint: env.get('NODE_ENV') === 'development'
})

export default logger
6 changes: 3 additions & 3 deletions src/Handlers/BioHandler.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { PrivmsgMessage } from '@kararty/dank-twitch-irc'
import { BASE, BIO } from 'befriendlier-shared'
import pajbotBanphraseCheck from '../banphrase'
import DefaultHandler from './DefaultHandler'

export default class BioHandler extends DefaultHandler {
Expand Down Expand Up @@ -27,10 +28,9 @@ export default class BioHandler extends DefaultHandler {
if (message.messageText.length === 0) return ''

// Check pajbots.
const pajbotCheck = await this.twitch.pajbotAPI.check(responseMessage.channelTwitch.name, this.twitch.filterMsg(message.messageText))
const pajbot2Check = await this.twitch.pajbotAPI.checkVersion2(responseMessage.channelTwitch.name, this.twitch.filterMsg(message.messageText))
const checkMessages = await pajbotBanphraseCheck(responseMessage.channelTwitch.name, this.twitch.filterMsg(message.messageText))

if (pajbotCheck === null || pajbot2Check === null || pajbotCheck.banned || pajbot2Check.banned) {
if (checkMessages.length > 0) {
throw new Error('BANNED_PHRASES')
}

Expand Down
6 changes: 2 additions & 4 deletions src/Handlers/DefaultHandler.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { Logger } from '@adonisjs/logger'
import { PrivmsgMessage, WhisperMessage } from '@kararty/dank-twitch-irc'
import { BASE, Emote, NameAndId, PajbotAPI } from 'befriendlier-shared'
import { BASE, Emote, NameAndId } from 'befriendlier-shared'
import messagesText from '../messagesText'
import Client from '../Twitch'
import Ws from '../Ws'
Expand All @@ -9,7 +9,6 @@ export default class DefaultHandler {
protected readonly twitch: Client
protected readonly ws: Ws
protected readonly messagesText = messagesText
protected readonly pajbotAPI: PajbotAPI
protected readonly logger: Logger

public messageType = 'DEFAULT'
Expand All @@ -24,10 +23,9 @@ export default class DefaultHandler {

public helpText = (): string | null => this.i18n(this.messagesText.helpText.none)

constructor (twitch: Client, ws: Ws, pajbotAPI: PajbotAPI, logger: Logger) {
constructor (twitch: Client, ws: Ws, logger: Logger) {
this.twitch = twitch
this.ws = ws
this.pajbotAPI = pajbotAPI
this.logger = logger
}

Expand Down
2 changes: 1 addition & 1 deletion src/Handlers/MoreHandler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ export default class MoreHandler extends DefaultHandler {

void matchText(
{ ...responseMessage },
{ pajbotAPI: this.pajbotAPI, logger: this.logger, twitch: this.twitch, getEmotes: async () => await this.getEmotes(), i18n: { messagesText: this.messagesText, parse: (str) => this.i18n(str) }, noPingsStr: this.noPingsStr },
{ logger: this.logger, twitch: this.twitch, getEmotes: async () => await this.getEmotes(), i18n: { messagesText: this.messagesText, parse: (str) => this.i18n(str) }, noPingsStr: this.noPingsStr },
foundUserRoll
)
}
Expand Down
24 changes: 5 additions & 19 deletions src/Handlers/RollMatchHandler.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { Logger } from '@adonisjs/logger'
import { PrivmsgMessage } from '@kararty/dank-twitch-irc'
import { Emote, MessageType, More, PajbotAPI, ROLLMATCH } from 'befriendlier-shared'
import { Emote, MessageType, More, ROLLMATCH } from 'befriendlier-shared'
import pajbotBanphraseCheck from '../banphrase'
import Client, { RollInstance, User } from '../Twitch'
import BioHandler from './BioHandler'
import DefaultHandler from './DefaultHandler'
Expand Down Expand Up @@ -50,7 +51,6 @@ export default class RollMatchHandler extends DefaultHandler {
void matchText(
{ channelTwitch, userTwitch, messageID },
{
pajbotAPI: this.pajbotAPI,
logger: this.logger,
twitch: this.twitch,
getEmotes: async () => await this.getEmotes(),
Expand All @@ -64,7 +64,7 @@ export default class RollMatchHandler extends DefaultHandler {

export async function matchText (
{ channelTwitch, userTwitch, messageID, global }: ROLLMATCH,
{ pajbotAPI, logger, twitch, getEmotes, i18n, noPingsStr }: { pajbotAPI: PajbotAPI, logger: Logger, twitch: Client, getEmotes: () => Promise<Emote[]>, i18n: { messagesText: any, parse: (str: string) => string }, noPingsStr: (str: string) => string },
{ logger, twitch, getEmotes, i18n, noPingsStr }: { logger: Logger, twitch: Client, getEmotes: () => Promise<Emote[]>, i18n: { messagesText: any, parse: (str: string) => string }, noPingsStr: (str: string) => string },
roll?: RollInstance
): Promise<void> {
let message = ''
Expand Down Expand Up @@ -94,24 +94,10 @@ export async function matchText (
let bio = profile.bio.split(' ').map(word => emotes.findIndex(ee => ee.name === word) > -1 ? word : noPingsStr(word)).join(' ')

// CHECK BANPHRASE FOR BIO
const checkMessages: string[] = []
let checkMessages: string[] = []

if (foundUserRoll.type !== More.FAVORITESTREAMERS) {
const pajbotCheck = await pajbotAPI.check(channelTwitch.name, twitch.filterMsg(bio))
if (pajbotCheck === null) {
checkMessages.push('Banphrase API is offline.')
} else if (pajbotCheck.banned) {
logger.warn('"%s" contains bad words (%s)', bio, JSON.stringify(pajbotCheck.banphrase_data))
checkMessages.push('[BANPHRASE v1]')
}

const pajbot2Check = await pajbotAPI.checkVersion2(channelTwitch.name, twitch.filterMsg(bio))
if (pajbot2Check === null) {
checkMessages.push('Banphrase v2 API is offline.')
} else if (pajbot2Check.banned) {
logger.warn('"%s" contains bad words (%s)', bio, JSON.stringify(pajbot2Check.filter_data))
checkMessages.push('[BANPHRASE v2]')
}
checkMessages = await pajbotBanphraseCheck(channelTwitch.name, twitch.filterMsg(bio))

if (checkMessages.length > 0) {
bio = checkMessages.join(' ')
Expand Down
44 changes: 12 additions & 32 deletions src/Twitch.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,10 @@ import {
SlowModeRateLimiter,
WhisperMessage
} from '@kararty/dank-twitch-irc'
import { BASE, Emote, MessageType, More, NameAndId, PajbotAPI, TwitchAuth } from 'befriendlier-shared'
import { BASE, Emote, MessageType, More, NameAndId, TwitchAuth } from 'befriendlier-shared'
import PQueue from 'p-queue'
import TwitchConfig from '../config/Twitch'
import pajbotBanphraseCheck from './banphrase'
import DefaultHandler from './Handlers/DefaultHandler'
import LeaveChannelHandler from './Handlers/LeaveChatHandler'
import Ws, { WsRes } from './Ws'
Expand Down Expand Up @@ -143,7 +144,6 @@ export default class Client {
private readonly invisibleSuffix = ' \u{000e0000}'

public readonly api: TwitchAuth
public readonly pajbotAPI: PajbotAPI
public readonly packageJSON: any
public token: Token

Expand All @@ -158,7 +158,7 @@ export default class Client {
public readonly admins: string[] | undefined
public readonly headers: { 'user-agent': string }

constructor (config: TwitchConfig, ws: Ws, api: TwitchAuth, pajbotAPI: PajbotAPI, packageJSON: any, logger: Logger) {
constructor (config: TwitchConfig, ws: Ws, api: TwitchAuth, packageJSON: any, logger: Logger) {
this.name = config.user.name
this.id = config.user.id
this.commandPrefix = config.commandPrefix
Expand All @@ -169,8 +169,6 @@ export default class Client {

this.api = api

this.pajbotAPI = pajbotAPI

this.packageJSON = packageJSON

this.logger = logger
Expand Down Expand Up @@ -245,29 +243,9 @@ export default class Client {
public async sendMessage (channel: NameAndId, user: NameAndId, message: string, messageID?: string): Promise<void> {
const foundChannel = this.channels.get(channel.id) as Channel

const checkMessages: string[] = []

const filteredMessage = this.filterMsg(message)

const pajbotCheck = await this.pajbotAPI.check(foundChannel.name, filteredMessage)
if (pajbotCheck === null) {
checkMessages.push('Banphrase v1 API is offline.')
} else if (pajbotCheck.banned) {
// banphrase_data appears on banned === true
// const banphraseData = pajbotCheck.banphrase_data as { phrase: string }
this.logger.warn('"%s" contains bad words (%s)', message, JSON.stringify(pajbotCheck.banphrase_data))
checkMessages.push('(v1) message contains banned phrases.')
}

const pajbot2Check = await this.pajbotAPI.checkVersion2(foundChannel.name, filteredMessage)
if (pajbot2Check === null) {
checkMessages.push('Banphrase v2 API is offline.')
} else if (pajbot2Check.banned) {
// banphrase_data appears on banned === true
// const banphraseData = pajbotCheck.banphrase_data as { phrase: string }
this.logger.warn('"%s" contains bad words (%s)', message, JSON.stringify(pajbot2Check.filter_data))
checkMessages.push('(v2) message contains banned phrases.')
}
const checkMessages = await pajbotBanphraseCheck(foundChannel.name, filteredMessage)

if (checkMessages.length > 0) {
checkMessages.push('Ignoring you for a minute.')
Expand Down Expand Up @@ -457,18 +435,20 @@ export default class Client {
id = channel[1].id
}

if (typeof name === 'undefined') {
this.logger.warn('Got a NoticeMessage for an unknown user (%s): %s', msg.channelName, JSON.stringify(msg))
return
}

switch (msg.messageID) {
case 'msg_banned':
case 'tos_banned':
case 'msg_channel_banned':
case 'msg_channel_banned': {
if (typeof name === 'undefined') {
this.logger.warn('[NoticeMessage] Unknown user (%s): %s', msg.channelName, JSON.stringify(msg))
return
}
// Unhost channel.
void (this.handlers.find(command => command.messageType === MessageType.LEAVECHAT) as LeaveChannelHandler).onBanned({ name, id })
break
}
default:
this.logger.info('[NoticeMessage] %s', msg.messageID)
}
}

Expand Down
35 changes: 35 additions & 0 deletions src/banphrase.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
import { PajbotAPI } from 'befriendlier-shared'
import logger from '../logger'

import PajbotConfig from '../config/Pajbot'

const pajAPIConfig = new PajbotConfig()
const pajbotAPI = new PajbotAPI(pajAPIConfig, logger.level)

async function pajbotBanphraseCheck (channelName: string, message: string): Promise<string[]> {
const checkMessages: string[] = []

const pajbotCheck = await pajbotAPI.check(channelName, message)
if (pajbotCheck === null) {
checkMessages.push('Banphrase v1 API is offline.')
} else if (pajbotCheck.banned) {
// banphrase_data appears on banned === true
// const banphraseData = pajbotCheck.banphrase_data as { phrase: string }
logger.warn('"%s" contains bad words (%s)', message, JSON.stringify(pajbotCheck.banphrase_data))
checkMessages.push('(v1) message contains banned phrases.')
}

const pajbot2Check = await pajbotAPI.checkVersion2(channelName, message)
if (pajbot2Check === null) {
checkMessages.push('Banphrase v2 API is offline.')
} else if (pajbot2Check.banned) {
// banphrase_data appears on banned === true
// const banphraseData = pajbotCheck.banphrase_data as { phrase: string }
logger.warn('"%s" contains bad words (%s)', message, JSON.stringify(pajbot2Check.filter_data))
checkMessages.push('(v2) message contains banned phrases.')
}

return checkMessages
}

export default pajbotBanphraseCheck

0 comments on commit a977209

Please sign in to comment.