Git Product home page Git Product logo

jacques's Introduction

Build Status Coverage Status Codacy Badge dependencies Status devDependencies Status

Jacques

A simple Discord soundboard bot that uses DiscordJS to play audio in Discord voice channels, both custom sound clips and audio from youtube videos. His companion website http://jacquesbot.io displays sounds by Discord guild, usage statistics, and accepts sound clip uploads.

Please note that Discord Guild names or sound names may contain language that is inappropriate. I do not monitor or police content posted to the site, nor the servers Jacques is invited to.

Overview

While only one repository, Jacques is composed of 3 independently run modules. An overview of each module is provided immediately below. Additional information on libraries used is further down. Note: a lot of this information is for my own benefit when I come back to this project months from now and forget why I did things.

jacques-bot

The actual bot which the user interacts with in Discord. Jacques listens for user messages in text channels. When a message starts with an exclamation point, he recognizes it as a potential command. For example...

  • !lol will join the current user's voice channel and play the sound clip called "lol" on that Guild (if it exists).
  • ! will play a random sound clip.
  • !stream <youtube_url> will play a youtube video.
  • !volume will print Jacques' current volume on that guild. Optionally, a value can be provided to adjust the volume.

Functionality is explained more in-depth at Jacques' help page.

jacques-api

Provides sounds, guilds, and usage data about jacques-bot through a RESTful API. Endpoints include:

  • GET /sounds
  • GET/POST/DELETE /sounds/:guildId/:soundName
  • GET /guilds
  • GET /guilds/:guildId
  • GET /statistics
  • GET /users/:birdfeed (authentication)

jacques-web

An AngularJS, material design website that leverages jacques-api to display guilds Jacques is on, sounds on those guilds, and pretty pictures regarding sound usage (how often, how recently, randomly, etc.). Users can also preview, upload, and download sound clips.

Sound uploads

Sounds can be uploaded after the user has been "authenticated." Jacques uses a rudimentary authentication where the user types a command, "!birdfeed" on their Discord server. This command enters a User entry (mapping a generated UUID to the discord user's ID) into the database. A direct message is sent to the user that contains this 10-digit UUID ("birdfeed"). The user copies this value, visits the website, and pastes it into the "birdfeeder" to complete authentication. This birdfeed is considered stale after 2 hours, at which point the user must request new birdfeed.

This process verifies that:

  1. The user is a member of a Discord Guild that Jacques belongs to.
  2. The user has at least the "Attach Files" discord permission, allowing server administrators to restrict sound upload access.
  3. The user does not need to enter the Guild ID the submission is for, nor who is submitting it, as that is included in the User object stored server-side. They can therefore perform multiple file uploads in a row without needing to enter any information at all. Plus, I can track the origin of a sound upload with a pretty good guarantee of who is responsible.
  4. The user cannot submit sounds for guilds they are not a member of.

The birdfeed is stored client-side and then included in POST and DELETE requests.

jacques-common

Not an independently run process, but a unit-tested module that shares models, database logic, logging, utility methods etc. between modules where possible.

App Dependencies

  • AngularJS because learning this client-side framework was one of the key objectives of this project.
  • Angular Material is used in conjunction with AngularJS to use high quality components and meet Google's Material Design specifications.
  • angular-chart.js to support chart.js (below) in an AngularJS manner.
  • angular-mocks per the AngularJS documentation as a recommended dependency for unit tests, especially those involving network transactions.
  • angular-resource as the sole module used for communicating from jacques-web to jacques-api, which under the hood uses the $http service.
  • AngularUI Router, for client-side routing. Really helpful for supplying each view with the required data in Resolve blocks and mapping URLs to views.
  • App Root Path to more easily locate the root folder of the project. Primarily used to support dotenv, easily reading the .env file in any file for environment variables.
  • Bluebird to replace Mongoose promises, which are deprecated.
  • body-parser to parse JSON from network requests to jacques-api.
  • chart.js to display sound usage data and look gorgeous in general.
  • coveralls for taking unit test .lcov files and sending it to coveralls.io to view code coverage.
  • DiscordJS for interfacing with the Discord API to do anything at all involving Discord.
  • dotenv for loading environment variables for a simple .env config file. Helpful for both externalizing sensitive tokens and allowing them to differ on my development environment and 'production' box.
  • Express: the standard server framework for Node.js.
  • Express Rate Limit to prevent one IP address from overwhelming the API.
  • Angular Material File Input for supporting file uploads in AngularJS in a material fashion, plus drag-and-drop, preview, and other cool stuff.
  • mkdirp to create multiple directories in parallel. I'm not even sure if I need this module, to be honest, but I can't find a good reason to remove it.
  • moment for dates/times and math involving dates/times.
  • mongoose for communicating with MongoDB.
  • node-opus to fulfill a DiscordJS dependency for transmitting audio.
  • readdirp to read through every guild's sound directories in parallel.
  • uuid to generate unique identifiers for users that authenticate themselves across their Discord guild and the website.
  • winston because logging.
  • ytdl-core to stream Youtube videos' audio through DiscordJS.

Dev Dependencies

  • chai to make assertions in Mocha unit tests.
  • cors to locally facilitate testing between the website and api.
  • grunt for the one below this.
  • grunt-lcov-merge to combine the code coverage results of jacques-bot, jacques-api, jacques-web, and jacques-common into one .lcov file! This results in one coveralls score and page for the entirety of Jacques.
  • Jasmine as the client's unit testing framework.
  • Karma as the client's test runner. Runs the code in actual browsers, or in my case, PhantomJS on the Travis build box.
  • karma-chrome-launcher to speed up local unit testing by running them in Chrome instead of PhantomJS.
  • karma-coverage to generate code coverage from karma-run client-side unit tests.
  • karma-jasmine as glue to stick Karma and Jasmine together.
  • karma-phantomjs-launcher so that the client-side browser unit tests can be run without an actual web browser installed.
  • Mocha as the test runner for all server-side unit tests. I plug in Chai and Sinon to do asserts and mocks.
  • npm-run-all to run my unit test scripts for each module in parallel.
  • nyc to get an lcov code coverage file from each Jacques module's unit tests.
  • Sinon as the stub/spy/mock portion of the Mocha test suite.
  • Windows-Build-Tools to locally develop and run Jacques.

Nuts and Bolts

Jacques runs on a DigitalOcean droplet. This was a great learning opportunity for me to better understand setting up an environment via the command line and learning linux commands in general. PuTTY was used to communicate with the droplet from my computer. I purposely chose not to deploy using a service like Heroku so that I'm intimately involved with the entire stack. Plus, it seems more flexible.

PM2 continually runs jacques-api, jacques-web, and jacques-bot.

Nginx is used as a reverse proxy as per this guide. Jacques' web and api modules both run on the jacquesbot.io server, but have different locations (the former being "/", and the latter being "/api".

Travis builds Jacques upon any commit to the /develop or /master branch. It installs Jacques' dependencies, runs all unit tests, and submits a code coverage report to Coveralls upon build completion. I manually deploy the master branch to the droplet upon all unit tests passing.

As mentioned above, Coveralls (the "coverage" badge at the top of this page) is used to monitor Jacques' unit test code coverage. Codacy is leveraged for static code analysis. David analyzes dependencies to look for new, outdated, or insecure libraries being used by Jacques. One of the funnest parts of developing Jacques has been seeing how easy it is to plug an open source project into these sorts of tools.

jacques's People

Contributors

scb5304 avatar

Stargazers

Kurt Moan avatar Noah avatar

Watchers

James Cloos avatar  avatar  avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.