My wife Luann showed her new art work at a local venue last Saturday. Here’s how the event looked in Keene’s elmcity hub:

It got there by way of a new technique I just added to elmcity’s repertoire. Until now, the only way to syndicate events from Facebook through an elmcity hub was the one described here. In that scenario a curator asks an elmcity hub to search Facebook for public events in the hub’s location. This hasn’t worked well. If you use Facebook’s API to search for public events using the term Keene, NH you’ll find events, but only ones that include Keene, NH in the event’s title. Events that mention Keene, NH in the location field are oddly missing.

So until now, if you wanted to use Facebook to promote a public event in Keene, you had to use Keene, NH in the title to get it to work. Being married to me, Luann knows to do that, and her event was already appearing in the hub. But for most people this sort of hack will (and should) be a non-starter.

Even if Facebook’s API worked the way I’d expect, and could find public events by location rather than just by name, it’s not really the right thing. The elmcity model puts event owners in charge of data feeds that hubs (and other consumers) access at specified URLs. It’s nice to know that your public events in Facebook can be found via search. But if you want to syndicate those events through a hub you’d rather publish an explicit feed URL.

It turns out that you can, but in an odd way that requires some explaining and raises important questions about the evolving landscape of online identity. The new elmcity technique relies on the Export link at the bottom of Facebook’s Events page. The label, Export, connotes private use of the iCalendar feed behind that link. The feed is primarily for Facebook users who want to sync their Facebook Events pages to their personal calendars. When you click the link, you’re shown an URL like this:

webcal://www.facebook.com/ical/u.php?uid=652….115&key=AQD…qcT

If you change webcal to http you’ve got one of those special sharing URLs that are public, in the sense that they live on the open web, but also private, in the sense that they’re not discoverable. You wouldn’t use this kind of URL for anything really sensitive. But it can be appropriate for calendars, or friends-and-family photo galleries, or other cases where security-by-obscurity is a reasonable tradeoff.

Syndicating Facebook events

When I fetched the URL for Luann’s Facebook events, by way of her Export link, I had an iCalendar feed that was a mixed bag. It included events to which Luann had been invited by friends; those events were marked private. It also included the event that Luann was promoting; that one was marked public. Ideally Facebook would provide a separate URL for just Luann’s (or any Facebook user’s) public events. There would be nothing secret about that URL, it could be shared freely on the open web.

Lacking such an URL from Facebook, elmcity has to synthesize it. To do so, it filters the private feed to include only events that meet two criteria:

  1. They belong to the Facebook user, not to a Facebook friend of that user.

  2. They are marked public.

Here are the iCalendar properties that enable such filtering:

ORGANIZER;CN=Luann Udell:MAILTO:luann@luannudell.com
CLASS:PUBLIC

In this example, when I excluded everything in Facebook’s iCalendar feed that wasn’t organized by Luann, and wasn’t public, I was left with a feed containing just one event: Luann’s art opening. That’s the feed I wanted to tell the Keene hub to subscribe to.

My first thought was to use the normal elmcity mechanism for subscribing a hub to calendar feeds. The hub’s curator bookmarks the feed in a designated Delicious account. In this case, there would need to be an extra bit of metadata to enable the hub to filter the feed properly. It could easily find events marked PUBLIC. But how would it know to find Luann’s public events? For that it would need the name of a Facebook user, in this case Luann’s name.

At first blush that seemed easy to solve. The elmcity service uses Delicious tags to convey metadata to hubs. I could define a new convention like so:

The combination of the trusted and ics and feed tags is the normal way a curator tells a hub that the bookmarked URL is an iCalendar feed that the hub should try to process. The who=Luann+Udell tag would be extra metadata telling the hub to restrict a Facebook calendar feed to only the events organized by the named Facebook user.

Problem solved? Unfortunately no. Do you see why not? This mechanism leaks private information. Although the elmcity hub isn’t going to publish anything other than Luann’s public event, her Facebook feed also contains a private event from Judy. Anyone who scans the feeds for the Keene hub would see the unfiltered URL and could find Judy’s private event.

