Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Import commands dynamically #1

Open
Wingysam opened this issue Nov 7, 2019 · 1 comment
Labels

Comments

@Wingysam
Copy link

@Wingysam Wingysam commented Nov 7, 2019

Commands could be imported dynamically instead of the mess that has grown in 3 places having everything manually imported, you could use this as rosie-bot.js:

It needs some work to get it working with the modules that export multiple commands

const tmi = require('tmi.js');
const path = require('path');
const fs = require('fs');

require('dotenv').config();

const emotesEvent = require('./events/event-emotes');
const twitchEvents = require('./events/event-twitchEvents');
const QnAEvent = require('./events/event-QnA');
const linkEvent = require('./events/event-link');
const timedMessages = require('./events/event-timedMessages');
const voteEvent = require('./events/event-vote');
const shoutOutEvent = require('./events/event-shoutout');
let socketCommands;

const opts = {
    identity: {
        username: process.env.TWITCH_USERNAME,
        password: process.env.TWITCH_PASSWORD
    },
    channels: [
        process.env.TWITCH_CHANNEL
    ]
};

const client = new tmi.client(opts);

client.on('message', onMessageHandler);
client.on('connected', onConnectedHandler);

client.connect()
    .then((data) => {
        // data returns [server, port]
        console.log('connected!');
    }).catch((err) => {
        console.log(err);
    });;

const commands = getCommands(path.resolve('./commands'), 'event-')

/**
 * Returns all commands in a directory as an object: { '!command': <Function> }
 * @param {String} dir 
 * @param {String} prefix 
 * @returns {Object}
 */
function getCommands(dir, prefix) {
    /* Commands are stored here in this format:
     * {
     *     '!dice': require('./commands/command-dice')
     * }
    */
    const commands = {}
    // https://nodejs.org/api/fs.html#fs_fs_readdirsync_path_options
    fs.readdirSync(dir)
        // In case of something like the data directory in ./commands
        .filter(item => item.startsWith(prefix))
        // Is sync when function is sync
        .forEach(filename => {
            // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Template_literals
            const commandName = `!${filename.split(prefix)[1]}`
            // path.join for Windows compatibility
            commands[commandName] = require(path.join(dir, filename))
        })
}

async function onMessageHandler(target, context, msg, self) {
    if (!!context.emotes) {
        emotesEvent(context.emotes);
    }

    if (self) {
        return;// Ignore messages from the bot
    }

    let shoutoutMessage = shoutOutEvent.shoutOut(context);
    if(!!shoutoutMessage){
        socketCommands.speak(shoutoutMessage);
    }

    if (linkEvent.containsLink(msg)) {
        linkEvent.validateLinks(client, target, context, msg);
    }

    if (voteEvent.getIsRunning()) {
        voteEvent.handleVote(msg, context['user-id']);
    }

    if (msg.trim().endsWith("?")) {
        msg = await QnAEvent(client, target, msg);
    };

    timedMessages(client, target);

    try {
        handleBangCommand(msg, target, context);
    } catch (err) {
        console.error(err);
    }
}

function handleBangCommand(msg, target, context) {
    const chatMessage = msg.trim();
    const splitCommand = chatMessage.split(/\s/gi);
    const command = splitCommand[0].toLowerCase();
    if (commands.hasOwnProperty(command)) {
        commands[command](client, target, context, ...splitCommand.splice(1));
    } else {
        if (commands['!command'].hasCommand(command)) {
            commands['!command'].execute(client, target, context, command, splitCommand.splice(1).join(' '));
        }
    }
}

function onConnectedHandler(addr, port) {
    socketCommands = twitchEvents(client, process.env.TWITCH_CHANNEL);
    commands['!command'].init(commands);
    console.log(`* Connected to ${addr}:${port}`);
   // socketCommands.speak('Hello World! We are good to go.')

}
@sorskoot

This comment has been minimized.

Copy link
Owner

@sorskoot sorskoot commented Nov 10, 2019

Thank you very much for sharing! We'll probably use this as a reference when we refactor the 2 parts into on App.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
2 participants
You can’t perform that action at this time.