YFrogに画像をアップロードする (古いOAuth Echo認証APIを利用) - C#

注意
この記事で紹介している方法は 2010年時点の方法です。現在はYFrogのサービス終了のため動作しませんので、ご注意ください。

概要

YFrogの古いOAuth認証方式のAPIを使って画像をYFrogにアップロードしてみます。
OAuthを使ってTwitterにツイートを投稿する際に利用したライブラリ(oAuthBase.csなど)を使います。

Twitter へのアプリケーション登録とアクセスキーの取得

Twitterへのアプリケーション登録とアクセスキーを取得する必要があります。手順はデスクトップアプリケーションの場合はこちら、ASP.NETなどのwebアプリケーションの場合はこちらです。

OAuth Echoを使って(古い認証方式のAPIで)YFrogに画像をアップロードする手順の概要

以下の手順でYFrogに画像をアップロードします
  1. TwitterのOAuthのシグネチャーを取得します。(OAuthBase.csのGenerateSignature()を使います。) 生成したシグネチャーとTimeStamp,nonceの3つをverify_urlの値として使います。
  2. YFrogへ画像を投稿(ポスト)するためのHttpWebRequestを準備します。これをwebRequestとします
  3. 本文(content)を作成します。
    1. 画像(media)の作成
      1. バウンダリのヘッダを挿入します。ヘッダの形式は "--(バウンダリ文字列)" となります。バウンダリ文字列はユニークな文字列にするため、Guid.NewGuid()メソッドで作成します。
      2. Content-Disposition: file; name="media"; filename="ファイル名" ヘッダを追加します。mediaはTwitpicのAPIで指定されているパラメータ名です。
      3. Content-Type: image/jpeg のContent-Typeヘッダを追加します。アップロードする画像の形式に合わせます。
      4. 空行を挿入しヘッダを終了します
      5. 画像データを挿入します。
    2. verify_urlの作成
      1. バウンダリのヘッダを挿入します。
      2. Content-Disposition: form-data; name="verify_url" ヘッダを挿入します。
      3. 空行を挿入しヘッダを終了します
      4. verify_urlを挿入します。verify_urlについては後述します。
    3. authパラメータの作成
      1. バウンダリのヘッダを挿入します。
      2. Content-Disposition: form-data; name="auth" ヘッダを挿入します。
      3. 空行を挿入しヘッダを終了します
      4. 文字列"oauth"を挿入します。
    4. messageパラメータの作成
      1. バウンダリのヘッダを挿入します。
      2. Content-Disposition: form-data; name="message" ヘッダを挿入します。
      3. 空行を挿入しヘッダを終了します
      4. 投稿するメッセージを挿入します。
    5. バウンダリのフッタを追加します。フッタの形式は "--(バウンダリ文字列)--" となります。
  4. 本文を"iso-8859-1"でエンコードします。
  5. webRequest.GetRequestStream();メソッドを使い、書き込み用のストリームを取得します。
  6. エンコードした本文を書き込みます。
  7. レスポンスを取得し正常に書き込めたかをチェックします。

verify_urlについて

verify_urlの値は以下の通りです。
https://api.twitter.com/1/account/verify_credentials.xml?oauth_version=1.0&oauth_nonce=(シグネチャー生成時のnonce)&oauth_timestamp=(シグネチャー生成時のタイムスタンプ)&oauth_consumer_key=(TwitterのConsumerKey)&oauth_token=(TwitterのAcessToken)&oauth_signature_method=HMAC-SHA1&oauth_signature=(シグネチャー)
となります。
  • (TwitterのConsumerKey),(TwitterのAcessToken)はTwitterから取得したキーを設定します。
  • (シグネチャー生成時のタイムスタンプ),(シグネチャー生成時のnonce),(シグネチャー)はOAuthのシグネチャー生成時のものを使います。
  • oauth_signatureパラメータに設定するシグネチャーはURLエンコードします。

プログラムの実装

Oauthを使ってTwitterのAPIを呼び出すライブラリのコードに以下を実装します。

oAuthBase.csへの実装

変更はありません。

oAuthTwitter.csへの実装

