Table of Contents
Open Table of Contents
スクリプトを準備した経緯
Twitter を始めて早 2 ヶ月が経とうとしている。
「Google Reader なんかもういらない!」(Rest in Peace, RSS)という記事に触発されて始めてみたのだが、自分自身には相変わらず Google Reader は必需品だ。。(用途の棲み分けはできている)
ただ、これまで触れ合うことはなかった方々と触れ合えたり、Google Reader と合わせて貴重な情報源となっており、今では Twitter も必需品だ。
そんな中、「Twitter で Unfollowers (アンフォローをした方)を調べるにはどうしたらいいの?」という質問を受けた。
現状身近な方には特に知らせることも無く、こっそり静かに Twitter を使っているのだが、自身の follower さんも少しづつ増えてきている。
この follower さん、増えるだけでは無く、当然ながら減ることもある。フォローされた場合は、メール通知の設定をしておけば、メールで知ることができるが、確かに、一度フォローした後、そのフォローを解除している方を知るための機能は標準では無さげだ。(きっと)
標準では無さそうだが、同様のことをしてくれるサービスは既にあるだろう。車輪の再開発だが、Twitter のサードパティのサービス/アプリは多すぎて、、、簡単なものであれば自分で準備した方が手軽だ。
しかし、もしかすると、これからやろうとしていることはパンドラの箱なのかもしれない。。
例えば、妻のアカウントからフォローされていたのに、ある日突然そのフォローが外れていたら、どう対応すればよいのだろう・・・知らぬが仏のような気もする。。
Unfollowers をチェックするスクリプト
まずは、Twitter API とやり取りを行うベースとなる簡易 Twitter クライアントを用意する。適当な名前付けでSimpleTwitter
とする。
SimpleTwitter
- 標準ライブラリ以外の原材料
httparty
gem (jnunemaker’s httparty at master - GitHub)
Twitter クライアントに特化した Ruby Twitter Gem などもあるが、 汎用的なものを使いたくてこちらを選択。
- 使用している Twitter API
httparty
gem がインストールされていない場合には、事前にインストール。
$ sudo gem install httparty
$ gem list httparty
*** LOCAL GEMS ***
httparty (0.4.3)
今回の目的からは外れるが、Timeline の表示、Mention の表示も一応入れておく。
simple_twitter.rb
require 'time'
require 'forwardable'
require 'rubygems'
require 'httparty'
class SimpleTwitter
extend Forwardable
include HTTParty
base_uri 'https://twitter.com' # SSL
def_delegator :"#{self}", :get, :get
def initialize(user, password, options = {})
if options.key? :http_proxy
options[:http_proxy_port] ||= 8080
self.class.http_proxy options[:http_proxy], options[:http_proxy_port].to_i
end
@auth_info = { :username => user, :password => password }
end
def timeline(which = :friends, options = {})
auth_info_merge! options
get("/statuses/#{which}_timeline.json", options)
end
def mentions(options = {})
auth_info_merge! options
get("/statuses/mentions.json", options)
end
def followers(options = {})
auth_info_merge! options
options[:query] ||= {}
options[:query].merge!({ :cursor => -1 }) unless options[:query].key? :cursor
get("/statuses/followers.json", options)
end
class << self
def format_time(time, format = '%Y/%m/%d %H:%M:%S')
(time.is_a?(String) ? Time.parse(time) : time).strftime(format)
end
end
private
def auth_info_merge!(options)
options.merge!({ :basic_auth => @auth_info })
end
end
タイムラインの表示などには、以下のような感じで使える。
require 'simple_twitter'
twitter = SimpleTwitter.new('user', 'password')
# for Proxy
# twitter = SimpleTwitter.new('user', 'password',
# { :http_proxy => 'proxy_server', :http_proxy_port => 8080 })
# query count default 20
twitter.timeline(:friends, { :query => { :count => 5 } }).each do |twit|
puts "#{twit['user']['screen_name']} [#{SimpleTwitter.format_time(twit['created_at'])}](#{twit['id'].to_s}):\n" +
" #{twit['text']}"
end
表示は以下のような感じ。
# >> delicious50 [2009/11/07 15:47:58](5501187604):
# >> ALC http://bit.ly/lcfEp japan
# >> delicious50 [2009/11/07 15:47:56](5501187311):
# >> findability.org - by Peter Morville http://bit.ly/15KKUP findability ia
# >> GuyKawasaki [2009/11/07 15:46:52](5501173816):
# >> Guess who is a Glamour woman of the year? http://om.ly/bTqX
# >> tek_news [2009/11/07 15:46:49](5501173203):
# >> HNews: Someone actually created a pyramid scheme for Twitter popularity. http://bit.ly/20gVa5
# >> GuyKawasaki [2009/11/07 15:46:46](5501172663):
# >> The official rules of Shotgun http://om.ly/bTqU
Unfollowers をチェックするスクリプト
- 標準ライブラリ以外の原材料
simple_twitter.rb
上記にあるスクリプト
follows_unfollowers_check.rb
require 'simple_twitter'
FOLLOWERS_CSV = 'followers.csv'
INDENT = ' ' * 2
def get_follower_user_list(twitter, cursor = -1)
users = []
twit_followers = twitter.followers(:query => { :cursor => cursor })
twit_followers['users'].each do |follower|
users << follower['screen_name']
end
next_cursor = (twit_followers['next_cursor'] ||= '0')
unless next_cursor.to_i == 0
users.concat(get_follower_user_list(twitter, next_cursor))
end
users
end
twitter = SimpleTwitter.new('user', 'password')
# for Proxy
# twitter = SimpleTwitter.new('user', 'password',
# { :http_proxy => 'proxy_server', :http_proxy_port => 8008 })
current_users = get_follower_user_list(twitter)
previous_users = []
if File.exist? FOLLOWERS_CSV
begin
previous_users = File.open(FOLLOWERS_CSV).read.split(',')
rescue
puts $!
exit(9)
end
end
unfollowers = previous_users - current_users
new_follow_users = current_users - previous_users
puts "Follow User Stats at #{SimpleTwitter.format_time(Time.now)}"
puts '=' * 50
puts "Current Follow Users count: %s" % current_users.size.to_s
puts "Unfollowers count: %s" % unfollowers.size.to_s
unfollowers.each do |user|
puts "#{INDENT}#{user}\t#{SimpleTwitter.base_uri}/#{user}"
end
puts "New follow Users count: %s" % new_follow_users.size.to_s
new_follow_users.each do |user|
puts "#{INDENT}#{user}\t#{SimpleTwitter.base_uri}/#{user}"
end
File.open(FOLLOWERS_CSV, 'w') { |f| f.write current_users * ',' }
結果は以下のような出力になる。(Emacs 上で rcodetools を利用した際の表示)
# >> Follow User Stats at 2009/11/07 15:03:01
# >> ==================================================
# >> Current Follow Users count: 65
# >> Unfollowers count: 7
# >> SavvyExplorer https://twitter.com/SavvyExplorer
# >> talyaalove https://twitter.com/talyaalove
# >> 59minlearning https://twitter.com/59minlearning
# >> lifefulfillment https://twitter.com/lifefulfillment
# >> follow4profit https://twitter.com/follow4profit
# >> Forex_Blog https://twitter.com/Forex_Blog
# >> VirtualTotte https://twitter.com/VirtualTotte
# >> New follow Users count: 6
# >> RecognitionApps https://twitter.com/RecognitionApps
# >> kazuyo_k https://twitter.com/kazuyo_k
# >> Dewina_Olivera https://twitter.com/Dewina_Olivera
# >> HP_AppSecurity https://twitter.com/HP_AppSecurity
# >> videotodaynews https://twitter.com/videotodaynews
# >> devtube https://twitter.com/devtube
実行は、simple_twitter.rb
と follows_unfollowers_check.rb
を同じディレクトリにおいておいて、
$ ruby ./follows_unfollowers_check.rb
前回スクリプトを動かした時との差分が表示される。
正確にやろうと思うと、細目にこのスクリプトを動かしておかないといけない。前回動作時との間に follow/unfollow の両方を行ったアカウントは捉えられないので。
また、結果の出力は標準出力以外のもの、メールでの送信などにしておくのもよいかもしれない。