SlideShare a Scribd company logo
Developing with @twitterapi




                                     TM

10 June 2010
giving a talk abouttalk at @chirp entitled
       an @ignite coding against the
@twitterapi
"energy / tweet".
about 2 minutes ago via mobile web from Y-Combinator San Francisco
                                        Fort Mason,
What is                     ?
How to use the Twitter Platform
What is                    ?
‣   REST API
    ‣   provides the “basic”       functionality - tweet, follow, etc.
    ‣   all functions available on your timeline on twitter.com
‣   Search API
    ‣   real-time search index
    ‣   get “top tweets” / relevant search results
‣   Streaming API
    ‣   HTTP long-poll connection
    ‣   tweets come out of the system in real-time
Tools of the trade
‣   dev.twitter.com
    ‣   documentation center
    ‣   API console for quick testing and exploration
‣   curl and a web browser
    ‣   testing unauthenticated endpoints
    ‣   CLI to get a raw dump of the interaction
‣   twurl
    ‣   OAuth-enabled version of curl
Authenticating to
‣   OAuth 1.0a
    ‣   signing “write” requests
    ‣   give     visibility into the stack
‣   Applications don’t have a user’s username / password
    ‣   user can change password at any time
    ‣   user is secure in knowing his/her password not being stored outside
        of
    ‣   user can revoke permissions to app at any time
Libraries
‣   PHP - http://github.com/abraham/twitteroauth
‣   Java - http://github.com/fernandezpablo85/scribe
‣   Ruby - http://oauth.rubyforge.org/
‣   C / C++ - http://liboauth.sourceforge.net/
‣   Actionscript / Flash - http://code.google.com/p/oauth-as3/
twurl
‣   http://github.com/marcel/twurl
‣   Command line tool to interact          with using OAuth
‣   Transparently handles OAuth signing against
    ‣   authorize against to get access tokens
    ‣   from there on out, all requests are signed
Limits
‣   350 API calls/hour using OAuth against api.twitter.com
    ‣   unauthenticated it goes against the source IP address
    ‣   authenticated it goes against the calling user
‣   “Natural” limits on
    ‣   number of tweets sent
    ‣   number of DMs sent
    ‣   number of followings / unfollowings
‣   Status limits
    ‣   can’t have duplicate tweets
    ‣   can’t have malware links in tweets
dev.twitter.com
The developer console
Creating an app
Your own small playground
Intro to developing for @twitterapi (updated)
Intro to developing for @twitterapi (updated)
Intro to developing for @twitterapi (updated)
Using the console
Interacting with @   for fun and profit
Intro to developing for @twitterapi (updated)
Intro to developing for @twitterapi (updated)
Intro to developing for @twitterapi (updated)
Intro to developing for @twitterapi (updated)
Intro to developing for @twitterapi (updated)
Anatomy of the
REST API
GETing from the API
Reading, reading, reading
GETing from the API
‣   For most cases, completely wide open
‣   Can do a HTTP connect and a simple GET request
‣   “Protected” information may require authentication (covered later)
    ‣   getting the tweet of a protected user
    ‣   getting the timeline of a user
Status objects
The basis of everything
Getting a status object
‣   Figure out the ID of the status objects
‣   Construct the URL for statuses/show
‣   Grab it!
Intro to developing for @twitterapi (updated)
Taking a look at status 13762161921
‣   Build the API URL
    ‣   http://api.twitter.com/1/statuses/show/
        13762161921.xml
    ‣   http://api.twitter.com/1/statuses/show/
        13762161921.json
‣   If it’s a public status, then just fetch it
    ‣   use a browser!
    ‣   use curl!
Taking a look at status 13762161921
[raffi@tw-mbp13-raffi Desktop]$ curl http://api.twitter.com/1/statuses/show/
13762161921.xml
<?xml version="1.0" encoding="UTF-8"?>
<status>
  <created_at>Tue May 11 01:58:56 +0000 2010</created_at>
  <id>13762161921</id>
  <text>...and another late night</text>
  <source>&lt;a href=&quot;http://mehack.com&quot; rel=&quot;nofollow&quot;&gt;@raffi's
Test App&lt;/a&gt;</source>
  <truncated>false</truncated>
  <in_reply_to_status_id></in_reply_to_status_id>
  <in_reply_to_user_id></in_reply_to_user_id>
  <favorited>false</favorited>
  <in_reply_to_screen_name></in_reply_to_screen_name>
  <user>
    <id>8285392</id>
    <name>raffi</name>
    <screen_name>raffi</screen_name>
    <location>San Francisco, California</location>
    <description>Tinkering, writing, engineering, and breaking things on the
@twitterapi.</description>
    <profile_image_url>http://a1.twimg.com/profile_images/364041028/raffi-headshot-
casual_normal.png</profile_image_url>
    <url>http://www.mehack.com/</url>
