Userstream previewers:

Coming soon there will be a number of changes that may impact applications.

The first is support for OAuth 1.0a.  When rolled out, you will be
able to sign requests to all streaming API endpoints on
betastream.twitter.com.  This means that you can use OAuth with both
user streams and other streaming calls (filter, sample, etc.)  To
obtain access tokens use the regular twitter.com OAuth flow, then sign
requests to betastream.twitter.com.  If you already have an access
token you should be able to use it with the streaming API.

The second is inclusion of fully hydrated objects for the social
events.  Instead of just getting a source id, target id, and target
object id you will get the full user object in source and target
fields, and the full status in the target object field (if
applicable).  You will also get a "created_at" field that indicates
the time the social event was created. This should dramatically reduce
the number of REST API calls needed to build a client.  Note that most
parsers shouldn't need to change -- the ID field will still be set,
you will just have more fields available. The format is the same as
statuses retrieved via the rest API, with following exceptions:

1) The user's latest status may not be included
2) The user's status count may not be included
3) The user's favorites count may not be included

An example of a hydrated social event is

{"created_at"=>"Mon May 03 17:42:55 +0000 2010",
 "target_object"=>
  {"coordinates"=>nil,
   "truncated"=>false,
   "created_at"=>"Sun Jun 28 23:10:35 +0000 2009",
   "favorited"=>false,
   "contributors"=>nil,
   "text"=>"looking at cricket eyes!",
   "id"=>4,
   "geo"=>nil,
   "in_reply_to_user_id"=>nil,
   "source"=>"web",
   "place"=>nil,
   "user"=>
    {"profile_background_tile"=>false,
     "name"=>"Ray",
     "profile_sidebar_border_color"=>"87bc44",
     "profile_sidebar_fill_color"=>"e0ff92",
     "location"=>nil,
     "created_at"=>"Mon Apr 12 00:00:00 +0000 2010",
     "profile_image_url"=>"/images/default_profile_4_normal.png",
     "profile_link_color"=>"0000ff",
     "contributors_enabled"=>false,
     "url"=>nil,
     "favourites_count"=>1,
     "id"=>4,
     "utc_offset"=>-21600,
     "profile_text_color"=>"000000",
     "protected"=>true,
     "lang"=>"en",
     "followers_count"=>3,
     "notifications"=>nil,
     "verified"=>false,
     "description"=>nil,
     "profile_background_color"=>"9ae4e8",
     "geo_enabled"=>false,
     "time_zone"=>"Saskatchewan",
     "profile_background_image_url"=>"/images/themes/theme1/bg.png",
     "statuses_count"=>1,
     "friends_count"=>3,
     "screen_name"=>"ray",
     "following"=>nil},
   "in_reply_to_screen_name"=>nil,
   "in_reply_to_status_id"=>nil},
 "event"=>"favorite",
 "target"=>
  {"profile_background_tile"=>false,
   "name"=>"Ray",
   "profile_sidebar_border_color"=>"87bc44",
   "profile_sidebar_fill_color"=>"e0ff92",
   "location"=>nil,
   "created_at"=>"Mon Apr 12 00:00:00 +0000 2010",
   "profile_image_url"=>"/images/default_profile_4_normal.png",
   "profile_link_color"=>"0000ff",
   "contributors_enabled"=>false,
   "url"=>nil,
   "favourites_count"=>1,
   "id"=>4,
   "utc_offset"=>-21600,
   "profile_text_color"=>"000000",
   "protected"=>true,
   "lang"=>"en",
   "followers_count"=>3,
   "notifications"=>nil,
   "verified"=>false,
   "description"=>nil,
   "profile_background_color"=>"9ae4e8",
   "geo_enabled"=>false,
   "time_zone"=>"Saskatchewan",
   "profile_background_image_url"=>"/images/themes/theme1/bg.png",
   "statuses_count"=>1,
   "friends_count"=>3,
   "screen_name"=>"ray",
   "following"=>nil},
 "source"=>
  {"profile_background_tile"=>false,
   "name"=>"Jack",
   "profile_sidebar_border_color"=>"87bc44",
   "profile_sidebar_fill_color"=>"e0ff92",
   "location"=>"San Francisco",
   "created_at"=>"Wed Apr 28 00:00:00 +0000 2010",
   "profile_image_url"=>
    
"http://s3.amazonaws.com/twitter_development/profile_images/2/jack_normal.jpg";,
   "profile_link_color"=>"0000ff",
   "contributors_enabled"=>false,
   "url"=>nil,
   "favourites_count"=>0,
   "id"=>3,
   "utc_offset"=>-28800,
   "profile_text_color"=>"000000",
   "protected"=>true,
   "lang"=>"en",
   "followers_count"=>2,
   "notifications"=>nil,
   "verified"=>false,
   "description"=>"love, love",
   "profile_background_color"=>"9ae4e8",
   "geo_enabled"=>false,
   "time_zone"=>"Pacific Time (US & Canada)",
   "profile_background_image_url"=>"/images/themes/theme1/bg.png",
   "statuses_count"=>1,
   "friends_count"=>2,
   "screen_name"=>"jack",
   "following"=>nil}}

