A Drake Twitter-Bot - Automating the 6 God

A short story (with example code) on building a Twitter-bot that replies to tweets containing Drake lyrics with the next line of the song.

Follow the DrizzyBot: @The110God (Note: 6 in binary is 110) 😏

How I Got the Idea

I was at a bar with an old group of friends over the holidays. While we were waiting in line, one of them mentioned that he heard about a Twitter-bot that replied to tweets containing Biggie Smalls lyrics with other Biggie Smalls lyrics.

I thought the idea was hilarious, and after one or five beers decided it was something I had to build! However, I wanted to do things a little differently:

  1. I rep the 6 I am from Toronto, so the Twitter-bot would be for Drake - a.k.a the DrizzyBot
  2. The DrizzyBot would reply to tweets containing Drake lyrics with the next line of the song
  3. The DrizzyBot would run at regular intervals with no human interaction
  4. The DrizzyBot would not be flagged as spam by Twitter's (admittedly fairly impressive) spam filters

After a day of programming, tinkering, and giggling, the DrizzyBot was born. Below are my favourite tweets thus far, and the steps I took to build the DrizzyBot.

My Favourite Tweets

Technical Requirements to Build the DrizzyBot

The following languages / software / packages are needed to build and run the DrizzyBot:

  1. Ruby (at least version 2.1)
  2. The (ruby) twitter gem
$ gem install twitter    
  1. Git
  2. OPTIONAL: a linux environment for scheduling recurring cron jobs; I use a (perpetually running) Raspberry Pi that my brother bought me for Christmas - thanks Tom!

Building the DrizzyBot

A. Initial Set Up

  • Create and save bot.rb file in root directory (I called my root directory twitter_bot)
  • In bot.rb file, require Twitter gem and standard library (Date) class we will be using:
require 'twitter'
require 'date'

B. Create a Twitter Application

  1. Consumer key
  2. Consumer secret
  3. Access token (generate first in Keys and Access Tokens)
  4. Access token secret (generate first in Keys and Access Tokens)

C. Create a File Containing Passwords

  • Create and save passwords.rb file in root directory
  • Create a .gitignore file in root directory and add the passwords.rb file to it:
# passwords
passwords.rb
  • In passwords.rb file, create constant variables for passwords (containing keys from step B.):
CONSUMER_KEY        = "consumer_key123456abcdef"
CONSUMER_SECRET     = "consumer_secret123456abcdef"
ACCESS_TOKEN        = "access_token123456abcdef"
ACCESS_TOKEN_SECRET = "access_token_secret123456abcdef"

D. Create DrizzyBot Class

  • In bot.rb file, require passwords.rb file and write initialize method:
require 'twitter'
require 'date'
require_relative 'passwords'

class DrizzyBot
  def initialize
    @client = Twitter::REST::Client.new do |config|
      config.consumer_key        = CONSUMER_KEY
      config.consumer_secret     = CONSUMER_SECRET
      config.access_token        = ACCESS_TOKEN
      config.access_token_secret = ACCESS_TOKEN_SECRET
    end
  end
end

E. Copy and Paste Lyrics to Various Drake Songs

  • Create lyrics.yaml file in root directory
  • Copy and paste song lyrics in the following format (album, song, lyric; please excuse syntax highlighting):
thank_me_later:
    over:
     - Bottles on me
     - Long as someone drink it
     - Never drop the ball
     - F!ck y'all thinking?
     - Making sure the young money ship is never sinking
     - Bout to set it off in this bitch Jada Pinkett
     - I shouldn't have drove
     - Tell me how I'm getting home
  • Create lyrics.rb file in root directory
  • In lyrics.rb file, load lyrics.yaml file:
require 'yaml'
lyrics = YAML.load_file(File.join(__dir__, './lyrics.yaml'))
ALBUMS = lyrics
  • In bot.rb file, import ALBUMS constant by requiring lyrics.rb file:
require 'twitter'
require 'date'
require_relative 'passwords'
require_relative 'lyrics'

class DrizzyBot
  def initialize
    @client = Twitter::REST::Client.new do |config|
      config.consumer_key        = CONSUMER_KEY
      config.consumer_secret     = CONSUMER_SECRET
      config.access_token        = ACCESS_TOKEN
      config.access_token_secret = ACCESS_TOKEN_SECRET
    end
  end
end