Dissecting a status object
                                                             The tweet's unique ID. These                   Text of the tweet.
                                                                IDs are roughly sorted &             Consecutive duplicate tweets
                                                             developers should treat them             are rejected. 140 character
                                                            as opaque (http://bit.ly/dCkppc).          max (http://bit.ly/4ud3he).
        DEPRECATED




                                 {"id"=>12296272736,
                                  "text"=>
                                  "An early look at Annotations:
                                   http://groups.google.com/group/twitter-api-announce/browse_thread/thread/fa5da2608865453",                      Tweet's
                                  "created_at"=>"Fri Apr 16 17:55:46 +0000 2010",                                                                  creation
                                  "in_reply_to_user_id"=>nil,                                             The ID of an existing tweet that           date.
                                  "in_reply_to_screen_name"=>nil,                                          this tweet is in reply to. Won't
                                  "in_reply_to_status_id"=>nil                                            be set unless the author of the
 The author's




                                                                              The screen name &
                                  "favorited"=>false,
   user ID.




                                                                              user ID of replied to       referenced tweet is mentioned.
                                  "truncated"=>false,      Truncated to 140
                                                           characters. Only      tweet author.
                                  "user"=>
                                                          possible from SMS.                               The author's
                                   {"id"=>6253282,
                                                                                                            user name.                             The author's
                                    "screen_name"=>"twitterapi",
                                                                                       The author's                                                  biography.
                                    "name"=>"Twitter API",
                                                                                      screen name.
 d object can get out of sync.




                                    "description"=>
                                    "The Real Twitter API. I tweet about API changes, service issues and
 uthor of the tweet. This




                                     happily answer questions about Twitter and our API. Don't get an answer? It's on my website.",
                                    "url"=>"http://apiwiki.twitter.com",                                                                                   The author's
                                    "location"=>"San Francisco, CA",                                                                                          URL.
                                                                                    The author's "location". This is a free-form text field, and
                                    "profile_background_color"=>"c1dfee",           there are no guarantees on whether it can be geocoded.
                                    "profile_background_image_url"=>
                                    "http://a3.twimg.com/profile_background_images/59931895/twitterapi-background-new.png",
                                                                                                                                                Rendering information
                                    "profile_background_tile"=>false,
                                                                                                                                                for the author. Colors
                                    "profile_image_url"=>"http://a3.twimg.com/profile_images/689684365/api_normal.png",
The tweet's unique ID. These                  Text of the tweet.
                                                  IDs are roughly sorted &            Consecutive duplicate tweets
                                               developers should treat them            are rejected. 140 character
                                              as opaque (http://bit.ly/dCkppc).         max (http://bit.ly/4ud3he).
    DEPRECATED




                   {"id"=>12296272736,
                    "text"=>
                    "An early look at Annotations:
                     http://groups.google.com/group/twitter-api-announce/browse_thread/thread/fa5da2608865453",                   Tweet's
                    "created_at"=>"Fri Apr 16 17:55:46 +0000 2010",                                                               creation
                    "in_reply_to_user_id"=>nil,                                             The ID of an existing tweet that        date.
                    "in_reply_to_screen_name"=>nil,                                          this tweet is in reply to. Won't
                    "in_reply_to_status_id"=>nil                                            be set unless the author of the
The author's




                                                                The screen name &
                    "favorited"=>false,
  user ID.




                                                                user ID of replied to       referenced tweet is mentioned.
                    "truncated"=>false,      Truncated to 140
                                             characters. Only      tweet author.
                    "user"=>
                                            possible from SMS.                               The author's
                     {"id"=>6253282,
                                                                                              user name.                          The author's
                      "screen_name"=>"twitterapi",
                                                                         The author's                                              biography.
                      "name"=>"Twitter API",
                                                                        screen name.
get out of sync.




                      "description"=>
                      "The Real Twitter API. I tweet about API changes, service issues and
tweet. This




                       happily answer questions about Twitter and our API. Don't get an answer? It's on my website.",
                      "url"=>"http://apiwiki.twitter.com",                                                                                The author's
                      "location"=>"San Francisco, CA",                                                                                       URL.
                                                                      The author's "location". This is a free-form text field, and
"favorited"=>false,                                                         referenced tweet is mentioned.




  user ID
                                                                                     user ID of replied to




The auth
                                       "truncated"=>false,      Truncated to 140
                                                                 characters. Only       tweet author.
                                       "user"=>
                                                               possible from SMS.                                   The author's
                                        {"id"=>6253282,
                                                                                                                    user name.                                   The author's
                                         "screen_name"=>"twitterapi",
                                                                                              The author's                                                        biography.
                                         "name"=>"Twitter API",
                                                                                             screen name.
embedded object can get out of sync.     "description"=>
                                         "The Real Twitter API. I tweet about API changes, service issues and
   The author of the tweet. This


                                          happily answer questions about Twitter and our API. Don't get an answer? It's on my website.",
                                         "url"=>"http://apiwiki.twitter.com",                                                                                           The author's
                                         "location"=>"San Francisco, CA",                                                                                                  URL.
                                                                                           The author's "location". This is a free-form text field, and
                                         "profile_background_color"=>"c1dfee",             there are no guarantees on whether it can be geocoded.
                                         "profile_background_image_url"=>
                                         "http://a3.twimg.com/profile_background_images/59931895/twitterapi-background-new.png",
                                                                                                                                                             Rendering information
                                         "profile_background_tile"=>false,
                                                                                                                                                             for the author. Colors
                                         "profile_image_url"=>"http://a3.twimg.com/profile_images/689684365/api_normal.png",
                                                                                                                                                              are encoded in hex
                                         "profile_link_color"=>"0000ff",
                                                                                                                                                                  values (RGB).
                                         "profile_sidebar_border_color"=>"87bc44",                 The creation date
                                         "profile_sidebar_fill_color"=>"e0ff92",                    for this account.
                                         "profile_text_color"=>"000000",                                                      Whether this account has
                                         "created_at"=>"Wed May 23 06:01:13 +0000 2007",                                         contributors enabled
                                         "contributors_enabled"=>true,                                                          (http://bit.ly/50npuu).                   Number of
Number of tweets




                                         "favourites_count"=>1,                                                                                                          favorites this
 this user has.




                                         "statuses_count"=>1628,                                                                                    Number of              user has.
                                         "friends_count"=>13,                                                                                     users this user
                                         "time_zone"=>"Pacific Time (US & Canada)",                           The timezone and offset              is following.
                                         "utc_offset"=>-28800,                                               (in seconds) for this user.
                                         "lang"=>"en",                                                                                                            The user's selected
                                         "protected"=>false,                                                                                                           language.
                                         "followers_count"=>100581,
                                         "geo_enabled"=>true,                                                                                        Whether this user is protected
http://bit.ly/4pFY77).




                                         "notifications"=>false,     DEPRECATED
r this user has geo




                                                                                                                                                     or not. If the user is protected,
                                         "following"=>true,          in this context                                        Number of
                                                                                                                                                       then this tweet is not visible
                                         "verified"=>true},                               Whether this user                followers for
                                                                                                                                                            except to "friends".
                                       "contributors"=>[3191321],                       has a verified badge.                 this user.
                                       "geo"=>nil,
                                       "coordinates"=>nil,           DEPRECATED
                                       "place"=>                                                                            The contributors' (if any) user
The fields you really need
‣   id - the unique identifier for the status
‣   text - the content of the status update
‣   created_at - the date the status was created at
‣   user/id - the unique identifier for the status creator
‣   user/screen_name - the name of the status creator
‣   user/profile_image_url - the URL to the creator’s avatar
User objects
The “who”
Getting an user object
‣   You can do this with a screen name or an ID
‣   Construct the URL for users/show
‣   Grab it!
‣   (and, status objects do have embedded users)
Taking a look at @raffi
‣   Build the API URL
    ‣   http://api.twitter.com/1/users/show/raffi.xml
    ‣   http://api.twitter.com/1/users/show/raffi.json
    ‣   http://api.twitter.com/1/users/show.xml?
        user_id=8285392
    ‣   http://api.twitter.com/1/users/show.json?
        user_id=8285392
‣   Just fetch it!
Taking a look at user @raffi
[raffi@tw-mbp13-raffi Desktop]$ curl http://api.twitter.com/1/users/show/raffi.xml
<?xml version="1.0" encoding="UTF-8"?>
<user>
  <id>8285392</id>
  <name>raffi</name>
  <screen_name>raffi</screen_name>
  <location>San Francisco, California</location>
  <description>Tinkering, writing, engineering, and breaking things on the
@twitterapi.</description>
  <profile_image_url>http://a1.twimg.com/profile_images/364041028/raffi-headshot-
casual_normal.png</profile_image_url>
  <url>http://www.mehack.com/</url>
  <protected>false</protected>
  <followers_count>2862</followers_count>
  <profile_background_color>C0DEED</profile_background_color>
  <profile_text_color>333333</profile_text_color>
  <profile_link_color>0084B4</profile_link_color>
  <profile_sidebar_fill_color>DDEEF6</profile_sidebar_fill_color>
  <profile_sidebar_border_color>C0DEED</profile_sidebar_border_color>
  <friends_count>424</friends_count>
  <created_at>Sun Aug 19 14:24:06 +0000 2007</created_at>
  <favourites_count>45</favourites_count>
  <utc_offset>-28800</utc_offset>
  <time_zone>Pacific Time (US &amp; Canada)</time_zone>
The fields you really need
‣   id - the unique identifier for the user
‣   screen_name - the screen name of the user
‣   name - the name the user entered on his/her settings page
‣   profile_image_url - the URL to the creator’s avatar
‣   description - the description the user entered on his/her
    settings page
‣   url - the URL the user entered on his/her settings page
Timelines
Getting lots of tweets
Timelines
‣   “Arrays” or “lists” of Tweets
    ‣   in XML, wrapped with <statuses>...</statuses>
    ‣   in JSON, regular array [...]
‣   Sorted (mostly) chronologically (hence “timeline”)
‣   When statuses are created in the system, they are fanned-out to
    timelines
Few different timelines for the user
‣   user_timeline - all the tweets you created
‣   friends_timeline - all the tweets that people you follow have
    created (sans native RTs)
‣   home_timeline - next generation friends_timeline in that it
    contains native RTs
‣   mentions - all tweets that @mention you


‣   Some don’t require authentication and some do
Taking a look at @raffi’s user_timeline
[raffi@tw-mbp13-raffi twurl (master)]$ curl http://api.twitter.com/1/statuses/
user_timeline/raffi.xml
<?xml version="1.0" encoding="UTF-8"?>
<statuses type="array">
<status>
  <created_at>Tue May 11 02:24:33 +0000 2010</created_at>
  <id>13763485927</id>
  <text>@precipice woot!</text>
  <source>web</source>
  <truncated>false</truncated>
  <in_reply_to_status_id>13763157270</in_reply_to_status_id>
  <in_reply_to_user_id>236</in_reply_to_user_id>
  <favorited>false</favorited>
  <in_reply_to_screen_name>precipice</in_reply_to_screen_name>
  <user>
    <id>8285392</id>
    <name>raffi</name>
    <screen_name>raffi</screen_name>
    <location>San Francisco, California</location>
    <description>Tinkering, writing, engineering, and breaking things on the
@twitterapi.</description>
    <profile_image_url>http://a1.twimg.com/profile_images/364041028/raffi-headshot-
casual_normal.png</profile_image_url>
    <url>http://www.mehack.com/</url>
Using skip_user to save bandwidth
‣   Only user/id - have to lookup user data through other means
[raffi@tw-mbp13-raffi twurl (master)]$ curl http://api.twitter.com/1/statuses/
user_timeline/raffi.xml?skip_user=true
<?xml version="1.0" encoding="UTF-8"?>
<statuses type="array">
<status>
  <created_at>Tue May 11 02:24:33 +0000 2010</created_at>
  <id>13763485927</id>
  <text>@precipice woot!</text>
  <source>web</source>
  <truncated>false</truncated>
  <in_reply_to_status_id>13763157270</in_reply_to_status_id>
  <in_reply_to_user_id>236</in_reply_to_user_id>
  <favorited>false</favorited>
  <in_reply_to_screen_name>precipice</in_reply_to_screen_name>
  <user>
    <id>8285392</id>
  </user>
  <geo/>
  <coordinates/>
  <place xmlns:georss="http://www.georss.org/georss">
    <id>ece7b97d252718cc</id>
POSTing to the API
Causing change
Tweeting
Letting the world know your thoughts
status/update
‣   Just POST with a status parameter - that’s it!
[raffi@tw-mbp13-raffi twurl (master)]$ ./bin/twurl -d "status=hey ho" /statuses/
update.xml
<?xml version="1.0" encoding="UTF-8"?>
<status>
  <created_at>Tue May 11 03:39:42 +0000 2010</created_at>
  <id>13767250371</id>
  <text>hey ho</text>
  <source>&lt;a href=&quot;http://www.mehack.com&quot;
rel=&quot;nofollow&quot;&gt;Background image uploading example&lt;/a&gt;</source>
  <truncated>false</truncated>
  <in_reply_to_status_id></in_reply_to_status_id>
  <in_reply_to_user_id></in_reply_to_user_id>
  <favorited>false</favorited>
  <in_reply_to_screen_name></in_reply_to_screen_name>
  <user>
    <id>8307492</id>
    <name>raffibot</name>
    <screen_name>raffibot</screen_name>
    <location>Doing the robot!</location>
    <description></description>
    <profile_image_url>http://a3.twimg.com/profile_images/637865751/
Following people
Subscribing to people to get content
friendships/create
‣   Just POST with a id parameter
[raffi@tw-mbp13-raffi twurl (master)]$ ./bin/twurl -d "id=3191321" /friendships/
create.xml
<?xml version="1.0" encoding="UTF-8"?>
<user>
  <id>3191321</id>
  <name>Marcel Molina</name>
  <screen_name>noradio</screen_name>
  <location>San Francisco, CA</location>
  <description>Engineer at Twitter on the @twitterapi team obsessed with running. In a
past life I was a member of the Rails Core team &amp; 37signals.</description>
  <profile_image_url>http://a3.twimg.com/profile_images/53473799/marcel-euro-rails-
conf_normal.jpg</profile_image_url>
  <url>http://project.ioni.st</url>
  <protected>false</protected>
  <followers_count>288034</followers_count>
  <profile_background_color>9AE4E8</profile_background_color>
  <profile_text_color>333333</profile_text_color>
  <profile_link_color>0084B4</profile_link_color>
  <profile_sidebar_fill_color>DDFFCC</profile_sidebar_fill_color>
  <profile_sidebar_border_color>BDDCAD</profile_sidebar_border_color>
  <friends_count>494</friends_count>
DMing people
Tweeting to one, instead of tweeting to many
direct_messages/new
‣   Just POST with a text and user parameter
[raffi@tw-mbp13-raffi twurl (master)]$ ./bin/twurl -d "text=yo&user=raffi" /
direct_messages/new.xml
<?xml version="1.0" encoding="UTF-8"?>
<direct_message>
  <id>1118562319</id>
  <sender_id>8307492</sender_id>
  <text>yo</text>
  <recipient_id>8285392</recipient_id>
  <created_at>Tue May 11 03:53:25 +0000 2010</created_at>
  <sender_screen_name>raffibot</sender_screen_name>
  <recipient_screen_name>raffi</recipient_screen_name>
  <sender>
    <id>8307492</id>
    <name>raffibot</name>
    <screen_name>raffibot</screen_name>
    <location>Doing the robot!</location>
    <description></description>
    <profile_image_url>http://a3.twimg.com/profile_images/637865751/
raffibot_normal.jpg</profile_image_url>
    <url></url>
    <protected>false</protected>
Search API
Sifting through large amounts of Tweets
Search API
‣   History
    ‣   Summize was purchased in 2008
    ‣   built their own real-time search engine
‣   Still a separate system from main Twitter stack
    ‣   separate database and indices (only goes back 10-14 days)
    ‣   different representations of data
        ‣   different overall status object
        ‣   different user IDs
        ‣   different output formats (Atom, instead of XML, and JSON)
‣   Search is a corpus of best quality Tweets
Running a simple query
‣   Just GET with a q parameter
[raffi@tw-mbp13-raffi Desktop]$ curl "http://search.twitter.com/search.atom?q=twitter"
<?xml version="1.0" encoding="UTF-8"?>
<feed xmlns:google="http://base.google.com/ns/1.0" xml:lang="en-US"
xmlns:openSearch="http://a9.com/-/spec/opensearch/1.1/" xmlns="http://www.w3.org/2005/
Atom" xmlns:twitter="http://api.twitter.com/">
  <id>tag:search.twitter.com,2005:search/twitter</id>
  <link type="text/html" href="http://search.twitter.com/search?q=twitter"
rel="alternate"/>
  <link type="application/atom+xml" href="http://search.twitter.com/search.atom?
q=twitter" rel="self"/>
  <title>twitter - Twitter Search</title>
  <link type="application/opensearchdescription+xml" href="http://search.twitter.com/
opensearch.xml" rel="search"/>
  <link type="application/atom+xml" href="http://search.twitter.com/search.atom?
q=twitter&amp;since_id=15865967471" rel="refresh"/>
  <twitter:warning>since_id removed for pagination.</twitter:warning>
  <updated>2010-06-10T17:33:47Z</updated>
  <openSearch:itemsPerPage>15</openSearch:itemsPerPage>
  <link type="application/atom+xml" href="http://search.twitter.com/search.atom?
max_id=15865967471&amp;page=2&amp;q=twitter" rel="next"/>
  <entry>
Advanced operators
‣   from - restrict results to tweets from a particular screen name
‣   result_type=popular - find both “best” tweets and temporally
    relevant tweets
‣   Textual operators
    ‣   OR to combine queries - http://search.twitter.com/
        search.atom?q=san+francisco
    ‣   - to negate - http://search.twitter.com/
        search.atom?q=san+francisco+-from%3Araffi
What @raffi usually does
‣   Use the web interface on search.twitter.com to construct the
    query
‣   Tweak it and shorten it
‣   Switch the result format to be in API compatible format
‣   Use that!
Intro to developing for @twitterapi (updated)
Intro to developing for @twitterapi (updated)
Trim down the URL
‣   http://search.twitter.com/search?
    q=&ands=twitter&phrase=&ors=&nots=&tag=&lang=all&from=raf
    fi&to=&ref=&near=&within=15&units=mi&since=&until=&rpp=15
‣   Strip down to only where our custom data is
    ‣   ands - where the query is
    ‣   from - restrict it to @raffi
    ‣   make the format atom to get an API friendly response
‣   http://search.twitter.com/search.atom?
    ands=twitter&from=raffi
Running the custom query
[raffi@tw-mbp13-raffi Desktop]$ curl "http://search.twitter.com/search.atom?
ands=twitter&from=raffi"
<?xml version="1.0" encoding="UTF-8"?>
<feed xmlns:google="http://base.google.com/ns/1.0" xml:lang="en-US"
xmlns:openSearch="http://a9.com/-/spec/opensearch/1.1/" xmlns="http://www.w3.org/2005/
Atom" xmlns:twitter="http://api.twitter.com/">
  <id>tag:search.twitter.com,2005:search/ twitter from:raffi</id>
  <link type="text/html" href="http://search.twitter.com/search?q=+twitter+from
%3Araffi" rel="alternate"/>
  <link type="application/atom+xml" href="http://search.twitter.com/search.atom?
ands=twitter&amp;from=raffi" rel="self"/>
  <title> twitter from:raffi - Twitter Search</title>
  <link type="application/opensearchdescription+xml" href="http://search.twitter.com/
opensearch.xml" rel="search"/>
  <link type="application/atom+xml" href="http://search.twitter.com/search.atom?
ands=twitter&amp;from=raffi&amp;since_id=15859958051" rel="refresh"/>
  <updated>2010-06-07T19:20:18Z</updated>
  <openSearch:itemsPerPage>15</openSearch:itemsPerPage>
  <entry>
    <id>tag:search.twitter.com,2005:15650598318</id>
    <published>2010-06-07T19:20:18Z</published>
    <link type="text/html" href="http://twitter.com/raffi/statuses/15650598318"
rel="alternate"/>
    <title>RT @rsarver: here for #WWDC? We're having an informal apple dev meetup at
Streaming API
I need it now, now, now, now, now
Streaming API
‣   Maintain a persistent connection to         servers
‣   Get pushed a tweet that matches your predicate in “real-time”
‣   Most useful for server to server integrations
‣   Beginning to experiment with server to client integrations
Get a sample of all the tweets
‣   Use curl for a really simple proof-of-concept client
‣   http://stream.twitter.com/1/statuses/
    sample.xml
‣   Requires basic authorization (username and password)
‣   Only one connection per username
Get the tweets from certain users
‣   http://stream.twitter.com/1/statuses/
    filter.xml
‣   Can pass in a list of user IDs
    ‣   up to 400 users (passed as follow with CSV IDs)
    ‣   get their tweets as they are getting created
Get the tweets containing a certain word
‣   http://stream.twitter.com/1/statuses/
    filter.xml
‣   Can pass in a list of words
    ‣   up to 200 users (passed as track with CSV IDs)
    ‣   e.g. Twitter will match TWITTER, twitter, “Twitter”, twitter.,
        #twitter, and @twitter
    ‣   get tweets as they are getting created
Questions?   Follow me at
             twitter.com/raffi




                           TM

More Related Content

KEY
What's happening here?
PDF
Developing for @twitterapi #hack4health
PDF
Developing for @twitterapi (Techcrunch Disrupt Hackathon)
KEY
Rails 3 and OAuth for Barcamp Tampa
PPTX
API Design - 3rd Edition
PDF
Twitter APIs for #MediaHackday
PDF
Twitter4R OAuth
PPT
Spring 2.0
What's happening here?
Developing for @twitterapi #hack4health
Developing for @twitterapi (Techcrunch Disrupt Hackathon)
Rails 3 and OAuth for Barcamp Tampa
API Design - 3rd Edition
Twitter APIs for #MediaHackday
Twitter4R OAuth
Spring 2.0

What's hot (20)

KEY
OAuth Introduction
KEY
Building @Anywhere (for TXJS)
PDF
Connecting to the Pulse of the Planet with the Twitter Platform
PDF
Seoptimizing
PPTX
Web application security for java (XSS,Session Fixation)
PDF
Building Twitter's SDKs for Android
PDF
OAuth Hacks A gentle introduction to OAuth 2 and Apache Oltu
PDF
Writing Secure Code for WordPress
PPT
Mashups & APIs
PPTX
UC2013 Speed Geeking: Intro to OAuth2
PDF
Securing WordPress
PDF
Kiran karnad rtc2014 ghdb-final
PDF
Использование социальных сетей и микроблогов для бизнеса
PPTX
Recommended material components : Android Bangkok 2019
PDF
Open social for science a sciverse primer - mysimplesearch
PPTX
SgCodeJam24 Workshop
PPTX
SgCodeJam24 Workshop Extract
PDF
OAuth2 in simple words
PDF
PDF
Training and Face Recognition in 5 Easy Steps with VisageCloud
OAuth Introduction
Building @Anywhere (for TXJS)
Connecting to the Pulse of the Planet with the Twitter Platform
Seoptimizing
Web application security for java (XSS,Session Fixation)
Building Twitter's SDKs for Android
OAuth Hacks A gentle introduction to OAuth 2 and Apache Oltu
Writing Secure Code for WordPress
Mashups & APIs
UC2013 Speed Geeking: Intro to OAuth2
Securing WordPress
Kiran karnad rtc2014 ghdb-final
Использование социальных сетей и микроблогов для бизнеса
Recommended material components : Android Bangkok 2019
Open social for science a sciverse primer - mysimplesearch
SgCodeJam24 Workshop
SgCodeJam24 Workshop Extract
OAuth2 in simple words
Training and Face Recognition in 5 Easy Steps with VisageCloud
Ad

Viewers also liked (20)

PPT
Earned value management lecture 2009e my31
TXT
user: Roo-user-Ob-PicklistMulti-Value-minimal uploder
PDF
2011 Chevrolet Silverado 3500 HD - Jack Burford Chevrolet Richmond, KY
PDF
Vesmír 11-2013
PPT
关于 Twitter 以及 Twitter 与 NGO2.0
PPT
Presentations tips
TXT
Freefixer log
PDF
205180 cm with jde
PDF
Rd1 02 comunicacao
PDF
Browsers with Wings
PPTX
Grm 201 project
PDF
Fatecs 20102 provas
TXT
Gwiiyomi lyric
DOCX
Sekolah kebangsaan jalan raja syed alwi
PDF
Jeffrey Sachs
PPTX
The Building Blocks of Great Video
PDF
2.a OPTIMIZATION CHARACTERIZATION OF JEC ABSORBED COMPOUNDS IN LACTATING RATS...
DOC
Boards part 4_review
PDF
Las Vegas - July 2008, Travel Digest
Earned value management lecture 2009e my31
user: Roo-user-Ob-PicklistMulti-Value-minimal uploder
2011 Chevrolet Silverado 3500 HD - Jack Burford Chevrolet Richmond, KY
Vesmír 11-2013
关于 Twitter 以及 Twitter 与 NGO2.0
Presentations tips
Freefixer log
205180 cm with jde
Rd1 02 comunicacao
Browsers with Wings
Grm 201 project
Fatecs 20102 provas
Gwiiyomi lyric
Sekolah kebangsaan jalan raja syed alwi
Jeffrey Sachs
The Building Blocks of Great Video
2.a OPTIMIZATION CHARACTERIZATION OF JEC ABSORBED COMPOUNDS IN LACTATING RATS...
Boards part 4_review
Las Vegas - July 2008, Travel Digest
Ad

Similar to Intro to developing for @twitterapi (updated) (20)

PDF
Intro to developing for @twitterapi
PDF
Map-of-a-tweet
PPT
Coalmine spie 2012 presentation - jsw -d3
PDF
Programming to the Twitter API: ReTweeter
PDF
Twitter Meetup at the Hacker Dojo
PDF
@twitterapi at SocialApp Workshop
PDF
iPhoneアプリのTwitter連携
PPTX
HATEOAS 101 - Opinionated Introduction to a REST API Style
PPTX
Development of Twitter Application #1 - Overview
PPT
A Journo's Intro to Twitter
PDF
500Startups @ Twitter
PDF
Twitter Protobufs And Hadoop Hug 021709
PDF
20130504 - FeWeb - Twitter API
PDF
Twitter 研究会2012-1-28 - Twitter APIの紹介
DOC
GO TO GATZ: Twitter Dictionary
PPTX
Twitter API, Streaming and SharePoint 2013
PPT
what is-twitter
PDF
Data exchange formats
PDF
Twitter for CS10 @ Berkeley (Spring 2011)
PPTX
Mz twitter-1.1-sdl
Intro to developing for @twitterapi
Map-of-a-tweet
Coalmine spie 2012 presentation - jsw -d3
Programming to the Twitter API: ReTweeter
Twitter Meetup at the Hacker Dojo
@twitterapi at SocialApp Workshop
iPhoneアプリのTwitter連携
HATEOAS 101 - Opinionated Introduction to a REST API Style
Development of Twitter Application #1 - Overview
A Journo's Intro to Twitter
500Startups @ Twitter
Twitter Protobufs And Hadoop Hug 021709
20130504 - FeWeb - Twitter API
Twitter 研究会2012-1-28 - Twitter APIの紹介
GO TO GATZ: Twitter Dictionary
Twitter API, Streaming and SharePoint 2013
what is-twitter
Data exchange formats
Twitter for CS10 @ Berkeley (Spring 2011)
Mz twitter-1.1-sdl

More from Raffi Krikorian (20)

PDF
Hacking Conway's Law
PDF
Re-architecting on the Fly #OReillySACon
PDF
Real-time systems at Twitter (Velocity 2012)
PDF
Twitter: Engineering for Real-Time (Stanford ACM 2011)
PDF
Securing Your Ecosystem (FOWA Las Vegas 2011)
PDF
#rtgeo (Where 2.0 2011)
PDF
Twitter by the Numbers (Columbia University)
KEY
Users and Geo
PDF
Twitter and the Real-Time Web
PDF
Twitter - Guest Lecture UC Berkeley CS10 Fall 2010
PDF
Twitter by the Numbers
PDF
How to use Geolocation in your webapp @ FOWA Dublin 2010
KEY
Twitter API Annotations
KEY
"What's Happening" to "What's Happening Here" @ Chirp
KEY
Energy / Tweet
KEY
Handling Real-time Geostreams
KEY
Adding the "Where" to the "When"
PDF
WattzOn @ ETech 2009
PDF
Scala + WattzOn, sitting in a tree....
PDF
WattzOn Whole Earth Simulator
Hacking Conway's Law
Re-architecting on the Fly #OReillySACon
Real-time systems at Twitter (Velocity 2012)
Twitter: Engineering for Real-Time (Stanford ACM 2011)
Securing Your Ecosystem (FOWA Las Vegas 2011)
#rtgeo (Where 2.0 2011)
Twitter by the Numbers (Columbia University)
Users and Geo
Twitter and the Real-Time Web
Twitter - Guest Lecture UC Berkeley CS10 Fall 2010
Twitter by the Numbers
How to use Geolocation in your webapp @ FOWA Dublin 2010
Twitter API Annotations
"What's Happening" to "What's Happening Here" @ Chirp
Energy / Tweet
Handling Real-time Geostreams
Adding the "Where" to the "When"
WattzOn @ ETech 2009
Scala + WattzOn, sitting in a tree....
WattzOn Whole Earth Simulator

Recently uploaded (20)

PPTX
A Presentation on Artificial Intelligence
PDF
Approach and Philosophy of On baking technology
PDF
Dropbox Q2 2025 Financial Results & Investor Presentation
PPTX
MYSQL Presentation for SQL database connectivity
PPTX
KOM of Painting work and Equipment Insulation REV00 update 25-dec.pptx
PDF
Unlocking AI with Model Context Protocol (MCP)
PDF
Machine learning based COVID-19 study performance prediction
PDF
Blue Purple Modern Animated Computer Science Presentation.pdf.pdf
PDF
Assigned Numbers - 2025 - Bluetooth® Document
PDF
Building Integrated photovoltaic BIPV_UPV.pdf
PDF
Empathic Computing: Creating Shared Understanding
PPTX
ACSFv1EN-58255 AWS Academy Cloud Security Foundations.pptx
PDF
Agricultural_Statistics_at_a_Glance_2022_0.pdf
PDF
Review of recent advances in non-invasive hemoglobin estimation
PPTX
20250228 LYD VKU AI Blended-Learning.pptx
PPTX
Cloud computing and distributed systems.
PDF
Build a system with the filesystem maintained by OSTree @ COSCUP 2025
PDF
Chapter 3 Spatial Domain Image Processing.pdf
PDF
Diabetes mellitus diagnosis method based random forest with bat algorithm
PDF
NewMind AI Weekly Chronicles - August'25-Week II
A Presentation on Artificial Intelligence
Approach and Philosophy of On baking technology
Dropbox Q2 2025 Financial Results & Investor Presentation
MYSQL Presentation for SQL database connectivity
KOM of Painting work and Equipment Insulation REV00 update 25-dec.pptx
Unlocking AI with Model Context Protocol (MCP)
Machine learning based COVID-19 study performance prediction
Blue Purple Modern Animated Computer Science Presentation.pdf.pdf
Assigned Numbers - 2025 - Bluetooth® Document
Building Integrated photovoltaic BIPV_UPV.pdf
Empathic Computing: Creating Shared Understanding
ACSFv1EN-58255 AWS Academy Cloud Security Foundations.pptx
Agricultural_Statistics_at_a_Glance_2022_0.pdf
Review of recent advances in non-invasive hemoglobin estimation
20250228 LYD VKU AI Blended-Learning.pptx
Cloud computing and distributed systems.
Build a system with the filesystem maintained by OSTree @ COSCUP 2025
Chapter 3 Spatial Domain Image Processing.pdf
Diabetes mellitus diagnosis method based random forest with bat algorithm
NewMind AI Weekly Chronicles - August'25-Week II

Intro to developing for @twitterapi (updated)

  • 1. Developing with @twitterapi TM 10 June 2010
  • 2. giving a talk abouttalk at @chirp entitled an @ignite coding against the @twitterapi "energy / tweet". about 2 minutes ago via mobile web from Y-Combinator San Francisco Fort Mason,
  • 3. What is ? How to use the Twitter Platform
  • 4. What is ? ‣ REST API ‣ provides the “basic” functionality - tweet, follow, etc. ‣ all functions available on your timeline on twitter.com ‣ Search API ‣ real-time search index ‣ get “top tweets” / relevant search results ‣ Streaming API ‣ HTTP long-poll connection ‣ tweets come out of the system in real-time
  • 5. Tools of the trade ‣ dev.twitter.com ‣ documentation center ‣ API console for quick testing and exploration ‣ curl and a web browser ‣ testing unauthenticated endpoints ‣ CLI to get a raw dump of the interaction ‣ twurl ‣ OAuth-enabled version of curl
  • 6. Authenticating to ‣ OAuth 1.0a ‣ signing “write” requests ‣ give visibility into the stack ‣ Applications don’t have a user’s username / password ‣ user can change password at any time ‣ user is secure in knowing his/her password not being stored outside of ‣ user can revoke permissions to app at any time
  • 7. Libraries ‣ PHP - http://github.com/abraham/twitteroauth ‣ Java - http://github.com/fernandezpablo85/scribe ‣ Ruby - http://oauth.rubyforge.org/ ‣ C / C++ - http://liboauth.sourceforge.net/ ‣ Actionscript / Flash - http://code.google.com/p/oauth-as3/
  • 8. twurl ‣ http://github.com/marcel/twurl ‣ Command line tool to interact with using OAuth ‣ Transparently handles OAuth signing against ‣ authorize against to get access tokens ‣ from there on out, all requests are signed
  • 9. Limits ‣ 350 API calls/hour using OAuth against api.twitter.com ‣ unauthenticated it goes against the source IP address ‣ authenticated it goes against the calling user ‣ “Natural” limits on ‣ number of tweets sent ‣ number of DMs sent ‣ number of followings / unfollowings ‣ Status limits ‣ can’t have duplicate tweets ‣ can’t have malware links in tweets
  • 11. Creating an app Your own small playground
  • 15. Using the console Interacting with @ for fun and profit
  • 22. GETing from the API Reading, reading, reading
  • 23. GETing from the API ‣ For most cases, completely wide open ‣ Can do a HTTP connect and a simple GET request ‣ “Protected” information may require authentication (covered later) ‣ getting the tweet of a protected user ‣ getting the timeline of a user
  • 24. Status objects The basis of everything
  • 25. Getting a status object ‣ Figure out the ID of the status objects ‣ Construct the URL for statuses/show ‣ Grab it!
  • 27. Taking a look at status 13762161921 ‣ Build the API URL ‣ http://api.twitter.com/1/statuses/show/ 13762161921.xml ‣ http://api.twitter.com/1/statuses/show/ 13762161921.json ‣ If it’s a public status, then just fetch it ‣ use a browser! ‣ use curl!
  • 28. Taking a look at status 13762161921 [raffi@tw-mbp13-raffi Desktop]$ curl http://api.twitter.com/1/statuses/show/ 13762161921.xml <?xml version="1.0" encoding="UTF-8"?> <status> <created_at>Tue May 11 01:58:56 +0000 2010</created_at> <id>13762161921</id> <text>...and another late night</text> <source>&lt;a href=&quot;http://mehack.com&quot; rel=&quot;nofollow&quot;&gt;@raffi's Test App&lt;/a&gt;</source> <truncated>false</truncated> <in_reply_to_status_id></in_reply_to_status_id> <in_reply_to_user_id></in_reply_to_user_id> <favorited>false</favorited> <in_reply_to_screen_name></in_reply_to_screen_name> <user> <id>8285392</id> <name>raffi</name> <screen_name>raffi</screen_name> <location>San Francisco, California</location> <description>Tinkering, writing, engineering, and breaking things on the @twitterapi.</description> <profile_image_url>http://a1.twimg.com/profile_images/364041028/raffi-headshot- casual_normal.png</profile_image_url> <url>http://www.mehack.com/</url>
  • 29. Dissecting a status object The tweet's unique ID. These Text of the tweet. IDs are roughly sorted & Consecutive duplicate tweets developers should treat them are rejected. 140 character as opaque (http://bit.ly/dCkppc). max (http://bit.ly/4ud3he). DEPRECATED {"id"=>12296272736, "text"=> "An early look at Annotations: http://groups.google.com/group/twitter-api-announce/browse_thread/thread/fa5da2608865453", Tweet's "created_at"=>"Fri Apr 16 17:55:46 +0000 2010", creation "in_reply_to_user_id"=>nil, The ID of an existing tweet that date. "in_reply_to_screen_name"=>nil, this tweet is in reply to. Won't "in_reply_to_status_id"=>nil be set unless the author of the The author's The screen name & "favorited"=>false, user ID. user ID of replied to referenced tweet is mentioned. "truncated"=>false, Truncated to 140 characters. Only tweet author. "user"=> possible from SMS. The author's {"id"=>6253282, user name. The author's "screen_name"=>"twitterapi", The author's biography. "name"=>"Twitter API", screen name. d object can get out of sync. "description"=> "The Real Twitter API. I tweet about API changes, service issues and uthor of the tweet. This happily answer questions about Twitter and our API. Don't get an answer? It's on my website.", "url"=>"http://apiwiki.twitter.com", The author's "location"=>"San Francisco, CA", URL. The author's "location". This is a free-form text field, and "profile_background_color"=>"c1dfee", there are no guarantees on whether it can be geocoded. "profile_background_image_url"=> "http://a3.twimg.com/profile_background_images/59931895/twitterapi-background-new.png", Rendering information "profile_background_tile"=>false, for the author. Colors "profile_image_url"=>"http://a3.twimg.com/profile_images/689684365/api_normal.png",
  • 30. The tweet's unique ID. These Text of the tweet. IDs are roughly sorted & Consecutive duplicate tweets developers should treat them are rejected. 140 character as opaque (http://bit.ly/dCkppc). max (http://bit.ly/4ud3he). DEPRECATED {"id"=>12296272736, "text"=> "An early look at Annotations: http://groups.google.com/group/twitter-api-announce/browse_thread/thread/fa5da2608865453", Tweet's "created_at"=>"Fri Apr 16 17:55:46 +0000 2010", creation "in_reply_to_user_id"=>nil, The ID of an existing tweet that date. "in_reply_to_screen_name"=>nil, this tweet is in reply to. Won't "in_reply_to_status_id"=>nil be set unless the author of the The author's The screen name & "favorited"=>false, user ID. user ID of replied to referenced tweet is mentioned. "truncated"=>false, Truncated to 140 characters. Only tweet author. "user"=> possible from SMS. The author's {"id"=>6253282, user name. The author's "screen_name"=>"twitterapi", The author's biography. "name"=>"Twitter API", screen name. get out of sync. "description"=> "The Real Twitter API. I tweet about API changes, service issues and tweet. This happily answer questions about Twitter and our API. Don't get an answer? It's on my website.", "url"=>"http://apiwiki.twitter.com", The author's "location"=>"San Francisco, CA", URL. The author's "location". This is a free-form text field, and
  • 31. "favorited"=>false, referenced tweet is mentioned. user ID user ID of replied to The auth "truncated"=>false, Truncated to 140 characters. Only tweet author. "user"=> possible from SMS. The author's {"id"=>6253282, user name. The author's "screen_name"=>"twitterapi", The author's biography. "name"=>"Twitter API", screen name. embedded object can get out of sync. "description"=> "The Real Twitter API. I tweet about API changes, service issues and The author of the tweet. This happily answer questions about Twitter and our API. Don't get an answer? It's on my website.", "url"=>"http://apiwiki.twitter.com", The author's "location"=>"San Francisco, CA", URL. The author's "location". This is a free-form text field, and "profile_background_color"=>"c1dfee", there are no guarantees on whether it can be geocoded. "profile_background_image_url"=> "http://a3.twimg.com/profile_background_images/59931895/twitterapi-background-new.png", Rendering information "profile_background_tile"=>false, for the author. Colors "profile_image_url"=>"http://a3.twimg.com/profile_images/689684365/api_normal.png", are encoded in hex "profile_link_color"=>"0000ff", values (RGB). "profile_sidebar_border_color"=>"87bc44", The creation date "profile_sidebar_fill_color"=>"e0ff92", for this account. "profile_text_color"=>"000000", Whether this account has "created_at"=>"Wed May 23 06:01:13 +0000 2007", contributors enabled "contributors_enabled"=>true, (http://bit.ly/50npuu). Number of Number of tweets "favourites_count"=>1, favorites this this user has. "statuses_count"=>1628, Number of user has. "friends_count"=>13, users this user "time_zone"=>"Pacific Time (US & Canada)", The timezone and offset is following. "utc_offset"=>-28800, (in seconds) for this user. "lang"=>"en", The user's selected "protected"=>false, language. "followers_count"=>100581, "geo_enabled"=>true, Whether this user is protected http://bit.ly/4pFY77). "notifications"=>false, DEPRECATED r this user has geo or not. If the user is protected, "following"=>true, in this context Number of then this tweet is not visible "verified"=>true}, Whether this user followers for except to "friends". "contributors"=>[3191321], has a verified badge. this user. "geo"=>nil, "coordinates"=>nil, DEPRECATED "place"=> The contributors' (if any) user
  • 32. The fields you really need ‣ id - the unique identifier for the status ‣ text - the content of the status update ‣ created_at - the date the status was created at ‣ user/id - the unique identifier for the status creator ‣ user/screen_name - the name of the status creator ‣ user/profile_image_url - the URL to the creator’s avatar
  • 34. Getting an user object ‣ You can do this with a screen name or an ID ‣ Construct the URL for users/show ‣ Grab it! ‣ (and, status objects do have embedded users)
  • 35. Taking a look at @raffi ‣ Build the API URL ‣ http://api.twitter.com/1/users/show/raffi.xml ‣ http://api.twitter.com/1/users/show/raffi.json ‣ http://api.twitter.com/1/users/show.xml? user_id=8285392 ‣ http://api.twitter.com/1/users/show.json? user_id=8285392 ‣ Just fetch it!
  • 36. Taking a look at user @raffi [raffi@tw-mbp13-raffi Desktop]$ curl http://api.twitter.com/1/users/show/raffi.xml <?xml version="1.0" encoding="UTF-8"?> <user> <id>8285392</id> <name>raffi</name> <screen_name>raffi</screen_name> <location>San Francisco, California</location> <description>Tinkering, writing, engineering, and breaking things on the @twitterapi.</description> <profile_image_url>http://a1.twimg.com/profile_images/364041028/raffi-headshot- casual_normal.png</profile_image_url> <url>http://www.mehack.com/</url> <protected>false</protected> <followers_count>2862</followers_count> <profile_background_color>C0DEED</profile_background_color> <profile_text_color>333333</profile_text_color> <profile_link_color>0084B4</profile_link_color> <profile_sidebar_fill_color>DDEEF6</profile_sidebar_fill_color> <profile_sidebar_border_color>C0DEED</profile_sidebar_border_color> <friends_count>424</friends_count> <created_at>Sun Aug 19 14:24:06 +0000 2007</created_at> <favourites_count>45</favourites_count> <utc_offset>-28800</utc_offset> <time_zone>Pacific Time (US &amp; Canada)</time_zone>
  • 37. The fields you really need ‣ id - the unique identifier for the user ‣ screen_name - the screen name of the user ‣ name - the name the user entered on his/her settings page ‣ profile_image_url - the URL to the creator’s avatar ‣ description - the description the user entered on his/her settings page ‣ url - the URL the user entered on his/her settings page
  • 39. Timelines ‣ “Arrays” or “lists” of Tweets ‣ in XML, wrapped with <statuses>...</statuses> ‣ in JSON, regular array [...] ‣ Sorted (mostly) chronologically (hence “timeline”) ‣ When statuses are created in the system, they are fanned-out to timelines
  • 40. Few different timelines for the user ‣ user_timeline - all the tweets you created ‣ friends_timeline - all the tweets that people you follow have created (sans native RTs) ‣ home_timeline - next generation friends_timeline in that it contains native RTs ‣ mentions - all tweets that @mention you ‣ Some don’t require authentication and some do
  • 41. Taking a look at @raffi’s user_timeline [raffi@tw-mbp13-raffi twurl (master)]$ curl http://api.twitter.com/1/statuses/ user_timeline/raffi.xml <?xml version="1.0" encoding="UTF-8"?> <statuses type="array"> <status> <created_at>Tue May 11 02:24:33 +0000 2010</created_at> <id>13763485927</id> <text>@precipice woot!</text> <source>web</source> <truncated>false</truncated> <in_reply_to_status_id>13763157270</in_reply_to_status_id> <in_reply_to_user_id>236</in_reply_to_user_id> <favorited>false</favorited> <in_reply_to_screen_name>precipice</in_reply_to_screen_name> <user> <id>8285392</id> <name>raffi</name> <screen_name>raffi</screen_name> <location>San Francisco, California</location> <description>Tinkering, writing, engineering, and breaking things on the @twitterapi.</description> <profile_image_url>http://a1.twimg.com/profile_images/364041028/raffi-headshot- casual_normal.png</profile_image_url> <url>http://www.mehack.com/</url>
  • 42. Using skip_user to save bandwidth ‣ Only user/id - have to lookup user data through other means [raffi@tw-mbp13-raffi twurl (master)]$ curl http://api.twitter.com/1/statuses/ user_timeline/raffi.xml?skip_user=true <?xml version="1.0" encoding="UTF-8"?> <statuses type="array"> <status> <created_at>Tue May 11 02:24:33 +0000 2010</created_at> <id>13763485927</id> <text>@precipice woot!</text> <source>web</source> <truncated>false</truncated> <in_reply_to_status_id>13763157270</in_reply_to_status_id> <in_reply_to_user_id>236</in_reply_to_user_id> <favorited>false</favorited> <in_reply_to_screen_name>precipice</in_reply_to_screen_name> <user> <id>8285392</id> </user> <geo/> <coordinates/> <place xmlns:georss="http://www.georss.org/georss"> <id>ece7b97d252718cc</id>
  • 43. POSTing to the API Causing change
  • 44. Tweeting Letting the world know your thoughts
  • 45. status/update ‣ Just POST with a status parameter - that’s it! [raffi@tw-mbp13-raffi twurl (master)]$ ./bin/twurl -d "status=hey ho" /statuses/ update.xml <?xml version="1.0" encoding="UTF-8"?> <status> <created_at>Tue May 11 03:39:42 +0000 2010</created_at> <id>13767250371</id> <text>hey ho</text> <source>&lt;a href=&quot;http://www.mehack.com&quot; rel=&quot;nofollow&quot;&gt;Background image uploading example&lt;/a&gt;</source> <truncated>false</truncated> <in_reply_to_status_id></in_reply_to_status_id> <in_reply_to_user_id></in_reply_to_user_id> <favorited>false</favorited> <in_reply_to_screen_name></in_reply_to_screen_name> <user> <id>8307492</id> <name>raffibot</name> <screen_name>raffibot</screen_name> <location>Doing the robot!</location> <description></description> <profile_image_url>http://a3.twimg.com/profile_images/637865751/
  • 46. Following people Subscribing to people to get content
  • 47. friendships/create ‣ Just POST with a id parameter [raffi@tw-mbp13-raffi twurl (master)]$ ./bin/twurl -d "id=3191321" /friendships/ create.xml <?xml version="1.0" encoding="UTF-8"?> <user> <id>3191321</id> <name>Marcel Molina</name> <screen_name>noradio</screen_name> <location>San Francisco, CA</location> <description>Engineer at Twitter on the @twitterapi team obsessed with running. In a past life I was a member of the Rails Core team &amp; 37signals.</description> <profile_image_url>http://a3.twimg.com/profile_images/53473799/marcel-euro-rails- conf_normal.jpg</profile_image_url> <url>http://project.ioni.st</url> <protected>false</protected> <followers_count>288034</followers_count> <profile_background_color>9AE4E8</profile_background_color> <profile_text_color>333333</profile_text_color> <profile_link_color>0084B4</profile_link_color> <profile_sidebar_fill_color>DDFFCC</profile_sidebar_fill_color> <profile_sidebar_border_color>BDDCAD</profile_sidebar_border_color> <friends_count>494</friends_count>
  • 48. DMing people Tweeting to one, instead of tweeting to many
  • 49. direct_messages/new ‣ Just POST with a text and user parameter [raffi@tw-mbp13-raffi twurl (master)]$ ./bin/twurl -d "text=yo&user=raffi" / direct_messages/new.xml <?xml version="1.0" encoding="UTF-8"?> <direct_message> <id>1118562319</id> <sender_id>8307492</sender_id> <text>yo</text> <recipient_id>8285392</recipient_id> <created_at>Tue May 11 03:53:25 +0000 2010</created_at> <sender_screen_name>raffibot</sender_screen_name> <recipient_screen_name>raffi</recipient_screen_name> <sender> <id>8307492</id> <name>raffibot</name> <screen_name>raffibot</screen_name> <location>Doing the robot!</location> <description></description> <profile_image_url>http://a3.twimg.com/profile_images/637865751/ raffibot_normal.jpg</profile_image_url> <url></url> <protected>false</protected>
  • 50. Search API Sifting through large amounts of Tweets
  • 51. Search API ‣ History ‣ Summize was purchased in 2008 ‣ built their own real-time search engine ‣ Still a separate system from main Twitter stack ‣ separate database and indices (only goes back 10-14 days) ‣ different representations of data ‣ different overall status object ‣ different user IDs ‣ different output formats (Atom, instead of XML, and JSON) ‣ Search is a corpus of best quality Tweets
  • 52. Running a simple query ‣ Just GET with a q parameter [raffi@tw-mbp13-raffi Desktop]$ curl "http://search.twitter.com/search.atom?q=twitter" <?xml version="1.0" encoding="UTF-8"?> <feed xmlns:google="http://base.google.com/ns/1.0" xml:lang="en-US" xmlns:openSearch="http://a9.com/-/spec/opensearch/1.1/" xmlns="http://www.w3.org/2005/ Atom" xmlns:twitter="http://api.twitter.com/"> <id>tag:search.twitter.com,2005:search/twitter</id> <link type="text/html" href="http://search.twitter.com/search?q=twitter" rel="alternate"/> <link type="application/atom+xml" href="http://search.twitter.com/search.atom? q=twitter" rel="self"/> <title>twitter - Twitter Search</title> <link type="application/opensearchdescription+xml" href="http://search.twitter.com/ opensearch.xml" rel="search"/> <link type="application/atom+xml" href="http://search.twitter.com/search.atom? q=twitter&amp;since_id=15865967471" rel="refresh"/> <twitter:warning>since_id removed for pagination.</twitter:warning> <updated>2010-06-10T17:33:47Z</updated> <openSearch:itemsPerPage>15</openSearch:itemsPerPage> <link type="application/atom+xml" href="http://search.twitter.com/search.atom? max_id=15865967471&amp;page=2&amp;q=twitter" rel="next"/> <entry>
  • 53. Advanced operators ‣ from - restrict results to tweets from a particular screen name ‣ result_type=popular - find both “best” tweets and temporally relevant tweets ‣ Textual operators ‣ OR to combine queries - http://search.twitter.com/ search.atom?q=san+francisco ‣ - to negate - http://search.twitter.com/ search.atom?q=san+francisco+-from%3Araffi
  • 54. What @raffi usually does ‣ Use the web interface on search.twitter.com to construct the query ‣ Tweak it and shorten it ‣ Switch the result format to be in API compatible format ‣ Use that!
  • 57. Trim down the URL ‣ http://search.twitter.com/search? q=&ands=twitter&phrase=&ors=&nots=&tag=&lang=all&from=raf fi&to=&ref=&near=&within=15&units=mi&since=&until=&rpp=15 ‣ Strip down to only where our custom data is ‣ ands - where the query is ‣ from - restrict it to @raffi ‣ make the format atom to get an API friendly response ‣ http://search.twitter.com/search.atom? ands=twitter&from=raffi
  • 58. Running the custom query [raffi@tw-mbp13-raffi Desktop]$ curl "http://search.twitter.com/search.atom? ands=twitter&from=raffi" <?xml version="1.0" encoding="UTF-8"?> <feed xmlns:google="http://base.google.com/ns/1.0" xml:lang="en-US" xmlns:openSearch="http://a9.com/-/spec/opensearch/1.1/" xmlns="http://www.w3.org/2005/ Atom" xmlns:twitter="http://api.twitter.com/"> <id>tag:search.twitter.com,2005:search/ twitter from:raffi</id> <link type="text/html" href="http://search.twitter.com/search?q=+twitter+from %3Araffi" rel="alternate"/> <link type="application/atom+xml" href="http://search.twitter.com/search.atom? ands=twitter&amp;from=raffi" rel="self"/> <title> twitter from:raffi - Twitter Search</title> <link type="application/opensearchdescription+xml" href="http://search.twitter.com/ opensearch.xml" rel="search"/> <link type="application/atom+xml" href="http://search.twitter.com/search.atom? ands=twitter&amp;from=raffi&amp;since_id=15859958051" rel="refresh"/> <updated>2010-06-07T19:20:18Z</updated> <openSearch:itemsPerPage>15</openSearch:itemsPerPage> <entry> <id>tag:search.twitter.com,2005:15650598318</id> <published>2010-06-07T19:20:18Z</published> <link type="text/html" href="http://twitter.com/raffi/statuses/15650598318" rel="alternate"/> <title>RT @rsarver: here for #WWDC? We're having an informal apple dev meetup at
  • 59. Streaming API I need it now, now, now, now, now
  • 60. Streaming API ‣ Maintain a persistent connection to servers ‣ Get pushed a tweet that matches your predicate in “real-time” ‣ Most useful for server to server integrations ‣ Beginning to experiment with server to client integrations
  • 61. Get a sample of all the tweets ‣ Use curl for a really simple proof-of-concept client ‣ http://stream.twitter.com/1/statuses/ sample.xml ‣ Requires basic authorization (username and password) ‣ Only one connection per username
  • 62. Get the tweets from certain users ‣ http://stream.twitter.com/1/statuses/ filter.xml ‣ Can pass in a list of user IDs ‣ up to 400 users (passed as follow with CSV IDs) ‣ get their tweets as they are getting created
  • 63. Get the tweets containing a certain word ‣ http://stream.twitter.com/1/statuses/ filter.xml ‣ Can pass in a list of words ‣ up to 200 users (passed as track with CSV IDs) ‣ e.g. Twitter will match TWITTER, twitter, “Twitter”, twitter., #twitter, and @twitter ‣ get tweets as they are getting created
  • 64. Questions? Follow me at twitter.com/raffi TM