1
\$\begingroup\$

I need help on truly understanding my self project. Javascript is a language I struggle the most with so I decided to create a project using Javascript. In my education I'm mostly familiar with C++, Java, C#.

I'm creating a Twitch chat bot using full javascript (node.js, express, mongodb), and I started my project out by using Twitch's authentication example and I started to build on that. Before I start diving futher in my project I'm already noticing that there is probably a better way to split this up into different folders and files.

The resources I check online for folder structure all say that it is up to me but I'm having difficulty following along and comparing it to what I have so far with my project.

I feel like I'm doing this very wrong, and I want to fix it now before I go further into it. ANY advice or help is appreciated.

Here is my very long, index.js file:

// Define our dependencies
var express        = require('express');
var session        = require('express-session');
var passport       = require('passport');
var OAuth2Strategy = require('passport-oauth').OAuth2Strategy;
var request        = require('request');
var handlebars     = require('handlebars');
var mongoose       = require('mongoose');
var tmi            = require('tmi.js');
var User           = require('./models/user');

// Connect to our database
mongoose.connect('<CONNECT TO DB HERE>');

// Define our constants
const TWITCH_CLIENT_ID = '<YOUR CLIENT ID HERE>';
const TWITCH_SECRET    = '<YOUR CLIENT SECRET HERE>';
const SESSION_SECRET   = '<SOME SECRET HERE>';
const CALLBACK_URL     = '<YOUR REDIRECT URL HERE>';
const TMI_API_KEY      = '<YOUR TMI API KEY>';

// Initialize Express and middlewares
var app = express();
app.use(session({secret: SESSION_SECRET, resave: false, saveUninitialized: false}));
app.use(express.static('public'));
app.use(passport.initialize());
app.use(passport.session());

/*
Twitch Authentication
*/
// Override passport profile function to get user profile from Twitch API
OAuth2Strategy.prototype.userProfile = function(accessToken, done) {
  var options = {
    url: 'https://api.twitch.tv/kraken/user',
    method: 'GET',
    headers: {
      'Client-ID': TWITCH_CLIENT_ID,
      'Accept': 'application/vnd.twitchtv.v5+json',
      'Authorization': 'OAuth ' + accessToken
    }
  };

  request(options, function (error, response, body) {
    if (response && response.statusCode == 200) {
      // Retrieves json response used to store display_name
      var json = JSON.parse(body);

      // Sets display_name to our user model
      User.display_name = json.display_name;

      done(null, JSON.parse(body));
    } else {
      done(JSON.parse(body));
    }
  });
}

passport.serializeUser(function(user, done) {
    done(null, user);
});

passport.deserializeUser(function(user, done) {
    done(null, user);
});

passport.use('twitch', new OAuth2Strategy({
    authorizationURL: 'https://api.twitch.tv/kraken/oauth2/authorize',
    tokenURL: 'https://api.twitch.tv/kraken/oauth2/token',
    clientID: TWITCH_CLIENT_ID,
    clientSecret: TWITCH_SECRET,
    callbackURL: CALLBACK_URL,
    state: true
  },
  function(accessToken, refreshToken, profile, done) {
    profile.accessToken = accessToken;
    profile.refreshToken = refreshToken;

    // Create user with values to save to database
    var user = new User({
      display_name: User.display_name,
      access_token: accessToken,
      refresh_token: refreshToken
    });

    // Securely store user profile in your DB
    user.save(function(err) {
      if (err) {
        console.log(err);
      }
      else {
        console.log('User successfully saved to DB!');
      }
    });

    done(null, profile);
  }
));

/*
Routes
*/
// Set route to start OAuth link, this is where you define scopes to request
app.get('/auth/twitch', passport.authenticate('twitch', { scope: 'user_read' }));

// Set route for OAuth redirect
app.get('/auth/twitch/callback', passport.authenticate('twitch', { successRedirect: '/', failureRedirect: '/' }));

// If user has an authenticated session, then connect chat bot, otherwise display link to authenticate
app.get('/', function (req, res) {
  if(req.session && req.session.passport && req.session.passport.user) {
    /*
    Twitch chat bot using tmi.js
    */
    // Create options for our tmi.js client
    var options = {
      options: {
        debug: true
      },
      connection: {
        cluster: "aws",
        recconect: true
      },
      identity: {
        username: "PEMchatbot",
        password: TMI_API_KEY
      },
      channels: [User.display_name]
    };
    // Create our tmi client
    var tmiClient = new tmi.client(options);
    // Connect our tmi client to the IRC we provided via options (aka twitch chat)
    tmiClient.connect();

    res.send('<html><head><title>Authenticated</title></head><body>Chatbot is connected! You may close this window.</body></html>');
  } else {
    res.send('<html><head><title>Twitch Auth Sample</title></head><a href="/auth/twitch"><img src="http://ttv-api.s3.amazonaws.com/assets/connect_dark.png"></a></html>');
  }
});

app.listen(3000, function () {
  console.log('Project PEMchatbot listening on port 3000!')
});
\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.