Catching Up on SpotBot

Spotbot 1 Link to heading

Spotbot is a Discord bot that scrapes Spotify links from a Discord channel and automatically adds the songs to a set Spotify playlist. Users must set up and host the bot on their own hardware. To authenticate, user login with a Spotify account and set all parameters in a JSON file. In its original state the bot utilizes files for storage of links sent in the chat.

When Matt, my college friend started applying to jobs he wanted to again start development to have a project to talk about in interviews. He decided to ask for help from some of his friends and create a new GitHub for use to work on.

Upgrades Link to heading

The big upgrades planned:

  • Store data in database: allows for new features and storage of meta-data
  • Spotbot Installer: simplifies installation process
  • Rate limiting: avoids issues with several songs being sent in chat
  • Leaderboards: “gameify” the use of the app
  • Milestones / achievements: “gameify” the use of the app

We set up a Kanban and got to work. My first order of business was working on the database to store the links sent in the chat and collect more metadata for later analysis or features.

Database Link to heading

The application already had some overhead in the form of hosting and configuration. Weighing these characteristics I chose SQLite for its lightweight nature and Python library for integration.

This required the baseline creation of the database for the storage of links, messages, timestamps, and users responsible for said links. Any portion of the application that previously interfaced with the file now had to be updated to connect to the database and query for results. Notable aspects of previously established functions that had to be re-written were the following:

  • Random song function
  • Duplicate song check
  • URI staging file function

It goes without saying that after transitioning code to interface with this database, proceeding functions will also need to interface with the database.

A small side note on databases, the playlist duration milestones function also uses the database. The playlist duration milestones are measured in hours from 1 all the way to 1000 and need persistence if the server for some reason has to restart. This could have been achieved through JSON but another team member is theorizing that cross-platform issues between Linux and Windows are due to JSON writing. Thus, a database table was created to keep track of achievements.

Leaderboards Link to heading

The ideas for leaderboards help “gameify” the application by adding leaderboards for songs given by each user. To cover bases for all sizes of servers, several types of leaderboards were made:

  1. A leaderboard for all-time stats
  2. A this-month leaderboard for stats on the current month
  3. A reaction champion for highest reacted songs for the current month

All-Time The first leaderboard for all time stats was made possible through the use of basic SQL. Utilizing the harvested sender_id from each filed Spotify link, the application can group all songs sent by the same user together. This is then filled into an embed to be sent to the chat that is formatted in a presentable fashion, alongside a link to the playlist itself.

This Month The second leaderboard that is limited to the current month makes use of the timestamp field in the database. As each link is filed in the database, the exact time stamp is recorded from the actual Discord message itself. This is made possible through discords data. when the message is recorded, the timestamp that it was sent to the Discord server using msg.created_at. I then format this to year-month-day hour:minute:second. Using the current year and month the SQL select statement can return only songs from this time period and count the number of links sent by each individual user.

Reactions this Month Finally, the last leaderboard is the reaction champion leaderboard. In Discord, users can add “reactions” to messages, where an emoji will be displayed under the respective message. Other users can click this reaction to add another reaction to it. This leaderboard utilizes the discord_message_id, a metric that our database collects that references the ID of the actual message on Discords servers. The usefulness of this metric offers the exact messages that need to be looked at. instead of parsing the entire log of messages, the bot can skip messages that do not count and begin the tally on messages that contain links sent containing Spotify songs.

Achievements Link to heading

For achievements the app uses 2 metrics; number of songs in the playlist and playlist duration.

Number of Songs The first and most simple of the 2 is the number of songs in the playlist. Every 5 messages, the number of songs is compared to the pre-set number of milestones that grow in size from 25 songs to the 100’s of songs. If one of these numbers is met, a message is crafted and sent from the bot in celebration.

Playlist Duration For the more complex of the 2 we have the playlist duration achievements. Again as previously stated, the playlist duration milestones function also uses the database. This requires the use of the Spotify API.

All of the work regarding the initial access to Spotify’s API, token handling, and token renewal, was already written and in a working state. This whole portion needed to be rewritten to better promote abstraction to pass a spotipy object to be used by the duration achievement portion of the program. In short, many aspects of the playlist_update.py file were moved around and rewritten to break up processes into smaller easier to digest methods.

With these methods, the spotipy object can be retrieved and used by achievements.py to get the playlist items from Spotify’s API and begin the process of summing the total duration in hours. This is then returned. The problem that separates this issue from the initial number of songs achievement is the fact that the playlist could potentially be the length of an achievement for several checks.

Using the database created, if the length in hours matches a milestone the database will record an associated timestamp for each milestone respectively. When the length is checked again and the duration is still the same milestone the timestamp will be populated and no longer send out a celebration message.

Summary Link to heading

Spotbot is a Discord bot that adds Spotify links from a Discord channel to a Spotify playlist. The initial project utilized text files for its main storage of songs. With the upgrades I have done so far, the bot now uses an SQLite database for storing links, messages, timestamps, and user data. Some features I have added include leaderboards and achievements that “gameify” the app and increase user interaction.

These leaderboards track all-time stats, monthly stats, and reactions. The achievements are based on the number of songs and playlist duration. The database offers persistence and avoids issues with JSON. Finally I have better abstracted the Spotify API interactions within the app for better maintainability.