Featured Projects

WWSU Sails.JS Server

WWSU Radio had to work with a limited budget as most college radio stations do. I developed a complex node.js application using the sails.js framework to bring many new features for WWSU. Together with the sails.js app, DJ Controls, and other apps, management of the station became much easier, intuitive, and enjoyable.

Technologies Used

  • JavaScript / Node.js
    • PM2 process manager
    • Sails.js MVH Framework
      • sails-mysql MySQL adapter
      • sails-hook-sockets socket.io websockets
    • Alpaca.js form builder (custom build to fix existing bugs)
    • AmplitudeJS audio player for the website / internet stream
    • HowlerJS for the display signs; audio queues and sound effects
    • bcrypt for encrypting passwords
    • breakdance for removing HTML entities in messages
    • discord.js Discord Bot Framework
    • jsonwebtoken
    • later.js recurring dates generator
    • moment.js date/time management library
    • needle HTTP client
    • node-cron recurring task scheduler
    • nodemailer email library
    • npm-gui package updater web UI
    • randomstring
    • sanitize-html HTML sanitizer
    • session-file-store for file-based sessions
    • shorthash to obfuscate sensitive information like IP addresses
    • url-safe-string for making strings URL-safe
    • winston advanced app logging
  • MariaDB Database Server
  • AdminLTE website template
  • Shoutcast Internet Audio Server (via Docker)
  • Owncast Internet Video Server (via Docker)
  • OneSignal push notifications
  • Tomorrow.io weather API
  • National Weather Service CAPS alerts feeds

