How to seperate websocket/express server into different files?

Viewed 229

I am having trouble wrapping my head around the best way to execute some code below from a separate file. I have it running well in my my app.js but obviously, I do not want to keep a bunch of code in only app.js and want to start moving things into other files but am at a loss on how to do so. My app.js more or less looks like this and is extremely bloated:

//web server
const express = require('express');
const app = express();
const port = 3000;

//raspberryPI
const { ChatClient } = require("dank-twitch-irc");
const { yay } = require('./JavaScript/yay');
const { readPin } = require('./JavaScript/readPin');
let ejs = require('ejs');


//listen on port 3000
app.listen(port, () => console.info('Listening on port', { port }));

app.use(express.static('./'))

app.set('view engine', 'ejs');

app.get('/', (req, res) => {
  res.render('index');
})

//Setup raspberry pi stepper motor hat
let spec = {

  steppers: [{ W1: 'M1', W2: 'M2' }, { W1: 'M3', W2: 'M4'}],
  //steppers: [{ W1: 'M3', W2: 'M4' }],
};

const motorHat = require('motor-hat')(spec);

motorHat.init();
motorHat.steppers[0].setSteps(2048);
motorHat.steppers[0].setSpeed({ rpm: 5 });

let client = new ChatClient({
  connection: {
    type: "websocket",
    secure: true,
  }
});

//connected?
client.on("ready", () => console.log("Successfully connected to chat"));
client.on("close", (error) => {
  if (error != null) {
    console.error("Client closed due to error", error);
  }
});

const keywordsList = [];
client.on("PRIVMSG", (msg, error) => {
  console.log(`[#${msg.channelName}] ${msg.displayName}: ${msg.messageText}`);
  const keywordFinder = /\b(^right)|(^left)|(^fire)\b/iy;
  
  //empty array fixes null value
  const keywords = msg.messageText.match(keywordFinder) || [];
  
  if (msg.messageText === keywords[0]){
    if (keywordsList.length>10){
      keywordsList.shift();
    }
    keywordsList.push(`${msg.displayName}: ${msg.messageText}`);
    console.log(keywordsList);
  }
  // keywordsList.forEach(keywords)
  if (msg.messageText === "right") {
    motorHat.steppers[0].stepSync('fwd', 12);
  }
  if (msg.messageText === "left") {
    motorHat.steppers[0].stepSync('back', 12);
  }
  if (msg.messageText === "yay") {
   yay();
  }
  if (msg.messageText === "pin") {
    readPin();
  }
  if (error != null) {
    console.error("Client closed due to error", error);
  }
});

//connect to specific Twitch chat
client.connect();
client.join("yuhn");

and the code I am having trouble removing is this (sorry if redundant):

const keywordsList = [];
client.on("PRIVMSG", (msg, error) => {
  console.log(`[#${msg.channelName}] ${msg.displayName}: ${msg.messageText}`);t
  const keywordFinder = /\b(^right)|(^left)|(^fire)\b/iy;
  
  //empty array fixes null value
  const keywords = msg.messageText.match(keywordFinder) || [];
  
  if (msg.messageText === keywords[0]){
    if (keywordsList.length>10){
      keywordsList.shift();
    }
    keywordsList.push(`${msg.displayName}: ${msg.messageText}`);
    console.log(keywordsList);
  }
  // keywordsList.forEach(keywords)
  if (msg.messageText === "right") {
    motorHat.steppers[0].stepSync('fwd', 12);
  }
  if (msg.messageText === "left") {
    motorHat.steppers[0].stepSync('back', 12);
  }
  if (msg.messageText === "yay") {
   yay();
  }
  if (msg.messageText === "pin") {
    readPin();
  }
  if (error != null) {
    console.error("Client closed due to error", error);
  }
});

What I thought I could do is just put the code in a separate file, make sure all my modules are connected (export client and import it into the separate files along with motorhat, etc) but it does not run. Any and all help is appreciated. I have attempted to read about this for a few hours now and I keep getting in depth guides to routing/express file structure...which is fine but I need to know if that's the direction to go in and if so, the first steps.

1 Answers

With my current understanding of your code, I would start by creating a file that contains the callback of your websocket event:

ws_callbacks.js

const motorHat = require('./main.js').motorHat
const keywordsList = [];
exports.PRIVMSG_callback = (msg, error) => {
  console.log(`[#${msg.channelName}] ${msg.displayName}: ${msg.messageText}`);t
  const keywordFinder = /\b(^right)|(^left)|(^fire)\b/iy;
  
  //empty array fixes null value
  const keywords = msg.messageText.match(keywordFinder) || [];

  // Rest of your code
}

You can then access the callback by requiring ws_callbacks.js in your main file as so:

app.js

// ...
motorHat.init();
motorHat.steppers[0].setSteps(2048);
motorHat.steppers[0].setSpeed({ rpm: 5 });
exports.motorHat = motorHat

// ...
client.on("PRIVMSG", require('./ws_callbacks.js').PRIVMSG_callback )
// ...

Here, The callback accesses motorHat, which is why it is being exported within the app.js file.

Note that you can also export the other websocket callbacks (ready and close) in similar fashion.

If you prefer to keep all websocket-related code in a separate file, this is how I would write it:

chat.js

const { ChatClient } = require("dank-twitch-irc");
let client = new ChatClient({
  connection: {
    type: "websocket",
    secure: true,
  }
});

//connected?
client.on("ready", () => console.log("Successfully connected to chat"));
client.on("close", (error) => {
  if (error != null) {
    console.error("Client closed due to error", error);
  }
});

client.on("PRIVMSG", require('./ws_callbacks.js').PRIVMSG_callback )

// Exporting client in case you want to use it somewhere else
exports.client = client

And then import it in app.js. However, you have mentioned experiencing problems with importing and exporting client so I am unsure if this will work

Related