bit.ly (短縮URL) API呼び出し (その2)

bit.ly (短縮URL) API呼び出し (その1) - m-kawato@hatena_diary

bit.ly APIの様子がつかめてきたので、本題のTwitter投稿のためのURL短縮を試してみます。
ここでは、入力としてメッセージ本文とURLを受け取り、必要に応じてURLを短縮URLに変換した形で本文とURLを連結します。

特に面倒な処理は必要ありませんが、入力中のURLがURLとして正当かどうかをチェックするために、Rubyの標準ライブラリuriを使用しています。

#!/usr/bin/ruby -Ku

require 'rubygems'
require 'net/http'
Net::HTTP.version_1_2
require 'json'
require 'jcode'
require 'uri'

BIT_LY_AUTH = 'login=<ユーザID>&apiKey=<APIキー>'

class String
  # 文字列を指定した長さに切り詰める
  def truncate(length)
    return self if self.jlength <= length
    i = 0
    new_string = ''
    self.each_char {|char|
      break if i >= length
      new_string << char
      i += 1
    }
    return new_string
  end
end

# bit.ly APIを呼び出して、URLを短縮URLに変換
def shorten_url(long_url)
  query = "version=2.0.1&longUrl=#{long_url}&#{BIT_LY_AUTH}"
  result = JSON.parse(Net::HTTP.get("api.bit.ly", "/shorten?#{query}"))
  result['results'].each_pair {|key, value|
    if key == long_url
      return value['shortUrl']
    end
  }
  raise "failed to shorten URL: #{long_url}"
end

# body: メッセージ本文とlong_url: URLから、必要に応じて短縮URLを含む
# twitterステータスメッセージを生成
def compose_message(body, long_url)
  URI.parse(long_url) # long_urlがURIとして正当であるかをチェック
  if body.jlength + long_url.length + 1 > 140
    short_url = shorten_url(long_url)
    if body.jlength + short_url.length + 1 > 140
      return body.truncate(137 - short_url.length) + ".. " + short_url
    else
      return body + " " + short_url
    end
  else
    return body + " " + long_url
  end
end

def print_report(body, url, message)
  puts "----------------------------"
  puts %|body: length = #{body.jlength}, content = "#{body}"|
  puts %|url: length = #{url.length}, content = "#{url}"|
  puts %|message: length = #{message.jlength}, content = "#{message}"|
  puts
end

body = "短いメッセージ。URLは変換されません。"
url = "http://www.atmarkit.co.jp/fcoding/articles/reading/05/reading05a.html"
message = compose_message(body, url)
print_report(body, url, message)

body = "長いメッセージ。URLはbit.lyを通して短縮URLに変換されます。This is a long message. The URL is converted into a short URL via bit.ly."
url = "http://www.atmarkit.co.jp/fcoding/articles/reading/05/reading05a.html"
message = compose_message(body, url)
print_report(body, url, message)

body = "不正なURLを入力した場合"
url = "不正なURL"
message = compose_message(body, long_url)
print_report(body, url, message)

実行結果:

----------------------------
body: length = 20, content = "短いメッセージ。URLは変換されません。"
url: length = 69, content = "http://www.atmarkit.co.jp/fcoding/articles/reading/05/reading05a.html"
message: length = 90, content = "短いメッセージ。URLは変換されません。 http://www.atmarkit.co.jp/fcoding/articles/reading/05/reading05a.html"

----------------------------
body: length = 108, content = "長いメッセージ。URLはbit.lyを通して短縮URLに変換されます。This is a long message. The URL is converted into a short URL via bit.ly."
url: length = 69, content = "http://www.atmarkit.co.jp/fcoding/articles/reading/05/reading05a.html"
message: length = 129, content = "長いメッセージ。URLはbit.lyを通して短縮URLに変換されます。This is a long message. The URL is converted into a short URL via bit.ly. http://bit.ly/18N7T0"

/usr/local/lib/ruby/1.8/uri/common.rb:436:in `split': bad URI(is not URI?): 不正なURL (URI::InvalidURIError)
        from /usr/local/lib/ruby/1.8/uri/common.rb:485:in `parse'
        from test2.rb:42:in `compose_message'
        from test2.rb:75