UNPKG

twitch2ma

Version:

Twitch chat bot that runs commands on the MA GrandMA2 using Telnet.

177 lines (138 loc) 4.94 kB
import Ajv = require("ajv"); import configSchema = require("../resources/config.schema.json"); import _ = require("lodash"); export class ConfigError extends Error { constructor(message: string) { super(message); Object.setPrototypeOf(this, ConfigError.prototype); this.name = ConfigError.name; } } export class Config { public readonly timeout: number; public readonly ma: MaConfig; public readonly twitch: TwitchConfig; public readonly sacn: SACNConfig; public readonly commands: Array<Command>; public readonly availableCommands: string; private readonly commandMap: _.Dictionary<Command>; constructor(config: any) { let ajv = new Ajv({ allErrors: true, useDefaults: true }); ajv.validate(configSchema, config); if(_.isArray(ajv.errors)) { throw new ConfigError(`Config file is invalid: ${ajv.errorsText(ajv.errors, {dataVar: "config"})}!`); } this.timeout = config.timeout; this.ma = new MaConfig(config.ma); this.twitch = new TwitchConfig(config.twitch); this.sacn = new SACNConfig(config.sacn); this.commands = new Array<Command>(); for (const command of config.commands) { this.commands.push(new Command(command)); } this.availableCommands = _.map(this.commands, command => `!${command.chatCommand}`).join(", "); this.commandMap = _.zipObject(_.map(this.commands, command => command.chatCommand), this.commands); } getCommand(chatCommand: string): Command { return _.get(this.commandMap, chatCommand); } } export class MaConfig { public readonly host: string; public readonly user: string; public readonly password: string; constructor(maConfig: any) { this.host = maConfig.host; this.user = maConfig.user; this.password = maConfig.password; } } export class TwitchConfig { public readonly clientId: string; public readonly accessToken: string; public readonly channel: string; constructor(twitchConfig: any) { this.clientId = twitchConfig.clientId; this.accessToken = twitchConfig.accessToken; this.channel = twitchConfig.channel; } } export interface Instructions { getChatCommand(): string; readonly consoleCommand: string; readonly message: string; readonly sacn: SACNLock; } export class Command implements Instructions { public readonly chatCommand: string; public readonly consoleCommand: string; public readonly message: string; public readonly help: string; public readonly sacn: SACNLock; public readonly parameters: Array<Parameter>; public readonly availableParameters: string; private readonly parameterMap: _.Dictionary<Parameter>; constructor(command: any) { this.chatCommand = command.chatCommand; this.consoleCommand = command.consoleCommand; this.message = command.message; this.help = command.help; if(command.sacn) { this.sacn = new SACNLock(command.sacn); } this.parameters = new Array<Parameter>(); if(_.isArray(command.parameters)) { for (const parameter of command.parameters) { this.parameters.push(new Parameter(parameter)); } this.parameterMap = _.zipObject(_.map(this.parameters, parameter => parameter.parameter), this.parameters); this.availableParameters = _.map(this.parameters, parameter => parameter.parameter).join(", "); } else { this.parameterMap = {}; } } getChatCommand(): string { return this.chatCommand; } getParameter(parameter: string): Parameter { return _.get(this.parameterMap, parameter); } } export class Parameter implements Instructions { public readonly parameter: string; public readonly consoleCommand: string; public readonly message: string; public readonly sacn: SACNLock; constructor(parameter: any) { this.parameter = parameter.parameter; this.consoleCommand = parameter.consoleCommand; this.message = parameter.message; if(parameter.sacn) { this.sacn = new SACNLock(parameter.sacn); } } getChatCommand(): string { return this.parameter; } } export class SACNLock { public readonly universe: number; public readonly channel: number; constructor(sacn: any) { this.universe = sacn.universe; this.channel = sacn.channel; } } export class SACNConfig { public readonly lockMessage: string; public readonly interface: string; public readonly timeout: number; constructor(sacn: any) { this.lockMessage = sacn.lockMessage; this.interface = sacn.interface; this.timeout = sacn.timeout; } }