a collection of problems and solutions for random combinations of technology

Sep 25, 2009

facebook push to iphone

the problem:
Facebook sends a lot of emails. I generally don't mind the default setting which sends an email everytime your friend sneezes, but I wanted certain kinds of notifications to "bubble up to the top". I recently stumbled on a new iPhone app called Notifications which offers a REST API to send push alerts to your iPhone. So, I started working on a solution...

ingredients used: Postfix 2.6.2, Dovecot 1.2.4, Dovecot Sieve 0.1.12, Ruby 1.8/1.9
prerequisites: a working Postfix and Dovecot installation
instructions for windows here

The basic flow is: mail comes in from facebook, a sieve script determines if the mail is high priority, then the mail is forwarded to a sub-address, a specific .forward file intercepts it and executes a script which utilizes the Notifications REST API

First, go get the Notifications app and register at their site. After creating your account, go to their REST API examples page. You'll see your API key embedded in the examples. You'll need it later...

I use dovecot as an IMAP server and as a MDA. This allows me to utilize the awesomeness that is the sieve plugin. In order for this recipe to work, you don't necessarily need Postfix or Dovecot. You will need a decent sieve interpreter. If you're currently using Postfix and Dovecot but are not using deliver as your MDA, here's a quick and dirty setup:

  1. modify postfix's main.cf mailbox_command = /usr/local/libexec/dovecot/deliver

  2. modify postfix's master.cf dovecot unix - n n - - pipe
    flags=DRhu user=vmail:vmail argv=/usr/local/libexec/dovecot/deliver -c /usr/local/etc/dovecot/dovecot.conf -f ${sender} -d ${user}@${nexthop} -a ${recipient}

  3. install the sieve plugin FreeBSD ports FTW $ cd /usr/ports/mail/dovecot-sieve/
    $ make install clean

  4. modify dovecot.conf protocol lda {
      ...
      mail_plugins = sieve
      ...
    }
more info here

Now we can configure a sieve script. The default location for user sieve scripts is ~/.dovecot.sieve. Here's what mine looks like require ["envelope", "subaddress", "fileinto", "copy"];
if allof(address :domain :is "from" "facebookmail.com",
         not envelope :detail "to" "notify-facebook") {
  fileinto "auto_filed.facebook";
  if allof(exists "X-Facebook-Notify",
           header :contains "X-Facebook-Notify" ["share_comment;", "feed_comment;", "friend;", "msg;", "photo_tag;", "photo_comment;", "photo_album_comment;"]) {
    redirect :copy "your_username+notify-facebook@example.com";
  }
}
in prose, form
If the mail is from facebook and does not have the sub-address "notify-facebook", file the mail into the sub-folder "auto_filed/facebook". If the mail contains specific facebook headers which we consider high priority, forward a copy to my email address with the sub-address of "notify-facebook".
In this example, the list of "high priority" notifications are when someone comments on one of your links, status, photos, albums or you receive a friend request, private message, or tags you in a photo.
I never found a list of all the message types embedded in the "X-Facebook-Notify" MIME header, if you stumble on such a list, leave a comment.

Postfix (and probably other MTAs) support different .forward files for sub-address. Let's make sure yours is configured properly by adding this to postfix's main.cf forward_path = $home/.forward${recipient_delimiter}${extension}, $home/.forward
recipient_delimiter = +

Now for our sub-address specific forward file: ~/.forward+notify-facebook. Point to a script which should take one argument of API Key and read mail from STDIN. "| /usr/local/share/mobile_notification_scripts/facebook.rb <YOUR-NOTIFICATIONS-API-KEY-GOES-HERE>"

