/
/index.shtml
  1 <?xml version="1.0"?>
  2 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
  3     "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
  4 <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
  5 <head>
  6   <title><!--#include virtual="project-name" --></title>
  7   <link rel="stylesheet" type="text/css" href="style.css"/>
  8   <meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1"/>
  9 </head>
 10 
 11 <body>
 12  <div class="header">
 13    <h1><!--#include virtual="project-name" --></h1>
 14  </div>
 15 
 16 <h3>About</h3>
 17 
 18 <p>This is a simple interface to the <a href="http://apiwiki.twitter.com/REST+API+Documentation">Twitter API</a> written by Ian Eslick.  It also implements the <a href="http://apiwiki.twitter.com/Search+API+Documentation">Search API</a> and provides a <a href="http://tinyurl.com/">tinyurl</a> mapping API and the REPL interface performs automatic conversions to tiny urls.  The library is currently only available via darcs.</p>
 19 
 20 <code>darcs get http://www.common-lisp.net/project/cl-twitter/darcs/cl-twitter</code><br><br>
 21 
 22 I will be putting a tarball up on cliki for asdf-install after it's had some more exercise.  There are at least two other libraries out there that came out literally on the same day as I posted this to cl.net.  <a href="http://chaitanyagupta.com/lisp/cl-twit/">'<code>cl-twit</code>'</a> by Chaitanya Gupta and <a href="http://seashellsandxml.co.uk/code/">'<code>cl-twitter</code></a>' by <a href="http://seashellsandxml.co.uk/">Chris Davies</a>.  With permission of the author, I reproduced most of the cl-twit REPL API in the latest patch as well as used his tinyurl function.
 23 
 24 <h3>Loading cl-twitter</h3>
 25 
 26 <p>cl-twitter depends on: cl-json, drakma, trivial-http, anaphora and cl-ppcre
 27 
 28 <p><code>(asdf:oos 'asdf:load-op :cl-twitter)</code> -> Creates package <code>:twitter</code>
 29 <h3>API for the REPL</h3>
 30 
 31 
 32 <h3>Authentication</h3>
 33 
 34 <p>Most API commands require an authenticating user.  An
 35 authenticating user (with valid username & password slots) can be
 36 passed to a command using the <code>:user</code> option.  There is a convenience
 37 function authenticate-user which takes a username and password,
 38 creates and populates a user object (if authentication works) and sets
 39 a global variable <code>*twitter-user*</code> which will be used to
 40 authenticate calls by default.  The <code>:user</code> option overrides the default
 41 parameter.
 42 
 43 <h3>User-level REPL API</h3>
 44 
 45 <p>There is a nice set of interactive routines for use at the REPL.  Each command prints the return values directly, then returns a set of internal objects represneting the full details of each reply.  You can use 'describe' on any element to see key fields.
 46 
 47 <pre>
 48 (public-timeline)            ;; public timeline
 49 
 50 ;; User specific commands
 51 (authenticate-user screen-name password) ;; will set the default user if valid
 52 (timeline)            ;; timeline for current authenticated user or use :id keyword argument
 53 (friends-timeline)    ;; full timeline including friends tweets
 54 (send-tweet text)     ;; will post a tweet / status update for the current user
 55 (update text)         ;; alias for send-tweet
 56 
 57 ;; Replies
 58 (reply-to tweet text) ;; Send a reply
 59 (@reply-to tweet text) ;; Send a reply, but prepend @username to text
 60 
 61 ;; Messages
 62 (messages)            ;; Your messages
 63 (send-message user message) ;; Send a message
 64 (sent-messages)       ;; Messages you've sent
 65 </pre>
 66 
 67 <p>Example run:
 68 
 69 <pre>
 70 TWITTER&gt; (authenticate-user "username" "password")
 71 #&lt;TWITTER-USER 'ieslick'&gt;
 72 
 73 TWITTER&gt; (user-timeline)
 74 status: "The lisp twitter api is nearly done!"
 75 by: First Last (username) on: Tue Feb 17 00:49:11 +0000 2009
 76 
 77 status: "Benefits of working from home; lunchtime stew in Cambridge, MA http://loopt.us/-Hps2Q"
 78 by: First Last (username) on: Mon Feb 16 17:49:52 +0000 2009
 79 
 80 status: "My lisp can tweet!"
 81 by: First Last (username) on: Mon Feb 16 04:52:28 +0000 2009
 82 
 83 status: "Family outing! in Cambridge, MA http://loopt.us/zUhMpQ"
 84 by: First Last (username) on: Sun Feb 15 21:14:26 +0000 2009
 85 
 86 (#&lt;TWEET 'username' id:1219635898&gt; #&lt;TWEET 'username' id:1217269236&gt;
 87  #&lt;TWEET 'username' id:1215984895&gt; #&lt;TWEET 'username' id:1214353382&gt;)
 88 
 89 TWITTER&gt; (print-tweets *)
 90 status: "The lisp twitter api is nearly done!"
 91 by: First Last (username) on: Tue Feb 17 00:49:11 +0000 2009
 92 
 93 status: "Benefits of working from home; lunchtime stew in Cambridge, MA http://loopt.us/-Hps2Q"
 94 by: First Last (username) on: Mon Feb 16 17:49:52 +0000 2009
 95 
 96 status: "My lisp can tweet!"
 97 by: First Last (username) on: Mon Feb 16 04:52:28 +0000 2009
 98 
 99 status: "Family outing! in Cambridge, MA http://loopt.us/zUhMpQ"
100 by: First Last (username) on: Sun Feb 15 21:14:26 +0000 2009
101 
102 TWITTER&gt; (send-tweet "cl-twitter is released!")
103 #&lt;TWEET 'username' id:1219635898&gt;
104 
105 TWITTER&gt; (describe *)
106 by: usernam (First Last) created: Tue Feb 17 17:33:33 +0000 2009
107 msg: cl-twitter is released!
108 ; No value
109 </pre>
110 
111 <H3>Search API</h3>
112 
113 The search API returns a 'search-result element which contains a set
114 of 'search-ref elements accessible via (search-result-results elt)
115 
116 <pre>
117 (do-search "query string" &rest args) ;; is a shortcut for
118    (twitter-op :search :q "query string" &rest args)
119    ;; and returns two values: the list of refs and the 'search-result elt.
120 
121 (twitter-trends)  ;; returns the top 20 twitter search trends
122 
123 ;; Can also directly do tinyurl conversions
124 (get-tinyurl "url")
125 </pre>
126 
127 Example use:
128 
129 <pre>
130 TWITTER&gt; (twitter-search "#lisp")
131 (#&lt;TWITTER-SEARCH-REF 'kotrit'&gt; #&lt;TWITTER-SEARCH-REF 'gibsonf1'&gt;
132  #&lt;TWITTER-SEARCH-REF 'dhess'&gt; #&lt;TWITTER-SEARCH-REF 'baphled'&gt;
133  #&lt;TWITTER-SEARCH-REF 'TheSeth26'&gt; #&lt;TWITTER-SEARCH-REF 'cdeger'&gt;
134  #&lt;TWITTER-SEARCH-REF 'taphon'&gt; #&lt;TWITTER-SEARCH-REF 'dhess'&gt;
135  #&lt;TWITTER-SEARCH-REF 'dhess'&gt; #&lt;TWITTER-SEARCH-REF 'yonkeltron'&gt;
136  #&lt;TWITTER-SEARCH-REF 'steveportigal'&gt; #&lt;TWITTER-SEARCH-REF 'duck1123'&gt;
137  #&lt;TWITTER-SEARCH-REF 'edgargoncalves'&gt; #&lt;TWITTER-SEARCH-REF 'edgargoncalves'&gt;
138  #&lt;TWITTER-SEARCH-REF 'adam_houston'&gt;)
139 #&lt;TWITTER-SEARCH '%23lisp'&gt;
140 TWITTER&gt; (mapcar #'search-ref-text *)
141  ("Luckily Slime takes care of most of the formatting quite nicely - RT @dhess Riastradh's Lisp style rules #lisp http://tinyurl.com/2onk5x"
142  "Riastradh's Lisp style rules #lisp http://tinyurl.com/2onk5x"
143  "I really need to learn #LISP one day" "Why macros over functions?? #lisp"
144  "Ich will Clojure fr .NET! Dynamisch, funktional, STM eingebaut, schnell: http://bit.ly/4qX28T #lisp #jvm"
145  "What's a good ide for #Lisp, any good books on the language written recently?"
146  "Technical issues re: Lisp-1 vs. Lisp-2 #pl #lisp http://tinyurl.com/2kh96k"
147  "What Common Lisp conditions (exceptions) are really about #lisp http://tinyurl.com/8r5yeh"
148  "@theseth26 the folks in #emacs on freenode are often less snippy than the folks on #lisp. i lurk there, will talk. hack strong and prosper!"
149  "@joshdamon I'm tempted to call it twethival #lisp"
150  "@horseman !stumpwm is the window manager for #emacs and #screen users. It's all keyboard commands, and written in common #lisp"
151  "Drawing a tree graph of my objects and their slots, in #lisp. looking for the easier way to do it. feel free to drop tips and hints."
152  "Finished a functional webapp server with offline work support. Serialized proxies fly over http between two #lisp servers, works well."
153  "Too bad we are moving to an integrated system though. Really wanted to rewrite the whole thing in #Lisp one of these days. Or maybe #Python.")
154 </pre>
155 
156 <h2>Error Handling</h2>
157 
158 <p>Any API call errors throw a <code>twitter-api-condition</code>
159 which provides the return code and short and long code messages.  It
160 also provides the failing URI and the specific server message.  The
161 accessors are not exported to avoid conflicts, but the slotnames are:
162 <br> &nbsp;&nbsp; <code>return-code, short, long, request, uri.</code>
163 
164 <p>You can play with this, for example, by trying to perform an API
165 command with invalid user authentication.  For debugging purposes the
166 API keeps the last condition in <code>twitter::*last-condition*</code>.
167 
168 <h3>Low Level, Programmatic Interface and Objects</h3>
169 
170 <p>The generic, low-level interface to the API is via the twitter-op function:<br><br>
171 
172 &nbsp;&nbsp; <code>(twitter-op :command &rest args)</code>
173 
174 <p>This top level function sends an API call for :command with any
175 arguments to the twitter server and returns one or more 'elements'
176 (see types below).  This API uses struct objects to encapsulate
177 composite values such as users or tweets.  I tried to be smart about
178 converting between names such as 'user_id' and the more natural
179 :user-id parameter names on the lisp side.
180 
181 <pre>
182 
183 TWITTER&gt; (twitter-op :user-show :id "lisp4life")
184 #&lt;TWITTER-USER 'lisp4life'&gt;
185 
186 TWITTER&gt; (describe *)
187 Name: Lisp ('lisp4life') id:19387004
188 Created at: Fri Jan 23 08:47:36 +0000 2009
189 Description: &quot;I'm the Greatest Gay Rapper in the World!&quot;
190 Counts: friends 2, followers 0, statuses 1
191 Location: West Hollywood, CA
192 Time Zone: Alaska
193 
194 TWITTER&gt; (twitter-op :friend-create :id "twitterapi" :follow t)
195 #&lt;TWITTER_USER 'twitterapi'
196 </pre>
197 
198 <p>You can view documentation for commands and elements using:
199 <pre>
200 (command-help [command-name]) ;; prints a summary of all commands or command-name
201 (element-help 'type)
202 </pre>
203 valid types: twitter-user, tweet, twitter-message, search-result, search-ref
204 
205 <h2>Mailing Lists</h2>
206 
207  <ul>
208   <li>
209    <a href="http://www.common-lisp.net/mailman/listinfo/cl-twitter-devel">
210     cl-twitter-devel</a><br>for developers</li>
211   <li>
212    <a href="http://www.common-lisp.net/mailman/listinfo/cl-twitter-announce">
213     cl-twitter-announce</a><br>for announcements.</li>
214 
215  </ul>
216 
217 <h2>API Status</h2>
218 
219 <p>This interface was interactively tested, but bugs remain and not all
220 features have been exercised.  Help tracking down the last of the 
221 bugs is always appreciated!
222 
223 <p>I have also not completely documented all the element slots.  This
224 should be easy to fix and you can also refer to the twitter APIs.
225 
226 <p>TODO:<br>
227 <ul>
228 
229 <li> Verify all API commands (<b>important</b>)
230 <li> Add documentation from Web API spec to element slots (<b>important</b>)
231 <li> Add logging support to capture API command history <br>&nbsp;&nbsp;(simple callback fn with twitter-op command and optionally, send and post-json receive data)
232 <li> Add optional unique-ification to tweets and messages as we do with twitter-user
233 <li> Cookie auth. support? (low priority)
234 <li> OpenID?
235 </ul>
236 
237  <p>Back to <a href="http://common-lisp.net/">Common-lisp.net</a>.</p>
238 
239  <div class="check">
240    <a href="http://validator.w3.org/check/referer">Valid XHTML 1.0 Strict</a>
241  </div>
242 </body>
243 </html>