SakuraWi - BLog

WEBエンジニア。聴いたお話をまとめておく倉庫的な。スタックストックスタック!

Ruby on Railsを使ってtwitterに画像付きtweetをするぞ


wip記事ですが、追記していきます。

Ruby on Rails使って、twitterにガンガン画像をあげてやろう、画像付きtweetをしようという記事です。

Twitter::REST::Request.new(@client, :post, "https://upload.twitter.com/1.1/media/upload.json", command: 'APPEND', media_id: media_id, media_data: file, segment_index: 0).perform

これ、media_dataにしてbase64でデコード済みのものを渡そうとするとエラる。

Twitter::Error::Unauthorized: Could not authenticate you.

きみ、認証できてへんで。なんでや!!

    Twitter::REST::Request.new(@client, :post, "https://upload.twitter.com/1.1/media/upload.json", command: 'APPEND', media_id: media_id, media: file, segment_index: 0).perform

media にして、fileを params[:image]のように直接デコードしないままのものを受け取って投げて見たります。 が。FINALIZEで失敗して以下のエラーが。

Twitter::Error::BadRequest: Segments do not add up to provided total file size.

結局

サーバの方の処理は以下な感じ(まだ整理も何もしてない)

    base_file = Base64.decode64(params[:image])
    file = params[:image]
    init_request = Twitter::REST::Request.new(@client, :post, "https://upload.twitter.com/1.1/media/upload.json", command: 'INIT', total_bytes: base_file.size ,media_type: 'image/jpeg').perform
    media_id = init_request[:media_id]
    Twitter::REST::Request.new(@client, :post, "https://upload.twitter.com/1.1/media/upload.json", command: 'APPEND', media_id: media_id, media: file, segment_index: 0).perform

    Twitter::REST::Request.new(@client, :post, "https://upload.twitter.com/1.1/media/upload.json", command: 'STATUS', media_id: media_id, media: file).perform
    Twitter::REST::Request.new(@client, :post, "https://upload.twitter.com/1.1/media/upload.json", command: 'FINALIZE',media_id: media_id).perform
    Twitter::REST::Request.new(@client, :post, "https://api.twitter.com/1.1/statuses/update.json", status: "test with image", media_ids: media_id).perform

名前ぐっちゃんぐっちゃんですが、デコードしてるファイルでサイズ測ってupするのは、デコードしてないバイナリなデータ。

jsの方はこんなかんじに。

      var imgData = canvas.toDataURL("image/jpeg");
      var data = { "image" : imgData.replace(/^.*,/, '') }

      $.ajax({
        url: "twitter_post",
        type: "POST",
        beforeSend: function(xhr) {xhr.setRequestHeader('X-CSRF-Token', $('meta[name="csrf-token"]').attr('content'))},
        data: data,
  • canvas.toDataURL("image/jpeg");
  • var data = { "image" : imgData.replace(/^.*,/, '') } あたりがハマりそう。 今は一旦動いてるよっていところですが。。。 .replace(/^.*,/, '')で画像の前についてるjpegの指定している文字列とかを消してます。