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

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

概要

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

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

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

APIキーの取得

YFrogのトップページにアクセスします。トップページのフッタ部分の[API]リンクをクリックします。


APIのページが表示されますページ左側の、Request a key:の欄の「Request a key」リンクをクリックします。


API Key Request Formが表示されますので入力します。


入力を終え、[submit]ボタンをクリックするとAPI Keyが取得できます。


OAuth Echoを使ってYFrogに画像をアップロードする手順の概要

以下の手順でYFrogに画像をアップロードします
  1. TwitterのOAuthのシグネチャーを取得します。(OAuthBase.csのGenerateSignature()を使います。) 生成したシグネチャーとTimeStamp,nonceの3つをX-Verify-Credentials-Authorizationの値として使います。
  2. YFrogへ画像を投稿(ポスト)するためのHttpWebRequestを準備します。これをwebRequestとします
  3. webRequestのヘッダに"X-Auth-Service-Provider"を追加します。値は認証プロバイダのURLとします。今回は認証プロバイダはTwitterになりますので、"https://api.twitter.com/1/account/verify_credentials.xml" となります。
  4. webRequestのヘッダに"X-Verify-Credentials-Authorization"を追加します。値は後述します。
  5. 本文(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. YFrogAPIキー(key)の作成
      1. バウンダリのヘッダを挿入します。
      2. Content-Disposition: form-data; name="key" ヘッダを挿入します。
      3. 空行を挿入しヘッダを終了します
      4. YFrogのAPIキー文字列を挿入します
    3. バウンダリのフッタを追加します。フッタの形式は "--(バウンダリ文字列)--" となります。
  6. 本文を"iso-8859-1"でエンコードします。
  7. webRequest.GetRequestStream();メソッドを使い、書き込み用のストリームを取得します。
  8. エンコードした本文を書き込みます。
  9. レスポンスを取得し正常に書き込めたかをチェックします。

X-Verify-Credentials-Authorization の値について

X-Verify-Credentials-Authorization の値は以下の通りです。
OAuth realm="(RealmURL)", oauth_consumer_key="(TwitterのConsumerKey)", oauth_signature_method="HMAC-SHA1", oauth_token="(TwitterのAcessToken)", oauth_timestamp="(シグネチャー生成時のタイムスタンプ)", oauth_nonce="(シグネチャー生成時のnonce)", oauth_version="1.0", oauth_signature="(シグネチャー)"
となります。
  • (RealmURL)は "http://api.twitter.com/" となります。
  • (TwitterのConsumerKey),(TwitterのAcessToken)はTwitterから取得したキーを設定します。
  • (シグネチャー生成時のタイムスタンプ),(シグネチャー生成時のnonce),(シグネチャー)はOAuthのシグネチャー生成時のものを使います。

プログラムの実装

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

oAuthBase.csへの実装

変更はありません。

oAuthTwitter.csへの実装

public string oAuthEchoWebRequestForYFrog(Method method, string url,
  string auth_provider_url, string auth_realm_url, byte[] image, string imageName, 
  string YFrogAPIKey, Encoding ContentEncoding, string FileContentType)
{
  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);

  webRequest.Headers.Add("X-Auth-Service-Provider", auth_provider_url);

  string oauthSignaturePattern
  = "OAuth realm=\"{0:s}\", oauth_consumer_key=\"{1:s}\", oauth_signature_method=\"HMAC-SHA1\","
  + " oauth_token=\"{2:s}\", oauth_timestamp=\"{3:s}\", oauth_nonce=\"{4:s}\","
  + " oauth_version=\"1.0\", oauth_signature=\"{5:s}\"";

  string authorizationHeader = string.Format(
                    System.Globalization.CultureInfo.InvariantCulture,
                    oauthSignaturePattern,
                    auth_realm_url,
                    this.ConsumerKey,
                    this.Token,
                    timeStamp,
                    nonce,
                    HttpUtility.UrlEncode(sig));

  webRequest.Headers.Add("X-Verify-Credentials-Authorization", authorizationHeader);
  webRequest.Method = method.ToString();

  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}\"", "key"));
    contents.AppendLine();
    contents.AppendLine(YFrogAPIKey);

    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 PostPictureToYFrog(byte[] image, string imageName, 
  string ConsumerKey, string ConsumerSecret, string AccessToken, string AccessTokenSecret,
  string YFrogAPIKey, string PictureContentType)
{
  string yfrog_api_url = "https://yfrog.com/api/xauth_upload";
  string auth_provider_url = "https://api.twitter.com/1/account/verify_credentials.xml";
  string auth_realm_url = "http://api.twitter.com/";

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

  oAuth.oAuthEchoWebRequestForYFrog(oAuthTwitter.Method.POST, 
    yfrog_api_url, auth_provider_url, auth_realm_url,
    image, imageName, YFrogAPIKey, contentEncoding, PictureContentType);
}

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

private void button3_Click(object sender, EventArgs e)
{
  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.PostPictureToYFrog(img, "pic.jpg", 
    ConsumerKey, ConsumerSecret, AccessToken, AccessTokenSecret, YFrogKey, PictureContentType);
}
ConsumerKey, ConsumerSecret, AccessToken, AccessTokenSecret, YFrogKeyには取得したキーを代入しておきます。
アプリケーションを実行し、ボタンをクリックすると実行ファイルのあるフォルダの中のimgフォルダに置いてあるpic.jpgをYFrogにアップロードします。
著者
iPentecのプログラマー、最近はAIの積極的な活用にも取り組み中。
とっても恥ずかしがり。
最終更新日: 2024-01-07
作成日: 2010-10-20
iPentec all rights reserverd.