twitter OAuthのアクセストークンをブラウザなしで取得

以前にブラウザを使った方法を引用したことがあります。

ただし、この方法だと、目的のアカウントにログインしているWebブラウザを用意しておく必要があります。
面倒でした。
ということで、コンソールというかターミナルだけで済ませるスクリプトを作りました*1ので掲載しておきます。

スクリプト

必要なgem:

  • watir (多分watir-webdriverも一緒に入るはず)
  • oauth

(2/24追記)すみません、gemでは無いですが、PhantomJSが必要ですm(_ _)m。Macならば"brew install phantomjs"で入ります。

#!/usr/bin/env ruby
# coding: utf-8
require 'io/console'
require 'watir'
require 'oauth'

def inputs
  puts "Please input consumer_key: "
  @consumer_key = gets.chomp
  puts "Please input consumer_secret: "
  @consumer_secret = gets.chomp
  puts "Please input your twitter account: "
  @screen_name = gets.chomp[/@?([^@]+)/, 1]
  puts "Please input your account's password (no keyboard echo): "
  @password = $stdin.noecho(&:gets).chomp
  puts
end

def get_request_token(consumer_key, consumer_secret)
  oauth = OAuth::Consumer.new(
    consumer_key, consumer_secret, 
    site: 'https://api.twitter.com/'
  )
  begin
    request_token = oauth.get_request_token
  rescue OAuth::Unauthorized
    puts "sorry, consumer_key/secret is probably wrong."
    exit
  end
end

def browse
  browser = Watir::Browser.new(:phantomjs)
  browser.goto("https://twitter.com/login")
  browser.text_field(xpath: '//fieldset/div[1]/input').set(@screen_name)
  browser.text_field(xpath: '//fieldset/div[2]/input').set(@password)
  browser.button(xpath: '//form/div[2]/button').click
  request_token = get_request_token(@consumer_key, @consumer_secret)
  request_url = request_token.authorize_url
  browser.goto(request_url)
  browser.button(xpath: '//input[@id="allow"]').click
  begin
    token_pin = browser.element(xpath: '//div[@id="oauth_pin"]/p/kbd/code').text
    @access_token = request_token.get_access_token(oauth_verifier: token_pin)
  rescue OAuth::Unauthorized, Watir::Exception::UnknownObjectException
    puts "sorry, your account and/or password is probably wrong."
    exit
  end
end

def output
  puts(<<EOF)
gem 'twitter', '>= 5.0.0'
require 'twitter'
client = Twitter::REST::Client.new(
  consumer_key:         '#{@consumer_key}',
  consumer_secret:      '#{@consumer_secret}',
  access_token:         '#{@access_token.token}',
  access_token_secret:  '#{@access_token.secret}',
)
EOF
end

def main
  inputs
  browse
  output
end

main

出力結果をそのままスクリプトに貼り付けて、Twitter::REST::Clientクラスのインスタンスであるclientを使えば、twitter apiを扱えます。
なお、以下の結果はイメージです(改変してあります)。

gem 'twitter', '>= 5.0.0'
require 'twitter'
client = Twitter::REST::Client.new(
  consumer_key:         'yfUdFtTbkEkrI8aPmsu4mA',
  consumer_secret:      'WCBQGGBuHbmOJw1pN3woKz9O0krB3xzoz7bbqLNrw',
  access_token:         '2354642274-qXfrk25BNnYI1GPH2e9SZj4hQNLn2RSvAeh4KHb',
  access_token_secret:  'cKR8tExsuH3XO1QFq6LvJJC02zhIjBFV6qJeEeYqbKnZc',
)

なお、twitter gemのバージョンが5未満の場合には

gem 'twitter', '>= 5.0.0'
require 'twitter'
client = Twitter::REST::Client.new(

の部分を

gem 'twitter', '< 5.0.0'
require 'twitter'
client = Twitter::Client.new(

にしてください。

*1:watirXPathが多用されているのは趣味ですw