Documentation

What is a PubSubHubbub hub?

PubSubHubbub is an open protocol developed by Google (specifications) that allows Publishers — i.e. people who produce content on the Internet — to notify Subscribers — i.e. applications — each time they publish a story, doing so with a single request to a decentralized Hub.

The benefits of this approach are that:

  • Publishers don't have to notify each Subscriber individually, and
  • Subscribers don't have to poll the Publisher's feed at a regular interval.

You can check out this cool short video from Brett Slatkin and Brad Fitzpatrick on what is PubSubHubbub?

What is Guzzle Ayup!

Guzzle Ayup! is a PubSubHubbub Hub. Publishers can notify the Guzzle Ayup! hub that new content is available on their feeds, in turn Guzzle Ayup! hub will notify all Subscribers that the feeds they subscribed to just got updated, by directly pushing the new entries to them.

As not all Publishers notify the hub each time they publish a new story, Guzzle Ayup! also polls the feeds at regular intervals so that Subscribers won't have to.

Additionally, Guzzle Ayup! normalizes each new entry as standard Atom before pushing it to the Subscriber, making parsing a lot easier for Subscribers' applications.

Code examples

In this documentation, we provide code examples for Ruby.

We use the HTTParty ruby gem by John Nunemaker because we think it's cool, but you could use the equally cool RestClient gem, or even Curb.

Why should I notify Guzzle Ayup! each time I publish a story?

Mostly because:

  • It's the fastest way to distribute your content to subscribers (e.g. news aggregators, mashups, search engines),
  • It's really easy to set up (see New content notification),
  • It's 100% free now, and will stay that way.

Discovery

To let people know they can get free instant notifications each time you publish a story, just add the following to your ATOM or RSS feed:

Atom

<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
  <title>Example Feed</title>
  <link href="http://example.org/feed/" rel="self" />
  <!-- PubSubHubBub discovery -->
  <link href="http://<my-hub-name>.ayup.us" rel="hub" />
  <!-- end PubSubHubBub discovery -->
  <id>urn:uuid:60a76c80-d399-11d9-b91C-0003939e0af6</id>
  <updated>2003-12-13T18:30:02Z</updated>
  ...
</feed>

RSS

<?xml version="1.0" encoding="UTF-8" ?>
<rss version="2.0">
<channel>
  <title>Example Feed</title>
  <link href="http://example.org/feed/" rel="self" />
  <!-- PubSubHubBub discovery -->
  <link href="http://<my-hub-name>.ayup.us" rel="hub" />
  <!-- end PubSubHubBub discovery -->
  <pubDate>Sat, Sep 13 2010 18:30:02 +0000</pubDate>
  ...
</channel>
</rss>

New content notification

To notify Guzzle Ayup! that new content is available on one of your feed, you just have to send a POST request to:

http://hub.ayup.us/ or http://<my-hub-name>.ayup.us/

With the following parameters:

  • hub.mode: Required String The literal string "publish".
  • hub.url: Required url The URL of the feed that has been updated.

If the notification is acceptable, the hub will return an HTTP 204 No Content response. If the notification is rejected, the hub will return an HTTP 400 Bad Request response with the description of the error in the response body.

Example

require 'httparty'

class Hub
  include HTTParty
  base_uri 'http://hub.ayup.us'
end

Hub.post( '/', :query => { :'hub.mode' => 'publish',
                           :'hub.url'  => 'http://myblog.com/rss.xml' } )

WordPress Plugin

If you use WordPress for your blog, you can use the PubSubHubbub WordPress Plugin by Josh Fraser.

I can't code!

If you can't code, you can still manually ping us. Of course, it's not an ideal solution, but we want everybody to be able to notify Guzzle Ayup! when new content is made available.

So you can always ping this URL:

http://ayup.us/fresh?url=http://myblog.com/rss.xml

You can even place it in your bookmarks bar if you want!

Subscribe, unsubscribe and receive notifications

