Today we'll build a ruby app(or script) to remind us to drink water every 1.5 hours using OneSignal API, whenever gem and cronjobs.

The Concept: We'll write ruby code so that it calls OneSignal API whenever we want us to remind to drink water and then OneSignal will send us Push Notifications on our browser(Mobile and PC both).

Motivation:

Yes Yes, I know there are many mobile apps(including Google Calendar) that can remind you stuff to do and also may be in a repetitive way. But, being a programmer and building something using code will make you feel good(maybe even 0.000001%, believe me, it's worth it and if you're good at Math, you'll know 0.000001% better than 0% 😜)

While doing my research many people built this kind of app with Twitter Bot, since I don't use Twitter much, I didn't consider this. Push Notifications solution worked for me. The only drawback I found in this solution is that this doesn't work offline.(I don't think Twitter or Slack bots run offline.). I always work on my Laptop with internet ON, and also my mobile internet data is also always ON, so even if I'm off my laptop I'll get this push notifications on mobile. So If you're looking for an offline solution, then this is not what you want. But, Hey, Give it a try.

Setting up:

  1. OneSignal Setup:

    • Signup at https://onesignal.com/ - if you don't have an account already.
    • Then Create a new app and add your website, icon etc. Everything is included in OneSignal setup process.
    • Add the JS code you get into your site and also download their SDK files and place it at the root of your domain. Again, Everything is included in OneSignal setup process which makes it super easy to get started.
    • Then go to you website and subscribe to your push notification from all the devices you want to get notifications.
    • Next step is to go to you OneSignal App settings -> Keys and theb Grab API and REST API Keys. Keep them safe, we'll need it later.
  2. For this tutorial, You'll need Ruby to write our code. You can see how to setup Ruby Here - GoRails. Just install Ruby, you don't need Rails.

  3. After installing Ruby, you'll need Whenever gem. Whenever is a Ruby gem that provides a clear syntax for writing and deploying cron jobs. Install it by running command below in your commandline:

    gem install whenever
    

Let's Code:

First, Create a new directory:

mkdir reminders_app
cd reminders_app

Next step is to create water_reminder.rb file.

# /path/reminders_app/water_reminder.rb

# Some Requirements :P
require 'net/http'
require "json"

# We need to convert HASH to JSON, This is available in Rails by default but not in Ruby
class Hash
  def as_json(opts = {})
    self
  end
end

# See OneSignal API for more parameters to use like icons etc.
params = {"app_id" => ENV["ONE_SIGNAL_APP_ID_REMINDERS"],
          "contents" => {"en" => "You should drink water now"},
          "headings" => {"en" => "Water Notification"},
          "subtitle" => {"en" => "You should drink water now"},
          "priority" => 10,
          "included_segments" => ["Active Users"]}

# Below is just Ruby's HTTP client request
uri = URI.parse('https://onesignal.com/api/v1/notifications')

http = Net::HTTP.new(uri.host, uri.port)
http.use_ssl = true

request = Net::HTTP::Post.new(uri.path,
                              'Content-Type'  => 'application/json;charset=utf-8',
                              'Authorization' => "Basic " + ENV["ONE_SIGNAL_REST_KEY_REMINDERS"])
request.body = params.as_json.to_json
# Making final call
response = http.request(request)

Make sure you've Environment variables ONE_SIGNAL_APP_ID_REMINDERS and ONE_SIGNAL_REST_KEY_REMINDERS in your .bashrc file or anywhere you prefer.

Then make sure you're on your app root folder /path/reminders_app/, then run command

wheneverize .

This will create an initial config/schedule.rb file for you. Delete all the commands if you want and then:

# /path/reminders_app/config/schedule.rb
env 'ONE_SIGNAL_APP_ID_REMINDERS', 'your_api_key'
env 'ONE_SIGNAL_REST_KEY_REMINDERS', 'your_rest_key'

every 1.day, at: ['6:00 am', '7:30 am', '9:00 am', '11:00 am', '12:30 pm', '2:00 pm', '4:00 pm', '5:30 pm', '7:30 pm', '9:00 pm', '10:45 pm'] do
  command "/path_to_ruby/ruby /path/reminders_app/water_reminder.rb"
end

Some Points:

  1. IDK where cronjobs runs, even if you supplied ENV variables for API and REST key in .bashrc file, things won't work. So you need to include your keys in this file also. So add them above.
  2. You can check syntax here for this schedule.rb file. Above we're telling cronjob to run every day at 6 AM, 7:30 AM etc. feel free to change accordingly to your timings.
  3. From your command line run which ruby to know location of your Ruby path. Paste this location above command "/path_to_ruby" and then with a whitespace paste the location of your water_reminder.rb file.
  4. So basically, this will tell cronjob every day at specified time to execute water_reminder.rb file.

Next step is to update our cronjob. Whenever gem provied easy way. From your reminders_app folder run:

whenever --update-crontab water_reminders

whenever --update-crontab {keyword}. Keyword is use to diffrentiate this cronjob with others so that you won't get confused later.

Then run command crontab -l, this will give output something like this:

# Begin Whenever generated tasks for: water_reminders at: 2018-08-20 11:06:02 +0530
ONE_SIGNAL_APP_ID_REMINDERS=your_api_key
ONE_SIGNAL_REST_KEY_REMINDERS=your_rest_key

0 6,9,11,14,16,21 * * * /bin/bash -l -c '/path_to_ruby/ruby /path/reminders_app/water_reminder.rb'

30 7,12,17,19 * * * /bin/bash -l -c '/path_to_ruby/ruby /path/reminders_app/water_reminder.rb'

# End Whenever generated tasks for: reminders at: 2018-08-20 11:06:02 +0530

Everythings working now. Wait for sometime and you'll get Push Notifications reminding you to drink water.

You can add more stuff like Reminder to take nap or eat food or exercise or anything. You can also have weekly tasks just run every 7.days etc. See the documentation to know all commands. That's it.

Feel free to correct me If I'm wrong somewhere. Also don't forget to comment what you've built.

Happy Reminding! Happy Hacking!

Now, Let there be The END 🙏