Skip to content

Instantly share code, notes, and snippets.

@miikka
Created August 24, 2010 19:07
Show Gist options
  • Save miikka/548120 to your computer and use it in GitHub Desktop.
Save miikka/548120 to your computer and use it in GitHub Desktop.
Simple Haskell Twitter OAuth example
{-# LANGUAGE PackageImports #-}
{-
You need to register your Twitter application at <http://dev.twitter.com/>
to get the consumer key and secret needed for OAuth. When connecting to
Twitter for the first time, do this:
let consumer = Consumer "consumer key" "consumer secret"
token <- authenticate
This authenticates your application against Twitter. You should save the
token. It has a Binary instance, so you could just use encodeFile from
Data.Binary.
If you are the only user of your Twitter application, you can choose to use
the single access token. In that case use singleAccessToken to generate a
token - you can run it every time as it's actually a pure operation
(although its type doesn't look like that).
token <- singleAccessToken consumer "access token" "access secret"
Now you are ready to tweet:
tweet consumer token "Hello world!"
-}
module Web.Twitter.Simple where
import Data.Maybe (fromJust)
import "mtl" Control.Monad.Trans
import Network.OAuth.Consumer
import Network.OAuth.Http.Request
import Network.OAuth.Http.Response
import Network.OAuth.Http.HttpClient
import Network.OAuth.Http.PercentEncoding
reqUrl = fromJust . parseURL $ "https://api.twitter.com/oauth/request_token"
accUrl = fromJust . parseURL $ "https://api.twitter.com/oauth/access_token"
tweetUrl = fromJust . parseURL $ "http://api.twitter.com/1/statuses/update.json"
authUrl = ("https://api.twitter.com/oauth/authorize?oauth_token=" ++)
. findWithDefault ("oauth_token","") . oauthParams
data Consumer = Consumer
{ key :: String
, secret :: String }
deriving (Show, Eq)
authenticate :: Consumer -> IO Token
authenticate consumer = unCurlM . runOAuth $ do
ignite $ Application (key consumer) (secret consumer) OOB
oauthRequest HMACSHA1 Nothing reqUrl
cliAskAuthorization authUrl
oauthRequest HMACSHA1 Nothing accUrl
getToken
singleAccessToken :: Consumer -> String -> String -> IO Token
singleAccessToken consumer accToken accSecret = unCurlM . runOAuth $ do
let app = Application (key consumer) (secret consumer) OOB
let newToken = [("oauth_token", accToken)
,("oauth_token_secret", accSecret)]
ignite app
token <- getToken
return $ AccessToken app (fromList newToken `union` oauthParams token)
tweet :: Consumer -> Token -> String -> IO Response
tweet consumer token message = unCurlM . runOAuth $ do
ignite $ Application (key consumer) (secret consumer) OOB
putToken token
-- I can't figure out how to put the status in the POST body, but putting
-- it in the query string works.
let body = "status=" ++ encode message
request = tweetUrl { method = POST
, qString = fromList [("status", message)]
}
serviceRequest HMACSHA1 Nothing request
@jstoner
Copy link

jstoner commented Dec 10, 2012

when I load this into GHCI, I'm getting

jstoner@erzulie]> ghci
GHCi, version 7.4.1: http://www.haskell.org/ghc/ :? for help
Loading package ghc-prim ... linking ... done.
Loading package integer-gmp ... linking ... done.
Loading package base ... linking ... done.
Prelude> :l tweetoauth2
[1 of 1] Compiling Web.Twitter.Simple ( tweetoauth2.hs, interpreted )

tweetoauth2.hs:51:25: Not in scope: `unCurlM'

tweetoauth2.hs:59:49: Not in scope: `unCurlM'

tweetoauth2.hs:68:32: Not in scope: `unCurlM'
Failed, modules loaded: none.

@jstoner
Copy link

jstoner commented Dec 10, 2012

as I look more carefully, I think Network.OAuth.Http.HttpClient is changed. Sorry, I'm just a Haskell newb trying to teach myself by building a twitterbot.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment