The Urbanairship Gem: Sending Push Notifications with Ruby

January 4, 2012

Note: I am no longer the maintainer of this gem, so please take a look at the project itself (as of 6/22/2015, it can be found here) for documentation on how to use the current version.


If you're building an app that sends push notifications, Urban Airship is a service that can save you a lot of headache. They provide a common API for sending notifications to iOS, Android and Blackberry devices, as well as some useful features like notification batching, scheduling, and the ability to tag devices to make sending a notification to a large group of users more manageable.

At Groupon we wrote the urbanairship gem to wrap these API interactions, which you can install with gem install urbanairship.

Registering a device token

Before sending notifications to a device, you have to register it with UA. The simplest way to do this is:

Urbanairship.register_device('DEVICE-TOKEN')

You can also give it an alias and a set of tags.

Urbanairship.register_device('DEVICE-TOKEN',
  :alias => 'user-1234',
  :tags => ['chicago-users']
)

The registration call is idempotent. If you want to change a device's tags or aliases later, you can resend the registration request. Just note that any attributes that are missing from the request will be removed, so be sure to include every tag and alias that you want to associate with that device token each time you make the registration call.

You can also set a 'quiet time' and timezone for each device. Check out the Urban Airship API docs for more options.

Sending a notification

Once your device tokens have been registered, sending simple notifications is easy.

Urbanairship.push({
  :device_tokens => ['DEVICE-TOKEN'],
  :aps => {:alert => 'You have a new message!', :badge => 1}
})

You can also specify tags, aliases, and even scheduled delivery times for your notifications. This code sends a push notification, delayed by one hour, to all the devices you've tagged with 'chicago-users'.

Urbanairship.push({
  :tags => ['chicago-users'],
  :schedule_for => [1.hour.from_now],
  :aps => {:alert => 'Hello Chicago!', :badge => 1}
})

The Urban Airship API docs detail even more options that you can specify.

Batched and broadcast notifications

If your back-end system uses some sort of batch process for generating and sending push notifications to multiple users, you can use Urban Airship's batch push method to cut down on the number of API requests you need to make.

Urbanairship.batch_push(
  {
    :device_tokens => ['DEVICE-TOKEN'],
    :aps => {:alert => 'Message one', :badge => 1}
  },
  {
    :device_tokens => ['DEVICE-TOKEN-TWO'],
    :aps => {:alert => 'Message two', :badge => 1}
  }
)

You can also send a message to ALL of your app's registered device tokens with the broadcast push method.

Urbanairship.broadcast_push({
  :aps => {:alert => 'Hello EVERYBODY!', :badge => 1}
})

The feedback API

Sometimes a user will opt-in for push notifications on their device and then later disable them or uninstall your app. In these cases, if you try to send a push notification to that device, it will fail and Apple will register the failure in their feedback API. If you send too many repeat notifications to devices that don't want to receive them, Apple will send you a warning or even revoke your ability to send push notifications.

Fortunately, Urban Airship steps in to help once again. If they notice you trying to send a notification to a device that can't receive it, UA will refrain from forwarding that notification along to Apple, sparing you from their wrath. But this is really just a safety measure. They also offer a feedback API which you can use to find tokens that have opted-out. You should poll this API periodically and, for each token that comes back, delete or disable it on your end.

Urbanairship.feedback(24.hours.ago) # =>
# [
#   {
#     "marked_inactive_on"=>"2011-06-03 22:53:23",
#     "alias"=>nil,
#     "device_token"=>"DEVICE-TOKEN-ONE"
#   },
#   {
#     "marked_inactive_on"=>"2011-06-03 22:53:23",
#     "alias"=>nil,
#     "device_token"=>"DEVICE-TOKEN-TWO"
#   }
# ]

This retrieves all devices which rejected a notification in the last 24 hours. We'd then go through our database and mark those tokens as inactive or just get rid of them.

That's it! With Urban Airship and a few lines of Ruby you can send cross-platform push notifications.