2010年3月3日水曜日

第19回 短縮URLサービスを利用する

twitterは140文字までなので、長いURLを短いURLにするサービスがよく使われています。
短縮URLサービスとして今一番よく見るbit.lyを利用してみたいと思います。

まずbit.lyでアカウントを取得してください。
※もちろん、アプリ作成者のアカウントをアプリ利用者全員が共用するようにも作ることができますが、
個々にアカウント取得が不要な代わりに、bit.lyで集計されるデータも取得が難しくなると思います。
今回は利用者に取得してもらうようにします。

取得した情報を保存するクラスを作ります。


 public class BitlySetting {
  public string Version { get; set; }
  public string LoginName { get; set; }
  public string APIKey { get; set; }
 }


このクラスはOptionクラスに持たせておきます(コード略)
※Optionクラスは今回からシングルトン構造にしています。



 class BitlyUtility {
  /// <summary>
  /// URLを短縮する
  /// </summary>
  /// <param name="longUrl">短縮したいURL</param>
  /// <param name="setting">Bitlyにログインするための情報</param>
  /// <returns>短縮されたURL</returns>
  public static string Shorten(string longUrl, BitlySetting setting) {
   var result = longUrl;
   var response = WebUtility.GetResponseWithoutAuth(
    @"http://api.bit.ly/shorten",
    "GET",
    new RequestParameter[] {
     new RequestParameter("login", setting.LoginName),
     new RequestParameter("apiKey", setting.APIKey),
     new RequestParameter("version", setting.Version),
     new RequestParameter("format", "xml"),
     new RequestParameter("longUrl", longUrl)
    }
   );
   using (var stream = response.GetResponseStream()) {
    var doc = new XmlDocument();
    doc.Load(stream);
    var elements = doc.GetElementsByTagName("shortUrl");
    if (elements.Count > 0) {
     result = elements[0].InnerText;
    }
   }
   response.Close();
   return result;
  }
 }



最初は他の箇所では全部JSONでやりとりしているので、
今回もJSONで取得しようと思っていましたが、
取得してみた結果、


"{\n
    \"errorCode\": 0, \n
    \"errorMessage\": \"\", \n
    \"results\": {\n
        \"http://wtwitter.codeplex.com/\": {\n
・・・以下略

のようにキー:値のペアの『キー』が短縮前のURLになっている、
→キーが動的に変わる
→DataContractJsonSerializerで扱えない(DataMemberを指定できない)
というわけで、XMLにしました。
JSONにこだわるならJSON.Netとかを使う手もありますが、
blogを見ている人ができるだけ環境をそろえる手間を省くために
標準の環境でできる方法を優先します。

あとはSubmitPanelViewModelでこの関数を使って、
編集中のテキストの中のURLを変換します。


<pre class="prettyprint">
  public void ShortenUrl() {
   var regex = new Regex(RegexPatterns.UrlPattern);
   var matches = regex.Matches(this.EditingText);
   foreach (Match m in matches) {
    var shortUrl = BitlyUtility.Shorten(m.Value, Option.Instance.Bitly);
    EditingText = EditingText.Replace(m.Value, shortUrl);
   }
  }

</pre>


あとはViewModelにCommandを追加して、
ViewにはそのCommandを呼び出すボタンを追加しています。

それ以外にもボタンを追加していますが、それは見たらすぐわかると思いますので、略。

今回のソースコード
http://wtwitter.codeplex.com/SourceControl/changeset/view/42219

3 件のコメント:

  1. bitlyのXMLは要素名に問題あると聞いた覚えが…
    と思ってググッたらこんなのありました。
    その後に仕様が変わってるかもしれませんが。

    http://d.hatena.ne.jp/d11/20090917/1253176846

    返信削除
  2. 情報ありがとうございます!
    見た感じ短縮する方向には問題が起きないようなので、
    伸長するときにどうするか考えますね。
    (正確に言えば、問題があるのならばbit.lyを使わないのが一番ですが、
    bit.lyがもっとも使われている現状では
    他のすべてのクライアントも使わないようにしてもらわないと
    うちのクライアントだけ使わないようにしてもほとんど解決にならないので。。)

    返信削除
  3. バグがありました。
    今回のソースコード、返信時の宛先にいれるのを
    ScreenNameにしなければならないところを
    Nameにしていました。申し訳ありません。
    リンク先ソースコードは修正前です。

    なぜ気づかなかったんだろう。。。

    返信削除