F. Write DrizzyBot Rap Logic

  1. Add method to (like and) reply to tweets containing (case insensitive) lyrics from a specified album and song with the next line of the song: see reply_to_tweets(album, song)
  • Must create method that finds matching tweets (contains lyrics without matching next phrase of song): see find_tweets(phrase, next_phrase)
  • Must create method that finds the most popular tweet, as replying to too many tweets will flag us as a bot: see most_popular_tweet(phrase, next_phrase)
  • Must create method that likes tweet and generates reply with the next phrase of the song, the song name, and the album name: see reply_to_matching_tweets(phrase, next_phrase, album, song)

2. Add method to tweet random lyrics to circumvent being identified as a bot (only replying to tweets will flag you, as will tweeting the same content consecutively): see tweet_phrase_from_song(album, song)

After adding the above logic, your bot.rb file will look like this:

require 'twitter'
require 'date'
require_relative 'passwords'
require_relative 'lyrics'

class DrizzyBot
  def initialize
    @client = Twitter::REST::Client.new do |config|
      config.consumer_key        = CONSUMER_KEY
      config.consumer_secret     = CONSUMER_SECRET
      config.access_token        = ACCESS_TOKEN
      config.access_token_secret = ACCESS_TOKEN_SECRET
    end
  end

  def reply_to_tweets(album, song)
    phrase_arr = ALBUMS[album][song]

    phrase_arr[0...-1].each_with_index do |phrase, idx| # can't reply to last phrase with next phrase
      reply_to_matching_tweets(phrase, phrase_arr[idx + 1], album, song)
    end
  end

  def tweet_phrase_from_song(album, song)
    phrase_arr = ALBUMS[album][song]
    phrase = phrase_arr.sample

    puts "DrizzyBot tweeted: #{phrase} ##{album} ##{song}"

    @client.update("#{phrase} ##{album} ##{song}")
  end

  private

  def find_tweets(phrase, next_phrase)
    tweets = @client.search(phrase, {result_type: 'recent'}).take(500) # limits to 500
  
    tweets.select do |tweet|
      today = Date.today === Date.parse(tweet.created_at.to_s)

      tweet.full_text.match(/#{phrase}/i) && 
      !tweet.full_text.match(/#{next_phrase}/i) &&
      today
    end
  end

  def most_popular_tweet(phrase, next_phrase)
    tweets = find_tweets(phrase, next_phrase)

    if tweets.empty?
      false
    else
      tweets.sort! do |a, b|
        b.favorite_count <=> a.favorite_count
      end
      
      tweets.first
    end
  end

  def reply_to_matching_tweets(phrase, next_phrase, album, song)
    tweet = most_popular_tweet(phrase, next_phrase)

    if tweet && !tweet.user.screen_name.match(/The110God/i) # tweet exists and isn't my account
      screen_name = '@' + tweet.user.screen_name
      album = album.gsub('_', '')
      song = song.gsub('_', '')

      puts "Favorited then tweeted at: #{screen_name}"

      @client.favorite(tweet)
      @client.update("#{screen_name} #{next_phrase} ##{song} ##{album} #drizzybot", 
                    in_reply_to_status_id: tweet.id)
      
      sleep(rand(300) + 180) # add 3 - 8 minute gap between tweets
    end
  end
end

G. Create DrizzyBot Object and Prepare it to Tweet

At the bottom of your bot.rb file (after the last 'end'), instantiate a DrizzyBot object and instruct it to (1) reply to tweets and (2) tweet random lyrics from a given album / song (song must be in lyrics.yaml file):

drizzy_bot = DrizzyBot.new
drizzy_bot.reply_to_tweets('views', 'one_dance') # 1
drizzy_bot.tweet_phrase_from_song('views', 'one_dance') # 2

H. Execute bot.rb File

From your terminal, change into your root directory and type:

$ ruby bot.rb

And that's it! Your very own DrizzyBot. ✨Magical✨

I. OPTIONAL: Set up Crontab

If you want to have your Twitter-bot send tweets without having to lift a finger, and you have a linux environment on your computer, open your crontab:

$ crontab -e

And add the following code to execute your Twitter-bot every day at 12:01 pm (your file paths will differ; please excuse the syntax highlighting):

PATH=/home/pi/.nvm/versions/node/v8.9.3/bin:/usr/local/bin:$PATH
1 12 * * * cd /home/pi/programming/twitter_bot && ruby bot.rb

Now you have a DrizzyBot that lives on its own!!! ✨Extra Magical✨

If You Made it This Far...

Thank you for reading! If you coded along, I hope you find a funny / productive use for your Twitter-bot!

Subscribe to Charlie Reese

Don’t miss out on the latest issues. Sign up now to get access to the library of members-only issues.
[email protected]
Subscribe