Subscribing, unsubscribing and receiving notifications is pretty easy. But here are a couple of things that you need to know:

  • To receive notifications, you need to set up a callback where the notifications will be sent via a HTTP POST request.
  • Subscribing and unsubscribing to a feed requires this very same callback to be active in order for the hub to verify the intent of the subscriber via an HTTP GET request.

Implementation

Guzzle Ayup! PubSubHubbub hub implements the Core specifications.

Please note that we do not currently support:

  • hub.lease_seconds this parameter will be ignored.
  • Subscription re-confirmation subscriptions are kept active unless you issue an "unsubscribe" command.

HTTP authentication

Subscribing and unsubscribing to a feed requires your requests to be authenticated with HTTP Basic Authentication.

  • Username is the e-mail address you used to sign up to Guzzle Ayup!
  • Password is your API key.

These information can be found in the Account Settings section of this website (Login is required).

Subscribing

Subscribing to a feed requires two actions:

  1. First, you send a subscription request to the Hub via a HTTP POST request,
  2. To verify your intent, the hub will in turn send an HTTP GET request to the HTTP callback you specified.

To start with, send a HTTP POST request to:

http://hub.ayup.us/s

With the following parameters:

  • hub.mode: Required String The literal string "subscribe".
  • hub.callback: Required url The URL of your HTTP callback.
  • hub.topic: Required url The URL of the feed you want to subscribe to.
  • hub.verify: Required String Either "sync" or "async" (can be repeated, see below).
  • hub.secret: Optional String A secret string that will be used to compute an HMAC digest of the content for every notification.
  • hub.verify_token: Optional String A token that will be echoed back in the verification request to assist the subscriber in identifying which subscription request is being verified.

Hub's response

The hub will respond to a subscription request with an HTTP 204 No Content response if the request was verified, and with an HTTP 202 Accepted response if the subscription has yet to be verified in the case of an "async" verification mode.

If an error occurred while subscribing, the hub will respond with an HTTP 400 Bad Request response with the description of the error in the response body.

Sync or Async?

If you set the value of hub.verify to "sync", the hub will trigger the verification request before the subscription request's HTTP response is returned. If it's set to "async", the verification will occur at a later point.

3 times, no more

The hub will try up to three times to contact you HTTP callback for verification purpose. If it can't get an answer after that, the subscription request will drop.

Example

Subscription request:

require 'httparty'

class Hub
  include HTTParty
  base_uri 'http://hub.ayup.us'
  basic_auth 'my_email_address', 'my_very_long_api_key'
end

Hub.post( '/s', :query  => {
  :'hub.mode'          => 'subscribe',
  :'hub.callback'      => 'http://myapp.com/endpoint',
  :'hub.topic'         => 'http://blog.com/rss.xml',
  :'hub.verify'        => 'sync',
  :'hub.secret'        => 'Y29vbCwgaGVoPw',
  :'hub.verify_token'  => 'my-unique-token'
})

Sample HTTP callback:

require 'sinatra'

get '/endpoint' do
  
  # you can verify that your app actually sent a subscription
  # request for this particular feed
  feed = Feed.find( :first,
                    :conditions => { :mode => params['hub.mode'],
                                     :url  => params['hub.topic'] } )
  
  # your app never heard of this feed, do not confirm subscription
  halt 400 if feed.nil?
  
  # we are good, echo back the challenge to the hub
  params['hub.challenge']  
  
end

Unsubscribing

Easy enough: just set the value of the hub.mode parameter to "unsubscribe", and follow the instructions to subscribe to a feed.

Notifications

Notifications will be sent to your HTTP callback via a HTTP POST request with a body consisting of an Atom feed document listing new and updated entries.

If you indicated a hub.secret when subscribing, the value of the X-Hub-Signature HTTP header is set to sha1=signature where signature is a SHA1 digest which is computed using the HMAC algorithm with the request body as the data and the hub.secret as the key.

Here's a sample notification.