11
5

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

(専用ライブラリなし)Twitter API v2でRubyからツイートするプログラムを書く

Last updated at Posted at 2023-04-11

いよいよ4月末にせまったTwitterAPIのv1からv2への移行にむけて自作プログラムのAPIv1からv2への移行を行ったので備忘録としてかいておきます

前提情報

なぜTwitter v2用ライブラリを使わないのかの理由

  • 大前提としてRubyの有名なライブラリであるtwitter gemはv1に対応してなさそうであること
  • 公式サイトにのっている各種言語のライブラリはコミュニティライブラリがほとんどというためメンテナンスの信頼度にかけるのと、Rubyライブラリそのものの数が少なくコミットも去年だったりしたので今回は自前でAPI v2でツイートするコードを書くことにしました

公式のサンプルを見てみる

公式がサンプルコードをあげてくれていますのでまずそれを見てみます

https://github.com/twitterdev/Twitter-API-v2-sample-code
https://github.com/twitterdev/Twitter-API-v2-sample-code/blob/main/Manage-Tweets/create_tweet.rb

require 'oauth'
require 'json'
require 'typhoeus'
require 'oauth/request_proxy/typhoeus_request'
require 'dotenv/load'
# The code below sets the consumer key and secret from your environment variables
# To set environment variables on Mac OS X, run the export command below from the terminal:
# export CONSUMER_KEY='YOUR-KEY', CONSUMER_SECRET='YOUR-SECRET'
consumer_key = ENV["CONSUMER_KEY"]
consumer_secret = ENV["CONSUMER_SECRET"]


create_tweet_url = "https://api.twitter.com/2/tweets"

# Be sure to add replace the text of the with the text you wish to Tweet.
# You can also add parameters to post polls, quote Tweets, Tweet with reply settings, and Tweet to Super Followers in addition to other features.
@json_payload = {"text": "Hello world! TwitterAPI V2 ハローワールド"}

consumer = OAuth::Consumer.new(consumer_key, consumer_secret,
	                                :site => 'https://api.twitter.com',
	                                :authorize_path => '/oauth/authenticate',
	                                :debug_output => false)

def get_request_token(consumer)

	request_token = consumer.get_request_token()

  return request_token
end

def get_user_authorization(request_token)
	puts "Follow this URL to have a user authorize your app: #{request_token.authorize_url()}"
	puts "Enter PIN: "
	pin = gets.strip

  return pin
end

def obtain_access_token(consumer, request_token, pin)
	token = request_token.token
	token_secret = request_token.secret
	hash = { :oauth_token => token, :oauth_token_secret => token_secret }
	request_token  = OAuth::RequestToken.from_hash(consumer, hash)

	# Get access token
	access_token = request_token.get_access_token({:oauth_verifier => pin})

    p access_token
    
	return access_token
end


def create_tweet(url, oauth_params)
	options = {
	    :method => :post,
	    headers: {
	     	"User-Agent": "v2CreateTweetRuby",
        "content-type": "application/json"
	    },
	    body: JSON.dump(@json_payload)
	}
	request = Typhoeus::Request.new(url, options)
	oauth_helper = OAuth::Client::Helper.new(request, oauth_params.merge(:request_uri => url))
	request.options[:headers].merge!({"Authorization" => oauth_helper.header}) # Signs the request
	response = request.run

	return response
end



# PIN-based OAuth flow - Step 1
request_token = get_request_token(consumer)
# PIN-based OAuth flow - Step 2
pin = get_user_authorization(request_token)
# PIN-based OAuth flow - Step 3
access_token = obtain_access_token(consumer, request_token, pin)

oauth_params = {:consumer => consumer, :token => access_token}


response = create_tweet(create_tweet_url, oauth_params)
puts response.code, JSON.pretty_generate(JSON.parse(response.body))

上記はサンプルコードにdotenvライブラリをたしているのと、メッセージに日本語をたしています
typhoeusというHTTPクライアントライブラリとoauthを使っているようです。
create_tweet_urlのURLはしっかりとv2になっているのでv2でツイートできるようですが、このプログラムはブラウザでURLを開いて認証してPINコードを打つということが必要で、バッチやBot的にツイートするというのには使えません。WEBアプリケーション連携するときのコードになります。

ほしいのはこれじゃない

v1でBot作ってた人が欲しがるコードはこっち

サンプルコードを元に修正しました