public string oAuthEchoWebRequestForYFrogOld(
  Method method, string url, string auth_provider_url, byte[] image, string imageName,
  string postMessage, Encoding ContentEncoding, string FileContentType, string UserName)
{
  HttpWebRequest webRequest = null;
  string responseData = "";

  webRequest = System.Net.WebRequest.Create(url) as HttpWebRequest;
  webRequest.Method = method.ToString();
  webRequest.ServicePoint.Expect100Continue = false;

  var boundary = Guid.NewGuid().ToString();
  webRequest.ContentType = string.Format("multipart/form-data; boundary={0}", boundary);

  string outUrl = "";
  string querystring = "";
  string ret = "";

  //Generate Signature
  Uri uri = new Uri(auth_provider_url);
  string nonce = this.GenerateNonce();
  string timeStamp = this.GenerateTimeStamp();
  string sig = this.GenerateSignature(uri,
      this.ConsumerKey,
      this.ConsumerSecret,
      this.Token,
      this.TokenSecret,
      "GET",
      timeStamp,
      nonce,
      out outUrl,
      out querystring);

  if (method == Method.POST) {
    string header = string.Format("--{0}", boundary);
    string footer = string.Format("--{0}--", boundary);

    StringBuilder contents = new StringBuilder();
    contents.AppendLine(header);

    string fileHeader = string.Format(
      "Content-Disposition: file; name=\"{0:s}\"; filename=\"{1:s}\"", "media", imageName);
    string fileData = ContentEncoding.GetString(image);

    contents.AppendLine(fileHeader);
    contents.AppendLine(string.Format("Content-Type: {0:s}", FileContentType));
    contents.AppendLine();
    contents.AppendLine(fileData);

    contents.AppendLine(header);
    contents.AppendLine(string.Format("Content-Disposition: form-data; name=\"{0:s}\"",
      "username"));
    contents.AppendLine();
    contents.AppendLine(UserName);

    string credentialPattern = "oauth_version=1.0&oauth_nonce={0:s}"
      + "&oauth_timestamp={1:s}&oauth_consumer_key={2:s}&oauth_token={3:s}"
      + "&oauth_signature_method=HMAC-SHA1&oauth_signature={4:s}";
    string credential = string.Format(credentialPattern,
      nonce, timeStamp, this.ConsumerKey, this.Token, HttpUtility.UrlEncode(sig));
    string CredentialURL = auth_provider_url + "?" + credential;

    contents.AppendLine(header);
    contents.AppendLine(
      string.Format("Content-Disposition: form-data; name=\"{0:s}\"", "verify_url"));
    contents.AppendLine();
    contents.AppendLine(CredentialURL);

    contents.AppendLine(header);
    contents.AppendLine(string.Format(
      "Content-Disposition: form-data; name=\"{0:s}\"", "auth"));
    contents.AppendLine();
    contents.AppendLine("oauth");

    contents.AppendLine(header);
    contents.AppendLine(string.Format(
      "Content-Disposition: form-data; name=\"{0:s}\"", "message"));
    contents.AppendLine();
    contents.AppendLine(postMessage);

    contents.AppendLine(footer);

    byte[] bytes = ContentEncoding.GetBytes(contents.ToString());
    webRequest.ContentLength = bytes.Length;

    Stream requestWriter = webRequest.GetRequestStream();
    try {
      requestWriter.Write(bytes, 0, bytes.Length);
    }
    catch {
      throw;
    }
    finally {
      requestWriter.Close();
      requestWriter = null;
    }
  }
  responseData = WebResponseGet(webRequest);
  webRequest = null;
  return responseData;
}

TwitterUtils.csへの実装

public void PostPictureToYFrogOld(byte[] image, string imageName, string comment, 
  string ConsumerKey, string ConsumerSecret, string AccessToken, string AccessTokenSecret,
  string PictureContentType, string UserName)
{
  string yfrog_api_url = "http://yfrog.com/api/upload";
  string auth_provider_url = "https://api.twitter.com/1/account/verify_credentials.xml";

  string contentEncodingStr = "iso-8859-1";
  Encoding contentEncoding = Encoding.GetEncoding(contentEncodingStr);
      
  oAuth.ConsumerKey = ConsumerKey;
  oAuth.ConsumerSecret = ConsumerSecret;
  oAuth.Token = AccessToken;
  oAuth.TokenSecret = AccessTokenSecret;

  oAuth.oAuthEchoWebRequestForYFrogOld(oAuthTwitter.Method.POST,
    yfrog_api_url, auth_provider_url, image, imageName, comment,
    contentEncoding, PictureContentType, UserName);
}

呼び出し側アプリケーションの実装

private void button4_Click(object sender, EventArgs e)
{
  string UserName="Twiter_ScreenName";
  string PictureContentType="image/jpeg"; //または "image/png"

  string apppath = Path.GetDirectoryName(Application.ExecutablePath);
  FileStream  fs = new FileStream(apppath + @"\img\pic.jpg", FileMode.Open);
  byte[] img = new byte[fs.Length];
  int r = fs.Read(img, 0, (int)fs.Length);

  TwitterUtils tu = new TwitterUtils();
  tu.PostPictureToYFrogOld(img, "pic.jpg", "test",
    ConsumerKey, ConsumerSecret, AccessToken, AccessTokenSecret,
    PictureContentType, UserName);
}
ConsumerKey, ConsumerSecret, AccessToken, AccessTokenSecretには取得したキーを代入しておきます。
アプリケーションを実行し、ボタンをクリックすると実行ファイルのあるフォルダの中のimgフォルダに置いてあるpic.jpgをYFrogにアップロードします。
著者
iPentecのプログラマー、最近はAIの積極的な活用にも取り組み中。
とっても恥ずかしがり。
最終更新日: 2024-01-06
作成日: 2010-10-20
iPentec all rights reserverd.