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

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

概要

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

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

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

Twitpic APIキーの取得

続いて、TwitpicのAPIキーを取得します。
Twitpicのページにアクセスします。右側の"How do I use Twitpic"の「API」のリンクをクリックします。


「Register」のリンクをクリックします。


アプリケーションを登録します。アプリケーションのタイトルや概要を記入します。記入できたら「Register Application」ボタンをクリックします。

TwitpicのAPIキーが取得できます。

右上の「Your Apps」リンクをクリックすると登録されているアプリケーションの一覧とキーが表示され確認できます。


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

以下の手順でtwitpicに画像をアップロードします
  1. TwitterのOAuthのシグネチャーを取得します。(OAuthBase.csのGenerateSignature()を使います。) 生成したシグネチャーとTimeStamp,nonceの3つをX-Verify-Credentials-Authorizationの値として使います。
  2. twitpicへ画像を投稿(ポスト)するためのHttpWebRequestを準備します。これをwebRequestとします
  3. webRequestのヘッダに"X-Auth-Service-Provider"を追加します。値は認証プロバイダのURLとします。今回は認証プロバイダはTwitterになりますので、"https://api.twitter.com/1/account/verify_credentials.json" となります。
  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. TwipicAPIキー(key)の作成
      1. バウンダリのヘッダを挿入します。
      2. Content-Disposition: form-data; name="key" ヘッダを挿入します。
      3. 空行を挿入しヘッダを終了します
      4. twitpicのAPIキー文字列を挿入します
    3. コメント(message)の作成
      1. Content-Disposition: form-data; name="message" ヘッダを挿入します。
      2. 空行を挿入しヘッダを終了します
      3. 画像に追加するメッセージを挿入します。
    4. バウンダリのフッタを追加します。フッタの形式は "--(バウンダリ文字列)--" となります。
  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 oAuthEchoWebRequestForTwitpic(Method method, string url, 
  string auth_provider_url, string auth_realm_url, 
  byte[] image, string imageName, string postMessage,
  string TwitpicAPIKey, 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 = "POST";
  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(TwitpicAPIKey);

    contents.AppendLine(header);
    contents.AppendLine(String.Format(
      "Content-Disposition: form-data; name=\"{0:s}\"", "message"));
    contents.AppendLine();
    contents.AppendLine(postMessage+"/"+DateTime.Now.ToString());
      //同じ文字は拒否されるため、時刻を付加
            
    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 PostPictureToTwitpic(byte[] image, string imageName, string comment, 
  string ConsumerKey, string ConsumerSecret, string AccessToken, string AccessTokenSecret,
  string TwitpicKey, string PictureContentType)
{
  string twitpic_api_url = "http://api.twitpic.com/2/upload.json";
  string auth_provider_url = "https://api.twitter.com/1/account/verify_credentials.json";
  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.oAuthEchoWebRequestForTwitpic(oAuthTwitter.Method.POST,
    twitpic_api_url, auth_provider_url, auth_realm_url,
    image, imageName, comment,
    TwitpicKey, contentEncoding, PictureContentType);
}

アプリケーションの実装

今回はWinFromアプリケーションを新規作成し、ボタンを1つ配置しClickイベントに以下を実装しました
    
private void button1_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.PostPictureToTwitpic(img, "pic.jpg", "test", 
    ConsumerKey, ConsumerSecret, AccessToken, AccessTokenSecret, TwitpicKey,
    PictureContentType);
}
ConsumerKey, ConsumerSecret, AccessToken, AccessTokenSecret, TwitpicKeyには取得したキーを代入しておきます。
アプリケーションを実行し、ボタンをクリックすると実行ファイルのあるフォルダの中のimgフォルダに置いてあるpic.jpgをtwitpicにアップロードします。


参考URL: http://blogs.southworks.net/jpgarcia/2010/07/31/using-twitpic-api-20-oauth-echo-from-a-c-client-to-upload-pictures/
著者
iPentecのプログラマー、最近はAIの積極的な活用にも取り組み中。
とっても恥ずかしがり。
最終更新日: 2024-01-06
作成日: 2010-10-15
iPentec all rights reserverd.