Twitter bots and OAuth
I'm working on a Twitter bot, and I ran up against something very annoying: apps need to be on an account with a mobile phone number. I have just one mobile phone, and it's already tied to my real Twitter account. Rather than finding a way to get another mobile number, I had the bot authorize my app using Twitter's OAuth API. Here's how to do it.
Step one: collect your API keys. There's a consumer key and a consumer secret, both available from your app's page at apps.twitter.com. Never commit these to a repository or post them anywhere. I put them in a special file that I tell git to ignore, keys.py
.
Step two: collect OAuth tokens. The key trick here is to collect tokens that are permanently good, using the out-of-band (OOB) PIN method. To actually send the requests, I used the requests-oauthlib library for Python. Here's how to do it:
from requests_oauthlib import OAuth1Session
from keys import *
twitter = OAuth1Session(consumer_key, consumer_secret) # loaded from keys.py!
twitter.params['oauth_callback'] = 'oob' # make sure we're in PIN mode
r = twitter.post('https://api.twitter.com/oauth/request_token')
At this point, r.text
will tell you, HTTP request parameter style, your oauth_token
and oauth_secret
. Add these to your keys.py
file and copy the oauth_token
to the clipboard.
Step three: authorize the app. Fire up a web browser and log in to the bot's account. Go to https://api.twitter.com/oauth/authorize?oauth_token=[whatever your oauth_token was]
. You'll get a PIN number. Add it to your keys.py
file.
Step four: finalize the authorization.
from requests_oauthlib import OAuth1Session
from keys import *
twitter = OAuth1Session(consumer_key, consumer_secret)
twitter.params['oauth_verifier'] = pin
r = twitter.get('https://api.twitter.com/oauth/access_token?oauth_token=' + oauth_token)
Now r.text
will give you a new oauth_token
and oauth_token_secret
. Save these---they're OAuth access tokens, which are how you can actually make API calls.
Step five: check that it worked. Log in to the bot account, go to settings, and check the apps subheading---your app should appear. You can tweet programmatically, now:
from requests_oauthlib import OAuth1Session
from keys import *
twitter = OAuth1Session(consumer_key, consumer_secret, oauth_access_token, oauth_token_secret)
twitter.post('https://api.twitter.com/1.1/statuses/update.json?status=Testing.')
I would be lying if I said I was 100% confident that everything from here on out is easy, but it seems like these access tokens are all you need after PIN based authorization.