require 'oauth'
require 'json'
require 'typhoeus'
require 'oauth/request_proxy/typhoeus_request'
require 'dotenv/load'
# The code below sets the consumer key and secret from your environment variables
# To set environment variables on Mac OS X, run the export command below from the terminal:
# export CONSUMER_KEY='YOUR-KEY', CONSUMER_SECRET='YOUR-SECRET'
consumer_key = ENV["CONSUMER_KEY"]
consumer_secret = ENV["CONSUMER_SECRET"]
access_token = ENV["ACCESS_TOKEN"]
access_token_secret = ENV["ACCESS_TOKEN_SECRET"]

create_tweet_url = "https://api.twitter.com/2/tweets"

# Be sure to add replace the text of the with the text you wish to Tweet.
# You can also add parameters to post polls, quote Tweets, Tweet with reply settings, and Tweet to Super Followers in addition to other features.
@json_payload = {"text": "Hello world! TwitterAPI V2 ハローワールド テスト。URLtest"}

def create_tweet(url, oauth_params)
	options = {
	    :method => :post,
	    headers: {
	     	"User-Agent": "v2CreateTweetRuby",
        "content-type": "application/json"
	    },
	    body: JSON.dump(@json_payload)
	}
	request = Typhoeus::Request.new(url, options)
	oauth_helper = OAuth::Client::Helper.new(request, oauth_params.merge(:request_uri => url))
	request.options[:headers].merge!({"Authorization" => oauth_helper.header}) # Signs the request
	response = request.run

	return response
end

# OAuth Consumerオブジェクトを作成
consumer = OAuth::Consumer.new(consumer_key, consumer_secret,
	:site => 'https://api.twitter.com',
	:debug_output => false)

# OAuth Access Tokenオブジェクトを作成
access_token = OAuth::AccessToken.new(consumer, access_token, access_token_secret)

# OAuthパラメータをまとめたハッシュを作成
oauth_params = {
:consumer => consumer,
:token => access_token,
}

response = create_tweet(create_tweet_url, oauth_params)
puts response.code, JSON.pretty_generate(JSON.parse(response.body))

これでV2でツイートできます

v1でBot作ってた人が欲しがるコードはこっち  クラス版

require 'oauth'
require 'json'
require 'typhoeus'
require 'oauth/request_proxy/typhoeus_request'
require 'dotenv/load'

class TwitterV2
  def self.tweet(text)
    # The code below sets the consumer key and secret from your environment variables
    # To set environment variables on Mac OS X, run the export command below from the terminal:
    # export CONSUMER_KEY='YOUR-KEY', CONSUMER_SECRET='YOUR-SECRET'
    consumer_key = ENV["CONSUMER_KEY"]
    consumer_secret = ENV["CONSUMER_SECRET"]
    access_token = ENV["ACCESS_TOKEN"]
    access_token_secret = ENV["ACCESS_TOKEN_SECRET"]

    create_tweet_url = "https://api.twitter.com/2/tweets"

    # Be sure to add replace the text of the with the text you wish to Tweet.
    # You can also add parameters to post polls, quote Tweets, Tweet with reply settings, and Tweet to Super Followers in addition to other features.
    json_payload = {"text": text}

    def self.create_tweet(url, oauth_params, json_payload)
      options = {
        :method => :post,
        headers: {
          "User-Agent": "v2CreateTweetRuby",
          "content-type": "application/json"
        },
        body: JSON.dump(json_payload)
      }
      request = Typhoeus::Request.new(url, options)
      oauth_helper = OAuth::Client::Helper.new(request, oauth_params.merge(:request_uri => url))
      request.options[:headers].merge!({"Authorization" => oauth_helper.header}) # Signs the request
      response = request.run

      return response
    end

    # OAuth Consumerオブジェクトを作成
    consumer = OAuth::Consumer.new(consumer_key, consumer_secret,
      :site => 'https://api.twitter.com',
      :debug_output => false)

    # OAuth Access Tokenオブジェクトを作成
    access_token = OAuth::AccessToken.new(consumer, access_token, access_token_secret)

    # OAuthパラメータをまとめたハッシュを作成
    oauth_params = {
      :consumer => consumer,
      :token => access_token,
    }

    response = create_tweet(create_tweet_url, oauth_params, json_payload)
    response
  end
end

TwitterV2.tweet("あいうえお")

API v2所感

APIリファレンスを見るとv2のみでメディアファイル添付つきのツイートは難しそうな感じでした。
mediaIDをツイートする感じですがmediaIDそのものを生成するには結局v1が今は必要そうなのでメディアアップロード機能がv2にできない限り今後プログラムからあげるのは難しいんじゃないかなと思いました。誰かできる手段を見つけたらお教えください

11
5
2

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
11
5

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?