雑記 / 2014-11-24



[編集]

C# bit.ly でURL短縮 - 2014-11-24

タグ :C#

Visual Studio 2010 Express で C# 、.NET Framework 4.0 で
bit.ly の Web API を呼び出してURL短縮するツールを作ってみる。

Amazon のURLがTwitterに貼るときにクソ長いので、
毎回 bit.ly で短縮かけてる (amazon.co.jp ドメインは bit.ly で短縮すると amzn.to になる)けれど
そのために bit.ly のページのタブを開いておくのは面倒なので、
Windowsクライアントアプリケーションでもう少し楽にできないかなーと思ったのが動機。

  • bit.ly のアカウントを作る
    • Web API にアクセスするにはアカウントを作る必要があるようなので bit.ly の SIGN UP からアカウントを登録しておく。
    • Twitter や Facebook のアカウントでログインできるようにできるが、
      アカウント登録後に SETTING>PROFILE でメールアドレスの有効チェックとかパスワード設定をしておかないとアプリケーションの登録ができないかも?
  • API_KEY でのURL短縮
    • Web API の呼び出しは通常 OAuth で認証してアクセストークン取得して、みたいな流れでやるけれど、
      まずは手軽な API_KEY を使用してURL短縮を試してみる。
      ちなみに API_KEY を使った呼び出し方は DEPRECATED (非推奨) 。今後廃止される可能性もあるので注意。
    • SETTING>ADVANCED で「Legacy API KEY」という項目に Login ID と API key が記載されているのでメモしておく。
      Firefoxだと選択不可領域になっていてコピペできなくて地味に不便。IEだと選択可能みたいだが。
    • Bitly API Documentation - /v3/shorten にURL短縮の呼び出し方が記載されている。
      要は、Login ID と API KEY、それから短縮させたいURLを渡せば、JSON形式、XML形式または短縮URLだけの文字列が取得できる。
      例えば http://google.com/ の短縮URLだけを取得したければ、以下のようなURLでHTTPアクセスさせればいい。
      https://api-ssl.bitly.com/v3/shorten?login=XXXXX&apiKey=XXXXX&longUrl=http://google.com/&format=txt
      
    • C# でやるならば、System.Net.WebClient でやるのが手っ取り早い。
      渡すURLのエスケープ処理も Uri.EscapeUriString() で忘れずにやっておくこと。
      // API_KEY による認証パラメータ
      string STR_AUTH_APIKEY = "login={0}&apiKey={1}";
      
      // URL短縮コマンドURL
      string STR_URL_SHORTEN = @"https://api-ssl.bitly.com/v3/shorten?{0}&longUrl={1}&format=txt";
      
      WebClient wc = new WebClient();
      Stream stream = null;
      StreamReader sreader = null;
      
      string url;
      
      string strResult;
      
      try
      {
              // URL短縮 shorter の呼び出しURL作成
              url = string.Format(STR_URL_SHORTEN, string.Format(STR_AUTH_APIKEY, "[STR_LOGIN_ID]", "[STR_API_KEY]"), 
                  Uri.EscapeUriString("[LONGURL]"));
                      
              stream = wc.OpenRead(url);
              sreader = new StreamReader(stream);
      
              strResult = sreader.ReadToEnd();
      
              // 結果の出力
              MessageBox.Show(strResult);
      }
      catch (Exception ex)
      {
              MessageBox.Show(ex.Message, "ERROR", MessageBoxButtons.OK, MessageBoxIcon.Error);
      }
      finally
      {
              if (stream != null) { stream.Close(); }
              if (sreader != null) { sreader.Close(); }
      }
      
  • OAuth での認証を行ってからのURL短縮
    • OAuth の認証を行うためにアプリケーション固有の CLIENT_ID や CLIENT_SECRET が必要になるので、bit.ly でアプリケーションを登録する。
      SETTING>ADVANCED で、OAuth Applications のリンクからOAuthアプリケーション管理ページが開けるので
      Register an application からアプリケーション登録を行う。
      アプリケーション名やリダイレクト先URL情報などを入力する(私は自サイトURLを入れたが、 bit.ly 自身や google とかのURLでもいいのかどうかは未確認)
      登録すれば CLIENT_ID や CLIENT_SECRET がOAuthアプリケーション管理ページに表示されるようになるのでメモしておく。
    • Bitly API Documentation - Authentication の方法に従って、HTTP POST通信で CLIENT_ID や CLIENT_SECRET、bit.ly アカウントのユーザー名、パスワードを送信してアクセストークンを取得する。
      なお、アクセストークンの取得方法は認証コードを使う方法(Webアプリケーション向き?)とユーザー名、パスワードを使う方法と二種類ある。今回は後者。
      https://api-ssl.bitly.com/oauth/access_token
      Header: Authorization: Basic XXXXXXXX ←「CLIENT_ID:CLIENT_SECRET」をBase64でエンコードした文字列
      POST Data: grant_type=password&username=XXXXX&password=XXXXX
      
    • アクセストークンはJSON形式で取得できるので、System.Runtime.Serialization.Json でパースするとかが必要。
      参照設定で System.Runtime.Serialization の追加をしておく必要あり。
    • アクセストークンが取得できれば、パラメータがLOGIN_IDとAPI_KEYからアクセストークンに変わるだけでAPI_KEYの時と同様のやり方で短縮URLが取得できる。
      [DataContract]
      public class BitlyJsonAToken
      {
          [DataMember]
          public string access_token;
      }
      
      // OAUTH による認証パラメータ
      string STR_AUTH_OAUTH = @"access_token={0}";
      
      // OAUTH 認証URL
      string STR_URL_OAUTH = @"https://api-ssl.bitly.com/oauth/access_token";
      
      // URL短縮コマンドURL
      string STR_URL_SHORTEN = @"https://api-ssl.bitly.com/v3/shorten?{0}&longUrl={1}&format=txt";
      
      WebClient wc = new WebClient();
      Stream stream = null;
      StreamReader sreader = null;
      
      string token;
      string url;
      
      string strResult;
      
      try
      {
              // OAUTH アクセストークン取得
              NameValueCollection postdata = new NameValueCollection();
              postdata.Add("grant_type", "password");
              postdata.Add("username", "[STR_USERNAME]");
              postdata.Add("password", "[STR_PASSWORD]");
              wc.Headers.Add("Authorization", "Basic " + 
                  Convert.ToBase64String(Encoding.ASCII.GetBytes(
                      string.Format("{0}:{1}", "STR_CLIENT_ID", "[STR_CLIENT_SECRET]")
                  ))
              );
      
              strResult = Encoding.Default.GetString(wc.UploadValues(STR_URL_OAUTH, postdata));
      
              // JSON形式のデータからアクセストークン抽出
              DataContractJsonSerializer jserial = new DataContractJsonSerializer(typeof(BitlyJsonAToken));
              MemoryStream mstream = new MemoryStream(Encoding.Default.GetBytes(strResult));
              BitlyJsonAToken jdata = (BitlyJsonAToken)jserial.ReadObject(mstream);
      
              if (string.IsNullOrEmpty(jdata.access_token))
              {
                  throw new Exception("アクセストークンの取得に失敗しました。");
              }
              token = jdata.access_token;
      
              // URL短縮 shorter の呼び出しURL作成
              /url = string.Format(STR_URL_SHORTEN, string.Format(STR_AUTH_OAUTH, token), Uri.EscapeUriString("[LONGURL]"));
      
              stream = wc.OpenRead(url);
              sreader = new StreamReader(stream);
      
              strResult = sreader.ReadToEnd();
      
              // 結果の出力
              MessageBox.Show(strResult);
      }
      catch (Exception ex)
      {
              MessageBox.Show(ex.Message, "ERROR", MessageBoxButtons.OK, MessageBoxIcon.Error);
      }
      finally
      {
              if (stream != null) { stream.Close(); }
              if (sreader != null) { sreader.Close(); }
      }