using System;
using System.Diagnostics;
using System.IO;
using System.Net;
using System.Security.Cryptography;
using System.Text;
using System.Web;
/*
* この辺を参考に:
*
* http://oauth.net/core/1.0
* http://hueniverse.com/oauth/guide/authentication/
* https://dev.twitter.com/docs/auth/authorizing-request
*/
namespace Direct_Commit_Twitter
{
class Program
{
static void Main(string[] args)
{
//
// 使うパラメータは次のようなもの。
//
// OAuth Consumer Key : Consumer Key そのまま。
// OAuth Token : Access Token そのまま。 (今回はこれも取得。)
// OAuth Nonce : ランダム文字列を与える。 (毎回変更する。)
// OAuth Signature : OAuth Signature 以外の値で HMAC-SHA1 をとった値。
// OAuth Signature Method : Twitter は HMAC-SHA1 指定っぽいので HMAC-SHA1.
// OAuth Time Stamp : UNIX 時間 (1970-01-01 UTC からの秒数) を与える。
// : (今回は GetUNIXTime() メソッドで取得します。)
// OAuth Version : 今回は 1.0 を使うので、1.0.
//
string consumer_key = "oDcUp76alv6VctYvRx2g";
string consumer_secret = "mg1U9TEFVafIPQm0Y0YuLR8EZatXiDBvPLiiCConzbg";
string access_token = "";
string access_secret = "";
string tweet_text = "ゲソーゲソー";
/************************ 以下、黙々と処理 ********************/
string[] verify_token;
if (access_token == "" || access_secret == "")
{
#region 01. Request Token を取得しなイカ?
{
Console.WriteLine("01 - Token を取得しなイカ?");
Console.WriteLine("-------------------------------------------------");
Random rand = new Random();
byte[] nonce_b = new byte[64];
rand.NextBytes(nonce_b);
string nonce = Math.Abs(BitConverter.ToInt64(nonce_b, 0)).ToString();
long unixtime = GetUNIXTime();
//
// OAuth Signature 生成のために、それ以外で仮のリクエスト文字列を作成する。
// この際、各パラメータは ABC 順にソートされている必要がある。
//
string signature_request = "POST&" + UrlEncode("https://api.twitter.com/oauth/request_token");
signature_request += "&" + UrlEncode(MakeParamString(consumer_key, nonce, null, unixtime, null, null, null));
//
// ちゃんとしたリクエスト文字列を作る。
//
string signature = GetSignature(consumer_secret, null, signature_request);
string param = MakeParamString(consumer_key, nonce, signature, unixtime, null, null, null);
DebugParamOut(consumer_key, consumer_secret, nonce, signature, unixtime, null, null, null);
return;
//
// 問い合わせ。
//
Console.WriteLine("* Access : https://api.twitter.com/oauth/request_token?" + param);
HttpWebRequest hwr = (HttpWebRequest)HttpWebRequest.Create("https://api.twitter.com/oauth/request_token?" + param);
hwr.Method = "POST";
WebResponse ret = hwr.GetResponse();
verify_token = new StreamReader(ret.GetResponseStream()).ReadToEnd().Split('&');
ret.Close();
Console.WriteLine();
Console.WriteLine("Response : ");
foreach (string s in verify_token)
Console.WriteLine("> " + s);
}
#endregion
#region 02. Access Token を取得しなイカ?
{
Console.WriteLine();
Console.WriteLine("02 - Access Token を取得しなイカ?");
Console.WriteLine("-------------------------------------------------");
string request_token = "";
string request_secret = "";
//
// ブラウザ開いて認証。
//
foreach (string s in verify_token)
{
int p = s.IndexOf("oauth_token=");
if (p != -1)
{
request_token = s.Substring(p + "oauth_token=".Length);
break;
}
}
Console.WriteLine("- OAuth Token : " + request_token);
Console.WriteLine("* Browser Open : https://twitter.com/oauth/authorize?oauth_token=" + request_token);
Process.Start("https://twitter.com/oauth/authorize?oauth_token=" + request_token);
//
// PIN を入力させる。
//
Console.Write("\nINPUT PIN : ");
string pin = Console.ReadLine();
foreach (string s in verify_token)
{
int p = s.IndexOf("oauth_token_secret=");
if (p != -1)
{
request_secret = s.Substring(p + "oauth_token_secret=".Length);
break;
}
}
//
// 以下 Twitter ともくもく通信。
//
Random rand = new Random();
byte[] nonce_b = new byte[64];
rand.NextBytes(nonce_b);
string nonce = Math.Abs(BitConverter.ToInt64(nonce_b, 0)).ToString();
long unixtime = GetUNIXTime();
//
// Signature 生成のための一時的なリクエスト文字列を作成。
//
string signature_request = "POST&" + UrlEncode("https://api.twitter.com/oauth/access_token");
signature_request += "&" + UrlEncode(MakeParamString(consumer_key, nonce, null, unixtime, request_token, pin, null));
string signature = GetSignature(consumer_secret, request_secret, signature_request);
string param = MakeParamString(consumer_key, nonce, signature, unixtime, request_token, pin, null);
DebugParamOut(consumer_key, consumer_secret, nonce, signature, unixtime, request_token, request_secret, pin);
//
// 問い合わせ。
//
Console.WriteLine("* Access : https://api.twitter.com/oauth/access_token?" + param);
HttpWebRequest hwr = (HttpWebRequest)HttpWebRequest.Create("https://api.twitter.com/oauth/access_token?" + param);
hwr.Method = "POST";
hwr.Headers.Add("Authorization", "OAuth");
WebResponse ret = hwr.GetResponse();
verify_token = new StreamReader(ret.GetResponseStream()).ReadToEnd().Split('&');
ret.Close();
Console.WriteLine();
Console.WriteLine("Response : ");
foreach (string s in verify_token)
{
if (s.IndexOf("oauth_token=") != -1)
access_token = s.Substring(s.IndexOf("=") + 1);
if (s.IndexOf("oauth_token_secret=") != -1)
access_secret = s.Substring(s.IndexOf("=") + 1);
Console.WriteLine("> " + s);
}
}
#endregion
}
#region 03. つぶやかなイカ?
{
Console.WriteLine();
Console.WriteLine("03 - つぶやかなイカ?");
Console.WriteLine("-------------------------------------------------");
Random rand = new Random();
byte[] nonce_b = new byte[64];
rand.NextBytes(nonce_b);
string nonce = Math.Abs(BitConverter.ToInt64(nonce_b, 0)).ToString();
long unixtime = GetUNIXTime();
string tweet_data = UrlEncode(tweet_text);
string signature_request = "POST&" + UrlEncode("https://api.twitter.com/1/statuses/update.xml");
signature_request += "&include_entities%3Dtrue%26" + UrlEncode(MakeParamString(consumer_key, nonce, null, unixtime, access_token, null, tweet_data));
string signature = GetSignature(consumer_secret, access_secret, signature_request);
string header_param = "OAuth oauth_consumer_key=\"" + UrlEncode(consumer_key) + "\",oauth_signature_method=\"HMAC-SHA1\"," +
"oauth_timestamp=\"" + unixtime + "\",oauth_nonce=\"" + UrlEncode(nonce) + "\"," +
"oauth_version=\"1.0\",oauth_token=\"" + UrlEncode(access_token) + "\"," +
"oauth_signature=\"" + UrlEncode(signature) + "\",";
DebugParamOut(consumer_key, consumer_secret, nonce, signature, unixtime, access_token, access_secret, null);
Console.WriteLine("* Access : https://api.twitter.com/1/statuses/update.xml");
Console.WriteLine("* Tweet at : " + tweet_text);
HttpWebRequest hwr = (HttpWebRequest)HttpWebRequest.Create("https://api.twitter.com/1/statuses/update.xml");
hwr.Method = "POST";
hwr.ServicePoint.Expect100Continue = false;
hwr.Headers.Add(HttpRequestHeader.Authorization, header_param);
hwr.ContentType = "application/x-www-form-urlencoded";
var s = new StreamWriter(hwr.GetRequestStream());
s.Write("status=" + tweet_data + "&include_entities=true");
s.Close();
WebResponse ret = hwr.GetResponse();
Console.WriteLine();
Console.WriteLine("Response:");
Console.WriteLine("> "+(new StreamReader(ret.GetResponseStream()).ReadToEnd()));
}
#endregion
}
// UNIX 時間を返す。
static long GetUNIXTime()
{
return (long)(DateTime.UtcNow - new DateTime(1970, 1, 1)).TotalSeconds;
}
// URLエンコード (どうやらエスケープ文字は大文字にしないといけないらしい。)
static string UrlEncode(string str)
{
string s = HttpUtility.UrlEncode(str);
return _UrlEncodeUpper(s);
}
static string _UrlEncodeUpper(string str)
{
int p = str.IndexOf("%");
if (p != -1)
{
str = str.Substring(0, p) + str.Substring(p, 3).ToUpper() + _UrlEncodeUpper(str.Substring(p + 3));
}
return str;
}
// パラメータ文字列を生成
static string MakeParamString(string oauth_consumer_key, string oauth_nonce, string oauth_signature, long oauth_timestamp, string oauth_token, string oauth_verifier, string status)
{
string param = "oauth_consumer_key=" + oauth_consumer_key + "&oauth_nonce=" + oauth_nonce;
if (oauth_signature != null)
param += "&oauth_signature=" + oauth_signature;
param += "&oauth_signature_method=HMAC-SHA1" + "&oauth_timestamp=" + oauth_timestamp;
if (oauth_token != null)
param += "&oauth_token=" + oauth_token;
if (oauth_verifier != null)
param += "&oauth_verifier=" + oauth_verifier;
param += "&oauth_version=1.0";
if (status != null)
param += "&status=" + status;
return param;
}
// Consumer Secret をKey とした、リクエスト文字列のハッシュを求める。
static string GetSignature(string consumer_secret, string access_token_secret, string param)
{
HMACSHA1 hmacsha1 = new HMACSHA1();
hmacsha1.Key = Encoding.ASCII.GetBytes(consumer_secret + "&" + access_token_secret);
byte[] hash = hmacsha1.ComputeHash(Encoding.ASCII.GetBytes(param));
return Convert.ToBase64String(hash);
}
// よくやる出力をまとめてみる。
static void DebugParamOut(string oauth_consumer_key, string oauth_consumer_secret, string oauth_nonce, string oauth_signature, long oauth_timestamp, string oauth_token, string oauth_token_secret, string oauth_verifier)
{
Console.WriteLine("- OAuth Consumer Key = " + oauth_consumer_key);
Console.WriteLine("- OAuth Consumer Secret = " + oauth_consumer_secret);
Console.WriteLine("- OAuth Nonce = " + oauth_nonce);
if (oauth_signature != null)
Console.WriteLine("- OAuth Signature = " + oauth_signature);
Console.WriteLine("- OAuth Time Stamp = " + oauth_timestamp);
if (oauth_token != null)
Console.WriteLine("- OAuth Access Token = " + oauth_token);
if (oauth_token_secret != null)
Console.WriteLine("- OAuth Access Token Secret = " + oauth_token_secret);
if (oauth_verifier != null)
Console.WriteLine("- OAuth Verifier = " + oauth_verifier);
}
}
}