Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP

Barebones Lua Twitter

branch: master

Fetching latest commit…

Octocat-spinner-32-eaf2f5

Cannot retrieve the latest commit at this time

Octocat-spinner-32 LICENSE
Octocat-spinner-32 README.md
Octocat-spinner-32 bbl-twitter.lua
README.md

bbl-twitter

... is a Barebones Lua Twitter module (OAuth-enabled) with minimal dependencies.

It is intended for thin/embedded platforms like OpenWRT routers.

Dependencies

  • Lua (5.1 assumed)
  • luasocket
  • shell w/ echo support (ie nearly any shell)
  • an openssl executable binary.

Packages

  • On OpenWRT, packages required are openssl-util, lua, luasocket
  • On Debian/Ubuntu, packages required are openssl, lua, liblua5.1-socket2
  • Other OSes will be similar. :)

License

MIT Licensed as per the LICENSE file.

Overview

To be able to use any twitter feature, you'll have to get a consumer key and consumer secret at https://dev.twitter.com and pass to to the client function.

Access token

To actually make resource requests (e.g., post tweets), you need to have an access token. You can get an access token in three ways:

  1. Get a single access token from https://dev.twitter.com. This only works if you need access just your own account, no others. See https://dev.twitter.com/pages/oauth_single_token for details.

  2. Use the out-of-band (PIN) OAuth flow. This means you present the user with a Twitter url he should visit. After clicking the authorize button at that url, the user is presented with a verifier (PIN code) that is entered back into your application. You can then "trade" the verifier for an access token using the OAuth API.

  3. Use the full (callback) OAuth flow, which is intended for web applications. You redirect the user to a Twitter url. After clicking the authorize button at that url, the user is redirected back to your webapplication with a verifier in the url. You can again "trade" the verifier for an access token using the OAuth API.

If you obtain an access token using method 2. or 3., you can save it into persistent (secure) storage for later use (so you don't have to run the authorization steps again). The access token can be obtained from the c.token_key and c.token_secret values and can later be passed into the client() function to reuse it.

Examples

Tweet from a client (known access token)

This assumes you already have an access token, obtained by any method described above.

require("bbl-twitter")
c=client(config.consumer_key, config.consumer_secret, config.token_key, config.token_secret)
update_status(c, "Look ma, tweets from Lua!")

Tweet w/ error handling

Errors thrown in the various functions can be handled using the pcall function. This example shows how to handle errors in update_status, but it applies to all other functions as well.

require("bbl-twitter")
c=client(config.consumer_key, config.consumer_secret, config.token_key, config.token_secret)
local r, e = pcall(update_status, c, "Look ma, this tweet might not make it!")
if (not r) then
  if string.match(e, "duplicate") then
    print("Best guess is this tweet was rejected as a duplicate. Did you already tweet this?")
  else
    print("Error sending tweet: " .. e)
  end
end

Authenticate Out-Of-Band to Twitter using the console

This example uses the out_of_band_cli function, which handles prompting the user with the authorization url and prompting for the pin code.

require("bbl-twitter")
c=client(config.consumer_key, config.consumer_secret)
-- The following function will prompt on the console to visit a URL and
-- enter a PIN for out-of-band authentication
out_of_band_cli(c)
update_status(c, "Look ma, I just authenticated my Lua twitter app!")
print(string.format("Authorized by user '%s'. My secrets are token_key '%s' token_secret '%s'",
                    c.screen_name, c.token_key, c.token_secret))

Authenticate Out-Of-Band to Twitter using other I/O

This example shows the details of doing out-of-band authorization (you'll need to fill in the TODOs with your favorite I/O method to make it work, of course).

require("bbl-twitter")
c=client(config.consumer_key, config.consumer_secret)
-- First get a request token and declare we need to do out-of-band
-- authorization
get_request_token(c, 'oob')
local url = get_authorize_url(c)
-- TODO: Show the url to the user
-- TODO: obtain pin from the user
local pin = ...
-- Now, trade the pin for an access token
get_access_token(c, pin)

update_status(c, "Look ma, I just authenticated my Lua twitter app!")
print(string.format("Authorized by user '%s'. My secrets are token_key '%s' token_secret '%s'",
                    c.screen_name, c.token_key, c.token_secret))

Authenticate using a callback

This example shows how to use this stuff in a webapplication using a callback. Again, fill in the TODOs for your webapp.

In the first request, you do:

require("bbl-twitter")
c=client(config.consumer_key, config.consumer_secret)
-- First get a request token and declare our callback url
get_request_token(c, 'http://www.example.org/mywebapp')
-- TODO: Store c.req_token and c.req_secret somewhere
local url = get_authorize_url(c)
-- TODO: Redirect user to url

After authorization is complete, the user will be redirected to http://www.example.org/mywebapp?oauth_token=...&oauth_verifier=...

This request should be handled as follows:

require("bbl-twitter")
c=client(config.consumer_key, config.consumer_secret)

-- TODO: get oauth_verifier from the url
local verifier = ...
-- TODO: get oauth_token from the url
c.req_token = ...
-- TODO: compare req_token with stored req_token
-- TODO: get stored req_secret
c.req_secret = ...

-- Now, trade the verifier for an access token
get_access_token(c, verifier)

update_status(c, "Look ma, I just authenticated my Lua twitter app!")
print(string.format("Authorized by user '%s'. My secrets are token_key '%s' token_secret '%s'",
                    c.screen_name, c.token_key, c.token_secret))

Perform custom signed requests

The signed_request function can be used to perform other requests to the Twitter API that require authorization. This example shows how you would implement posting a new tweet if the update_status function would not exist.

This assumes you already have an access token, obtained by any method described above.

require("bbl-twitter")
c=client(config.consumer_key, config.consumer_secret, config.token_key, config.token_secret)
signed_request(c, "/1/statuses/update.xml", {status = "Look ma, tweets from Lua!"}, "POST")

Provide bbl-twitter options in a global 'twitter_config' table

require("bbl-twitter")
twitter_config.openssl = "/opt/bin/openssl" -- if your openssl is not on the PATH
twitter_config.consumer_key = "myconsumerkey"
twitter_config.consumer_secret = "myconsumersecret"
twitter_config.token_key = "myaccesstoken"
twitter_config.token_secret = "myaccesssecret"
update_status(client(), "Look ma, global settings!")

Alternatives

Jeffrey Friedl has actually coded a pure Lua Twitter module right down to SHA1 & HMAC-SHA1 implementations, which is quite impressive (if a bit absurd!) Although as-written it is tied to the Adobe Lightroom plugin environment. http://regex.info/blog/lua/twitter

bbl-twitter was inspired by "shtter" shell twitter client for OpenWRT, by "lostman" http://lostman-worlds-end.blogspot.com/2010/05/openwrt_22.html (lostman's is better if you want command-line tweeting on a very severe budget!)

If you have easy access to luarocks + working C compiler then a better fully-featured option may be ltwitter - https://github.com/TheLinx/ltwitter

Todo

  • Make less bodgy
  • Add more Twitter API features (parsing JSON/XML w/o additional dependencies FTL)
Something went wrong with that request. Please try again.