Here's the ruby script I use... #!/usr/local/bin/ruby
require 'rubygems'
require 'tmail'
require 'mechanize'
begin
  SINGLE_TOKEN = ARGV[0]
  VERSIONLIB = '0.1'
  POST_URL = "https://www.appnotifications.com/account/notifications.xml"

  exit if SINGLE_TOKEN.blank?

  # parse mail
  email = TMail::Mail.parse(STDIN.read)
  body = (email.multipart?) ? parts.detect { |part| part.content_type == "text/plain" } : email.body
  exit if body.blank?
  link = (match = body.match(/(http:\/\/www.facebook.com\/n\/.+?)\n/)) ? match[1] : nil
  message_details = email.body.gsub(/\n/, "<br/>")
  unless link.nil?
    message_details = message_details.sub(/#{Regexp.escape(link)}.*/m,'') + <<-HTML
    <a href='#{link}'>http://www.facebook.com/...</a><br/><br>
    facebook app links:<br/>
    <table style="width:100%;">
      <tr>
        <td style="padding-top:16px;text-align:left;"><a href="fb://feed">News Feed</a></td>
        <td style="padding-top:16px;text-align:center;"><a href="fb://requests">Requests</a></td>
        <td style="padding-top:16px;text-align:right;"><a href="fb://profile">Profile</a></td>
      </tr>
      <tr>
        <td style="padding-top:30px;text-align:left;"><a href="fb://albums">Albums</a></td>
        <td style="padding-top:30px;text-align:center;"><a href="fb://notes">Notes</a></td>
        <td></td>
      </tr>
    </table>
    HTML
  end
  
  a = WWW::Mechanize.new { |agent|
    agent.user_agent = "AppNotifications Ruby #{VERSIONLIB}"
  }

  # Send a notification
  a.post(POST_URL,
    { :user_credentials => SINGLE_TOKEN,
      'notification[title]'                => 'facebook',
      'notification[message_level]'        => -1,
      'notification[silent]'               => 0,
      'notification[action_loc_key]'       => 'View',
      'notification[run_command]'          => 'notifications://',
      'notification[message]'              => email.subject,
      'notification[long_message_preview]' => email.subject,
      'notification[long_message]'         => message_details
    }
  )
rescue
end
Did you know iPhone apps can register URL scheme handlers? here's a list. Notably, facebook supports fb://profile, fb://requests, etc...
This script configures the push notification badge to automatically open the Notifications app when unlocking your phone. Once in the app, you can click on the latest notification and view the full details which includes a shortened version of the original mail. I also added some facebook app links to the bottom of the notification details.

It seems like a lot of work to get a bullshit feature. True. But it was a fun detour...

8 comments:

  1. You should be shrewd about phone repair and you have to settle on your choice as cautiously as you can. You have to focus on the parts quality. Handy reparatur

    ReplyDelete
  2. Mobile phones when all is said in done are not bio-degradable.Display Iphone reparatur

    ReplyDelete
  3. Casino de Gama Casino - DrmCD
    Casino de 파주 출장샵 Gama Casino was established in 1998 by the Government 공주 출장마사지 of the 공주 출장마사지 Federations of the Central African Republic. We 안양 출장샵 are 정읍 출장마사지 a professional, innovative and

    ReplyDelete
  4. Online playing shall be only possible on the sites with Polish license. Many of the businesses working out of the island nation of Antigua and Barbuda are publicly traded on numerous stock 슬롯사이트 exchanges, particularly the London Stock Exchange. Antigua has met British regulatory requirements and has been added to the UK's "white listing", which permits licensed Antiguan corporations to promote within the UK.

    ReplyDelete
  5. We help 1000's of gamers place secure, secure and legal bets every day across 12 international locations. Our professional workers compiles and ranks lists of the playing business's absolute best sites. Explore our hottest Sportsbook, Casino and Poker sites, plus learn our evaluations, suggestions and methods. Once you determine what to guess on, the markets supplied for that occasion should be evaluated. 안전사이트 Gambling.com supplies the most up-to-date information on legal on-line playing in every state.

    ReplyDelete
  6. The scatter symbol usually can't be matched utilizing wilds, 1xbet korea and a few games might require the scatter symbols to look on consecutive reels find a way to} pay. On some multiway games, scatter symbols still pay in unused areas. Sittman and Pitt of Brooklyn, New York developed a playing machine in 1891 that was a precursor to the fashionable slot machine. It contained 5 drums holding a total of 50 card faces and was based mostly on poker.

    ReplyDelete
  7. Golden Nugget on-line on line casino does an excellent job of capturing the 토토사이트 glitz and glamour of the real on line casino expertise, making your on line casino gaming expertise one to remember. There are more than 1,000 on line casino games to decide on} form, as well as|in addition to} live dealer options to blow you away. What’s more, their on line casino is full of bonuses and particular offers, from an enormous welcome bonus model spanking new|for model new} members to weekly promos. Variety of Games – It is essential that on-line casinos cater for the wants of all gamers phrases of|when it comes to|by way of} the games they provide. Whether it be slots, table games or live dealer titles you might be} in search of, our high ranked websites provide a number of options. Games include different themes, jackpots, minimum/maximum bets and soundtracks.

    ReplyDelete