If the architecture of elmcity were more typical, this wouldn’t be a problem. Curators would create accounts at elmcity, they’d log into those accounts to add feeds, the lists of feeds subscribed to by hubs would be hidden from the world. But elmcity does things differently. Hubs are transparent conduits through which public information flows. They reveal their sources. Nothing needs to be hidden, and so nothing is hidden. Curators do their work out in the open. Communities served by elmcity hubs can see how those hubs are constituted.

If Facebook provided a Publish link for public events, along with an Export link for all events, then it could participate directly in elmcity-style calendar syndication. Since Facebook doesn’t offer a Publish link, elmcity needs to receive the Export link from curators by way of some private channel of communication.

Syndicating Facebook events privately

If the architecture of elmcity were more typical, curators would have accounts at elmcity and would use those accounts to send private messages to the service. But again, elmcity does things differently. You shouldn’t have to create an account for everything under the sun. You already have plenty of perfectly good accounts. Why not reuse them?

The relationship between elmcity and Delicious is one example of such reuse. A curator creates a new elmcity hub by designating a Delicious account to control it. If the administrator of the elmcity service deems the proposed new hub legitimate, he or she (so far, just me) tells the service to use that Delicious account to specify the hub’s settings and list its feed URLs.

There’s an analogous relationship between elmcity and Twitter. If a hub’s Delicious settings name a curator’s Twitter account, then Twitter becomes a channel for private messages between the curator and the hub. For example, a curator can send a Twitter direct message to the hub that simply says: start. When the hub receives the start message, it immediately refreshes all the hub’s feeds instead of waiting for the next scheduled refresh.

Until recently that was the only control message that a curator could send to a hub. But now there’s another: add_fb_feed. From my Twitter account I just sent a direct message to the elmcity service’s Twitter account. The message said:

add_fb_feed id=652...115 key=AQD...qcT who=Luann+Udell category=art

Which means the following:

  1. Make this Facebook iCalendar URL: http://www.facebook.com/ical/u.php?uid=652….115&key=AQD…qcT

  2. Restrict it to public events organized by Luann Udell

  3. Use art as the tag for events in this feed

The hub read that message and responded:

elmcity received your add_fb_feed command

And then:

facebook feed successfully added

This isn’t ideal. Curators still need to trust the elmcity service not to disclose URLs sent through the private Twitter channel. Such disclosure could happen in any of the following ways:

  • The operator of the elmcity service gives up the data on purpose. I wouldn’t, of course, but it’s theoretically possible.

  • The elmcity service gives up the data accidentally. It’s just software; mistakes happen.

  • A curator gives up the data either accidentally or on purpose. This risk exists because the elmcity service only has trust relationships with curators. They, in turn, have trust relationships with the contributors who provide calendar feed URLs. Contributors who want to use Facebook as a source for public events that flow through an elmcity hub will give their Export URLs to curators. And curators, accidentally or on purpose, could leak those URLs.

This post is already too long, so I’ll say elsewhere why I think you probably shouldn’t use Facebook as the authoritative source for public events that you want to promote. But if you understand the mechanism I’ve explained here, and if you think the risk/reward tradeoff is acceptable, then you’re welcome to use it. If you’re an elmcity curator who has designated a Twitter account for private communication with the service, here’s the new command you can send to add a Facebook feed from one of your contributors:

add_fb_feed id=UID key=KEY who=USER [category=CATEGORY]

Usage is as follows:

add_fb_feed is a required verb

id=UID is a required parameter. Replace UID with the xxx from uid=xxx in your Facebook Export URL

key=KEY is a required parameter. Replace KEY with the yyy from key=yyy in your Facebook Export URL

who=USER is a required parameter. Replace USER with your Facebook name, using + instead of the space character.

category=CATEGORY is an optional parameter. You can use a single term or a comma-separated list of terms. These will appear as tags on each event flowing from the feed through the hub.

If you send a bogus or missing command verb, or id, or key, you’ll get a Twitter message describing what went wrong.