A twitter client library for Common Lisp
Switch branches/tags
Nothing to show
Clone or download
Latest commit e520b24 Aug 17, 2018
Permalink
Failed to load latest commit information.
.gitattributes Create .gitattributes May 17, 2018
LICENSE Added LICENSE Feb 22, 2014
README.md Ported old about-template to README and new staple. Sep 20, 2016
about.html Doc up Jan 4, 2018
account.lisp Copyright header update to Shirakumo Oct 9, 2014
blocks.lisp Copyright header update to Shirakumo Oct 9, 2014
chirp-core.asd Add support for Twitter collection API Oct 21, 2017
chirp-dexador.asd Remove in-package from ASD file. Aug 16, 2017
chirp-drakma.asd Remove in-package from ASD file. Aug 16, 2017
chirp-logo-single.png New logo Mar 17, 2014
chirp-logo.png New logo Mar 17, 2014
chirp.asd Fix asd Aug 17, 2018
collections.lisp Export symbols in collections.lisp Nov 8, 2017
cursor.lisp Copyright header update to Shirakumo Oct 9, 2014
dexador.lisp Ignore dexador's errors. Aug 3, 2016
direct-messages.lisp Add FULL-TEXT parameter to dm endpoints. This is new. Jul 29, 2016
documentation.lisp Copyright header update to Shirakumo Oct 9, 2014
drakma.lisp Fix return for open-request. Jul 29, 2016
entities.lisp Copyright header update to Shirakumo Oct 9, 2014
favorites.lisp Copyright header update to Shirakumo Oct 9, 2014
friends.lisp Copyright header update to Shirakumo Oct 9, 2014
generics.lisp Copyright header update to Shirakumo Oct 9, 2014
help.lisp Added new help/configuration propery: dm-text-character-limit Jul 30, 2016
indent.lisp Copyright header update to Shirakumo Oct 9, 2014
lists.lisp Fix deleting members from a list Feb 8, 2017
location.lisp Copyright header update to Shirakumo Oct 9, 2014
oauth.lisp Spliced off drakma parts into separate system and added a system for … Jul 29, 2016
package.lisp Export symbols in collections.lisp Nov 8, 2017
saved-searches.lisp Copyright header update to Shirakumo Oct 9, 2014
search.lisp Copyright header update to Shirakumo Oct 9, 2014
staple.ext.lisp Fix staple.ext for 2.0 May 31, 2018
statuses.lisp Fixed favorites/retweets counts Oct 3, 2017
stream.lisp Fixed stream reading for messages that are longer than 4096. Jul 30, 2016
suggestions.lisp Copyright header update to Shirakumo Oct 9, 2014
timelines.lisp Copyright header update to Shirakumo Oct 9, 2014
toolkit.lisp Fix url encoding: Twitter requires uppercase hex characters after % Feb 5, 2017
trends.lisp Copyright header update to Shirakumo Oct 9, 2014
user.lisp Fixed users/lookup - params named wrong and the call doesn't return a… Sep 24, 2015

README.md

How To

Load Chirp through Quicklisp or ASDF:

(ql:quickload :chirp)

To use twitter's API, you need to authorize an account. By default this happens through the PIN method, though others are available as well. Retrieve your twitter application's api key and secret and invoke the following function:

(chirp:initiate-authentication :api-key "<app api key>" :api-secret "<app api secret>")

You may use the following keys for testing purposes: API-KEY: D1pMCK17gI10bQ6orBPS0w API-SECRET: BfkvKNRRMoBPkEtDYAAOPW4s2G9U8Z7u3KAf0dBUA. These are for the CL-CHIRP twitter application. You should not use these for anything other than the testing of Chirp, as it may pose a security risk.

If the first OAuth step is successful, it should return an URL that you have to visit. This will then prompt you to authorize the application and present a PIN. Copy this pin and complete the authentication process:

(chirp:complete-authentication "<pin>")

If the function returns successfully, you are ready to use the twitter API:

(chirp:account/verify-credentials)

In the case that you do not want to repeat the authentication process, you can save and later set the *oauth-api-key*, *oauth-api-secret*, *oauth-access-token* and *oauth-access-secret* variables manually. That's all the information it takes to authenticate over twitter. Make sure to keep these tokens secret.

(chirp:statuses/update "Hooray, I successfully used the Chirp Common Lisp library to tweet!")

There are functions to check for tweet length, available languages, access level, rate limits, and so on as well.

(chirp:compute-status-length "Wowsers, URL shortening sure is a thing! https://github.com/Shinmera/chirp.git")
(chirp:valid-language-p "en")
(chirp:access-level)

Chirp also provides access to twitter's streaming API:

(chirp:stream/user #'(lambda (message) (when message (format T "~&amp;STREAM: ~a~%" message)) T))

Do note that Chirp does not concern itself with threading. As such, processing stream objects in the background is up to you.

Using the various convenience methods, a simple bot can be assembled with relative ease:

(chirp:map-timeline :mentions #'(lambda (status) (chirp:reply status "Chirp chirp!")))

Though the timelines are heavily rate-limited. For a more immediate response, the streaming API should be used:

(chirp:start-stream
  :user #'(lambda (message)
            (when (and (typep message 'chirp:status) (chirp:direct-mention-p message))
              (chirp:reply message "Chirp chirp!"))
            T))

One thing to note is that twitter XML entity encodes certain things like status texts. I frankly don't know why it does that since it's a JSON api. Chirp does not automatically decode these entities, as the twitter entities (like hashtags, urls, etc) contain position markers that depend on the encoded string. Decoding it screws over these positions. However, Chirp offers a couple of functions to make handling of entities or decoding easier:

(chirp:xml-decode (chirp:text status))
(chirp:text-with-expanded-urls status)
(chirp:text-with-markup status)
(chirp:replace-entity :urls #'expanded-url)

Especially the last two can be very useful for preparing the text for a web-interface. Chirp's symbols are separated into three packages (and unified in CHIRP) so that you may selectively USE what you need.

  • CHIRP-API contains all the direct Twitter API call mapping functions.
  • CHIRP-EXTRA contains the various helper functions that make dealing with the API easier.
  • CHIRP-OBJECTS contains all accessor and class symbols. You probably want to USE this package if you work with the objects a lot.