Full List of Features

  • Analytics
    • Online listener tracking (Shoutcast)
    • Video stream watcher tracking (Owncast)
    • Tracking of chat messages exchanged, including in Discord
    • Tracking of broadcast times, FCC compliance, and calendar / schedule compliance
    • Reputation scores to determine how compliant members are with hosting their shows on time and complying with FCC regulations
    • Analytics separated by member/host, broadcast, or broadcast type. Also separated by week, semester, or year
    • Weekly analytics to showcase top performing shows and other motivational statistics
    • Email system sends weekly analytics to directors each week, and broadcast analytics to hosts after they finish a broadcast
  • Announcements
    • Can post or schedule messages on web pages, display signs (as slides), DJ Controls, or Timesheet application
  • Attendance Tracking
    • Tracking of attendance of broadcasts, including start/end times, absences, and cancellations
    • Separation of operation logs by broadcast
  • Authorization
    • Prevents unauthorized changes / use of the API by requiring authorization by host (DJ Controls / app), org member, director, or administrator director for sensitive endpoints
    • Authorizations are stored on the server by session and last 10 minutes
    • Prevents others from interfering with on-air broadcasts if they are not the one running it
  • Blogs
    • Can create and schedule blog posts for the website
    • Blogs are tied to the org member system; an org member can be selected as the author
    • Blogs are categorized by general, station, sports, music, or radio shows
    • When a blog post is published, the Discord bot can post in the Discord server, and OneSignal can send push notifications to subscribers
  • Bookings (Studios)
    • Org members and directors can book the on-air or production studio
    • Bookings system is tied into the calendar system; studios cannot be booked when other bookings are made or when an in-studio broadcast is scheduled
    • Can limit how much an org member can book at once or on a day
    • Also tied to the lockdown system; members with a scheduled booking can log in when scheduled to use the studio
    • Online web interface for scheduling bookings and showing the current availability status of the studios; meant for use with a touchscreen
  • Calendar
    • Advanced calendar system for managing when broadcasts are scheduled, office hours, studio bookings, and manual events like meetings or maintenance
    • Uses later.js to allow for recurring schedule rules
    • Can set overrides on specific schedules or specific days/times to change the broadcast type, description, logo, flyer, etc.
    • Priority system and conflict resolution system; can automatically cancel or re-schedule events and broadcasts when higher priority events get scheduled. And it can also reverse the changes if the higher priority event later gets re-scheduled or cancelled.
    • Automatic emails to show hosts when events get re-scheduled or cancelled
    • Can automatically queue and play RadioDJ playlists for prerecords and playlists when it is time for them to air
  • Configuration
    • How long members may book the studios
    • Categories – Groups of RadioDJ main categories and subcategories used in configuring things such as breaks, what tracks are removed when broadcasts start, what can be requested, and more
    • Breaks – Configure what happens and what tracks play for hour clockwheel breaks, when broadcasts start or end, when hosts start or end a break, and fillers to keep breaks going until hosts request to resume their show
    • URLs / API keys for the Campus Alert feed, National Weather Service CAPS feeds, OneSignal, Owncast, Shoutcast, Skyway.js, tomorrow.io, and social media websites
    • Discord.js / Discord bot settings
    • Profanity filter
    • Maximum allowed queue lengths when broadcasts are going on the air
    • Configure what instances of RadioDJ are being used and their REST server URL and password. Can also remove all of them to go into “assisted” mode where the Sails.js server expects the automation system (which does not have to be RadioDJ) to post now playing information
    • How reputation scores are calculated for org members
    • Limits to the track request system and how track requests affect track priority
    • HTML sanitizer options
    • How top-performing shows of the week are calculated
    • Limits to track liking and how liking a track affects its priority
    • Sports covered
    • Start of Semester date for semesterly analytics
    • Thresholds for when the status system should alarm for bad music tracks, server CPU use, and server memory use
  • Delay system monitoring / activation
    • via. DJ Controls application
    • DJ Controls can monitor the status of the delay system and report it to sails.js. The status system will alarm if there is an issue.
    • Delay system dump button can also be remotely triggered (eg. remote broadcasts)
  • Directors Management
    • Manage the employees of the radio station
    • Tied into the director / admin director authorization system
    • Tied into the timesheets system and calendar system (office hours)
    • Can configure which automatic emails they receive (show changes, status alarms, weekly analytics, flagged tracks)
    • Can configure who can send emails through the system as the radio station
  • Discipline
    • Can ban, temporarily or permanently, IP addresses abusing the website or API
    • Banned IP addresses will see their reason for ban when they visit WWSU and can report they acknowledged the discipline
  • Display Signage (see screenshots)
    • Two web interfaces for display signage use (see screenshots)
    • Public sign – Advertises show calendar, what is on the air, social media, how to become a member, RSS Feeds from The Guardian Media Group, emergency alerts, current weather, and 12-hour weather forecast. The display sign in the studio can also give audio alarms to guests in the studio when the host is about to go on the air.
    • Internal sign – Advertises directors and their office hours / if they are in the office now, weekly analytics, org announcements, current station status and which systems are reporting problems, and emergency alerts. Also gives audio warnings for high-priority status alarms and when a host is about to go on the air.
    • Status system can track when a display sign goes offline (no longer connected on the web page).
  • DJs / Org Member Tracking
    • Can track the full roster of station members: on-air nicknames, real names, emails, door codes, and head shots / profiles for the website.
    • Assign permissions to define which org members can book the studios, do in-studio broadcasts, do remote broadcasts, and can use their computers (via DJ Controls) to do remote sports broadcasts
    • Add and track notes, remote credits earned (contributing to the organization), and warning points (violating the org constitution or bylaws).
  • Internal Emergency Alert System
    • Separate from FCC Emergency Alert Systems and Devices
    • Pick up on alerts from the National Weather Service or Campus Alerts automatically
    • Send manual alerts
    • Read non-FCC alerts on the air through text to speech by assigning a special API endpoint as a track in the automation system
    • Get active alerts via an API endpoint, which displays on the website
    • Show alerts on the display signs, and give audible alerts when a new alert is issued and scrolling on the signs
  • Emailing
    • System can send emails automatically for a variety of things: Weekly analytics to directors, broadcast analytics to hosts after each broadcast, re-schedules / cancellations of events or bookings, major system issues detected, reported tracks / broadcasts, and more
    • Directors can send emails to people in the system as the radio station
    • Uses a queue system to reduce load on the email / SMTP server
  • Failsafes
    • Automatic failsafes for trying to keep the station on the air as best as possible, such as switching or resetting RadioDJs when they stop working correctly, sending remote broadcasts to break when the call disconnects or goes silent, etc.
  • Flagging / Reporting of Tracks and Broadcasts
    • Listeners can report tracks / broadcasts on the website in case of inappropriate content or technical issues.
    • Directors will get emailed of reports, and tracks reported will be disabled in RadioDJ until reviewed.
  • Hosts Management
    • Manage every installation of DJ Controls and the Timesheets application and view which versions are running on those computers
    • Can define which installations are allowed to connect to the station’s API
    • Can assign an org member to a host so that when the org member is marked inactive / removed, they can no longer use DJ Controls on their computer.
    • The above can also be used to prevent org members from starting remote broadcasts from their computer when not scheduled to do one.
    • Can specify which DJ Controls should lock the computer down for use only when someone booked the studio or is on the schedule for a broadcast
    • Can specify settings like which DJ Controls are responsible for silence detection, recording on-air programming, monitoring the delay system, and sending audio over the air for remote broadcasts
    • Can specify which DJ Controls have access to the administration menu to manage station settings
  • Inventory System
    • Manage all of the supplies and equipment at the station: names, makes, models, condition, quantity, location, and additional information
    • Specify which items can be checked in and out
    • Items with permission can be checked out, logging the name of the person, quantity checking out, condition on checking out, reason / use, and due date for return. Checking in asks for quantity checked in, condition, and additional notes (such as reported damage)
    • Status system alerts when items checked out are still checked out past due date or when quantity of items are missing / not checked in when expected
  • Lockdown System
    • via DJ Controls
    • DJ Controls can override the computer’s power and account locking settings with its own locking system. It full screens the computer with a login prompt. Members or directors must log in. Members can only use the computer if they booked the studio or have an in-studio broadcast scheduled.
    • DJ Controls reports to Sails.js when people log in and log out for logging in the system
    • Logs can be viewed by director, org member, or host / computer in DJ Controls
  • Logging
    • Operation logs for many things: tracks played, operations performed during broadcasts, break execution, system status changes, failsafe operations executed, failed FCC compliance, etc.
    • Logs are grouped by broadcast / attendance record so directors can view logs for a specific broadcast
    • Logs pertaining to issues can be marked by directors as acknowledged
    • Logs regarding member reputation can be marked excused or unexcused
  • Messages system
    • Can send messages from one DJ Controls to another, with visitors on the website, or with those in the Discord server
    • The Discord bot can cross-post messages to and from the station Discord server, website, and DJ Controls
    • Can send private messages to specific visitors / IP addresses / DJ Controls, and visitors can send private messages to broadcast hosts
  • Metadata
    • Can track what is currently airing or playing on the air and present that information in the API, such as on the website or display signs
    • When sails.js is rebooted, meta is remembered as it is saved in the database
  • Requests System
    • Web visitors can request tracks in RadioDJ
    • Requests are queued / played as defined when configuring breaks
    • Broadcast hosts can also view and play requests
    • Request system prevents requesting tracks already in the queue or which played recently / would violate RadioDJ track repeat rules
  • Shootout Scoreboard
    • Contains a Basketball shootout scoreboard feature for the display signs for use with the in-office mini basketball hoop.
    • Directors can have timed shootouts and keep score with music and audio sound effects
  • Silence Detection
    • via DJ Controls
    • DJ Controls can monitor for on-air silence and report it to sails.js
    • Silences can be logged and failsafes can be triggered (such as going to break, ending a broadcast, or changing / resetting RadioDJ) depending on what is currently broadcasting
  • State Changes / RadioDJ Integration for Broadcasts
    • via DJ Controls
    • System can make managing broadcasts, such as going on/off the air or doing breaks, easier by reducing the number of things that must be clicked
    • Sails.js will remotely tell what RadioDJ should do, and gracefully start / stop it, when starting or stopping broadcasts or breaks
  • Status System
    • Many station systems are monitored by the sails.js server regularly. And detected issues are reported to directors along with guides on how to fix the issues.
    • Critical issues are emailed to respective directors.
    • Major and critical issues can trigger an alarm on display signage.
    • DJ Controls can display current system issues and logged issues from the past.
  • Subscribers / Push Notifications
    • via OneSignal
    • Visitors can subscribe to broadcasts to receive push notifications for when they air, get re-scheduled, or get cancelled.
    • Can subscribe to all schedules or a specific schedule or date/time
    • Can also subscribe to a blog category to get notified of new blog posts in that category
    • Can receive notifications when requested tracks begin playing
    • Can receive notifications for direct messages
    • Notifications can be managed on the website
  • Timesheets
    • Directors can clock in and out of the office via the timesheet app which runs on a computer at the station.
    • Directors can also clock in and out for remote hours on a website
    • The status of a director (whether they are in the office, doing remote hours, or out of office) is displayed on the website and display signs
    • The dates/times that directors clock in and out, and their reported accomplishments when clocking out, are logged and can be viewed
    • Missed scheduled office hours are logged
  • Underwritings / Commercials
    • Underwritings in RadioDJ can be scheduled in sails.js
    • Schedules can be made specifying days of the week and hours of the day the underwriting should air. Filters can also be applied ensuring it only airs during certain broadcasts.
    • Schedules can be forced (always once per hour) or algorithmic (sails.js determines when to air them based on many factors like needed spin counts left, start / end date, priority, and openness of the schedules).
    • Sails.js can adjust frequencies based on the number of online listeners currently listening (more listeners = more frequent)
    • Status system can alert of underwritings that missed the required number of spins by their end date, though the system tries to ensure they are met
  • Weather
    • via Tomorrow.io API
    • Sails.js reports weather information to display signs and DJ Controls to display current weather and weather forecast
  • Website (see screenshots)
    • Progressive Web App responsive website
    • Audio player for tuning in to the internet stream for the station
    • Page listing information about the station and its social media
    • Page listing the directors at the station, their office hours, head shots, profile, and whether or not they are currently in the office
    • Page listing all org members, their head shots / profile, and broadcasts of which they are a host / co-host
    • Blog posts by category with a search
    • Now playing on the air along with recently played tracks and the ability to like a track or report a track or broadcast for inappropriate content
    • Video stream page for watching the video stream when live, and a live badge when someone is video streaming
    • Radio shows and sports broadcasts pages listing all active radio shows / sports, their description, and regular broadcast schedules in the station timezone (including re-schedules and cancellations)
    • Program calendar for viewing upcoming broadcasts by day (up to 28 days) in the local timezone of the website visitor
    • Chat page for sending and receiving messages with other listeners and show hosts
    • Subscribe buttons for receiving push notifications of shows or blogs
    • Notifications tab to manage notifications
    • Track request page to browse tracks in the system and request

Display Sign Screenshots

Website Screenshots