hello-world
webエンジニアのメモ。とりあえずやってみる。

[twitter][ruby]twitter APIのツイート上限回数について調べてみた

公開日時

本調査の結果は2014/9/8時点でのものになります。また、自分のテストアカウントでしか確認していないため、他のユーザでも同じ回数まで使えるかは分かりません。

twitter apiを使って定期的にツイートを行うbotを作ろうと思い、ツイート回数上限について調べてみました。

公式サイトには

ツイート:2,400件/1日。1日あたりのリミットは、更に細かい1時間に2回間隔のリミットに分かれます。リツイートも、ツイートとして数に考慮されます。

これらのリミットは、ウェブ、モバイル、電話、API等を含む、すべてのデバイスからの操作を含みます。すべてのサードパーティのアプリケーションからのAPIリクエストは、1時間毎のAPIリミットとは別にトラックされます。アカウントを複数のサードパーティアプリケーションでご利用の場合は、APIリミットにかかりやすくなりますことご理解ください。詳細は「APIレートリミット」をご覧ください。

これらのリミットは、サイト利用が多い期間中に一時的に下げる場合があります。その場合は、Twitterステータスブログでご案内致します。

と書かれており、1日当たり2400件まで投稿可能のようです。(APIに限らずブラウザから投稿を行っても1件として扱われるとのこと)

ただ、1日当たりの制限に加えて1時間毎の上限も決められているとのことだったので、1時間毎の上限も探してみたのですが見つからず、テストアカウントを用いて検証してみました。

結論から先に書くと、

1時間あたり100回のペースだとAPI制限に引っかからずツイートを行うことができました(3時間あたり300回の制限がある模様)

以下、結論に至るまでの経緯をダラダラ残しておきます。

1. 1分に1回ツイートするサンプルを作成

gem twitterを使って、ツイートを行うサンプルを作成し、cronで1分おきに実行するようにしてみました。

こちらは問題なく24時間実行できました。

2. 9〜21時までは1分間に2回つぶやくサンプルを作成 1.で作ったサンプルのまま、cronの設定をいじって無理やり対応しました。

0-8,21-23 * * * /bin/bash -lc '/home/test/tw_bot_cron.sh'
9-20 * * * for i in 15 45;do (sleep ${i} ; /bin/bash -lc '/home/test/tw_bot_cron.sh') & done;

このサンプルの場合、一定時間おきにAPI上限に達して以下のエラーが発生しました。

User is over daily status update limit.

エラーをグラフにしてみると以下のようになり、3時間おきにエラーが60回近く発生していました。

tw_bot

3時間で360回つぶやこうとすると60回近くエラーになるので、3時間で300回までならいけそうな予感。

3. 1時間あたり100回つぶやくサンプルを作成

以下のようなサンプルを作成し、cronでの実行をやめて1回ツイートする毎に36秒sleepするようにしました。

# Gemfile
source 'https://rubygems.org'

gem 'twitter'
gem 'pry'
gem 'activerecord'
gem 'sqlite3'

# migration.rb
require "rubygems"
require "bundler/setup"
require 'active_record'

ActiveRecord::Base.establish_connection(
  adapter: "sqlite3",
  database: "tw.sqlite3"
)

class InitialSchema < ActiveRecord::Migration
  def self.up
    create_table :tweets do |t|
      t.string :tw_id, :null => false
      t.string :text, :null => false
      t.timestamps
      t.index :tw_id, :unique => true
    end
  end

  def self.down
    drop_table :tweets
  end
end

InitialSchema.migrate(:up)

# tweet.rb
require 'rubygems'
require 'twitter'
require "active_record"
require 'pry'
require 'logger'

CONSUMER_KEY         = "YOUR CONSUMER_KEY"
CONSUMER_SECRET      = "YOUR CONSUMER_SECRET"
ACCESS_TOKEN         = "YOUR ACCESS_TOKEN"
ACCESS_TOKEN_SECRET  = "YOUR ACCESS_TOKEN_SECRET"

ActiveRecord::Base.establish_connection(
  adapter: "sqlite3",
  database: "tw.sqlite3"
)

class Tweet < ActiveRecord::Base
end

def main
  log = Logger.new("test.log", 3)

  client = Twitter::REST::Client.new do |config|
    config.consumer_key        = CONSUMER_KEY
    config.consumer_secret     = CONSUMER_SECRET
    config.access_token        = ACCESS_TOKEN
    config.access_token_secret = ACCESS_TOKEN_SECRET
  end

  loop do
    tw_cnt = Tweet.count
    text = "#{tw_cnt + 1}番目のつぶやき"
    begin
      tweet = client.update!(text)
      Tweet.create!(tw_id: tweet.id, text: text)
      p text
    rescue => e
      log.error("#{text}: #{e.message}")
    end
    sleep 36 # 1時間に100回投稿
  end
end

main

このサンプルだと User is over daily status update limit. のエラーは発生することなく24時間ツイートができました。

twitter apiでツイートを行う場合、3時間あたり300回以内に抑えておくのが良さそうです。

参考


Related #Ruby

[Rails]find_or_create_byとfind_or_initialize_by

Rails4で確認。

capistranoで世代管理する際の注意点

最近、デプロイツールに capistranoを使っているのですが、世代管理の設定を勘違いしていたのでメモを残しておきます。

[rails]unicornでpryを使う

先日、pryでデバッグする という記事を書きましたが、こちらはrails server(フォアグランド)でアプリを立ち上げた際のデバッグ方法でした。