The third is an improvement to the direct message payload.  Currently
it's a bit of a pain to disambiguate statuses and DMs.  We'll be
wrapping direct messages in a higher level "direct_message" object,
e.g.

{"direct_message"=>
  {"created_at"=>"Wed Apr 28 14:56:31 +0000 2010",
   "sender_screen_name"=>"user1",
   "sender"=>
    {"profile_background_tile"=>false,
     "name"=>"User1",
     "profile_sidebar_border_color"=>"87bc44",
     "profile_sidebar_fill_color"=>"e0ff92",
     "location"=>"San Francisco",
     "created_at"=>"Wed Apr 28 00:00:00 +0000 2010",
     "profile_image_url"=>
      
"http://s3.amazonaws.com/twitter_development/profile_images/2/user1_normal.jpg";,
     "profile_link_color"=>"0000ff",
     "contributors_enabled"=>false,
     "url"=>nil,
     "favourites_count"=>0,
     "id"=>3,
     "utc_offset"=>-28800,
     "profile_text_color"=>"000000",
     "protected"=>true,
     "lang"=>"en",
     "followers_count"=>2,
     "notifications"=>nil,
     "verified"=>false,
     "description"=>"love, love",
     "profile_background_color"=>"9ae4e8",
     "geo_enabled"=>false,
     "time_zone"=>"Pacific Time (US & Canada)",
     "profile_background_image_url"=>"/images/themes/theme1/bg.png",
     "statuses_count"=>1,
     "friends_count"=>2,
     "screen_name"=>"user1",
     "following"=>nil},
   "text"=>"holy calamity scream insanity",
   "recipient_screen_name"=>"user2",
   "id"=>1,
   "recipient"=>
    {"profile_background_tile"=>false,
     "name"=>"User2",
     "profile_sidebar_border_color"=>"87bc44",
     "profile_sidebar_fill_color"=>"e0ff92",
     "location"=>nil,
     "created_at"=>"Mon Feb 01 00:00:00 +0000 2010",
     "profile_image_url"=>"/images/default_profile_5_normal.png",
     "profile_link_color"=>"0000ff",
     "contributors_enabled"=>true,
     "url"=>"http://twitter.com/user2";,
     "favourites_count"=>0,
     "id"=>5,
     "utc_offset"=>19800,
     "profile_text_color"=>"000000",
     "protected"=>true,
     "lang"=>"en",
     "followers_count"=>4,
     "notifications"=>nil,
     "verified"=>false,
     "description"=>nil,
     "profile_background_color"=>"9ae4e8",
     "geo_enabled"=>false,
     "time_zone"=>"Mumbai",
     "profile_background_image_url"=>"/images/themes/theme1/bg.png",
     "statuses_count"=>7,
     "friends_count"=>4,
     "screen_name"=>"user2",
     "following"=>nil},
   "recipient_id"=>5,
   "sender_id"=>3}}

Given this structure, all messages are easily disambiguated by looking
at the first level of keys in the JSON message

1) If the key "text" exists, this is a status
2) If the key "delete" exists, this is a status deletion
3) If the key "scrub_geo" exists, this is a geo-tagging deletion message
4) If the key "direct_message" exists, this is a direct message
5) If the key "event" exists, this is a social event

We realize that email isn't the best way to keep this documented in
the long term, and we're working on getting this information onto
dev.twitter.com.  We'll send out additional notices as these become
available, but we wanted to let you know these changes were coming.

   ---Mark

http://twitter.com/mccv

Reply via email to