twitch2ma
Version:
Twitch chat bot that runs commands on the MA GrandMA2 using Telnet.
177 lines (138 loc) • 4.94 kB
text/typescript
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;
}
}