I have just created a Twitter "App" for a simplistic conference demo in which my software tool is supposed to do a post to Twitter programmatically via dotnet. I am using the LinqToTwitter
library from github. I was easily able to locate my Consumer Key (API Key)
, Consumer Secret (API Secret)
, accessToken
and accessTokenSecret
here:
But LinqToTwitter also requires an oauthToken
and oauthTokenSecret
which I cannot find anywhere in my Twitter app settings or account settings. Where can I find these two values?
I found a chunk of c# sample code that works great, and discovered that those additional 2 keys are unnecessary (or autogenerated perhaps). Here is the simple code that works GREAT for simply doing a twitter post to your own account:
using System;
using System.Configuration;
using System.IO;
using System.Net;
using System.Security.Cryptography;
using System.Text;
namespace TwitterTest
{
class Program
{
static void Main(string[] args)
{
var tweet = new Twitter();
tweet.SendTweet("Test from Visual Studio @ " + DateTime.Now);
Console.WriteLine("Tweet sent!");
Console.ReadLine();
}
}
public class Twitter
{
private string oAuthConsumerKey = ConfigurationManager.AppSettings["ConsumerKey"];
private string oAuthConsumerSecret = ConfigurationManager.AppSettings["ConsumerSecret"];
private string accessToken = ConfigurationManager.AppSettings["AccessToken"];
private string accessTokenSecret = ConfigurationManager.AppSettings["AccessTokenSecret"];
string oAuthUrl = "https://api.twitter.com/1.1/statuses/update.json";
public void SendTweet(string message)
{
string authHeader = GenerateAuthorizationHeader(message);
string postBody = "status=" + Uri.EscapeDataString(message);
HttpWebRequest authRequest = (HttpWebRequest)WebRequest.Create(oAuthUrl);
authRequest.Headers.Add("Authorization", authHeader);
authRequest.Method = "POST";
authRequest.UserAgent = "OAuth gem v0.4.4";
authRequest.Host = "api.twitter.com";
authRequest.ContentType = "application/x-www-form-urlencoded;charset=UTF-8";
authRequest.ServicePoint.Expect100Continue = false;
authRequest.AutomaticDecompression = DecompressionMethods.GZip | DecompressionMethods.Deflate;
using (Stream stream = authRequest.GetRequestStream())
{
byte[] content = Encoding.UTF8.GetBytes(postBody);
stream.Write(content, 0, content.Length);
}
WebResponse authResponse = authRequest.GetResponse();
authResponse.Close();
}
private string GenerateAuthorizationHeader(string status)
{
string signatureMethod = "HMAC-SHA1";
string version = "1.0";
string nonce = GenerateNonce();
double timestamp = ConvertToUnixTimestamp(DateTime.Now);
string dst = string.Empty;
dst = string.Empty;
dst += "OAuth ";
dst += string.Format("oauth_consumer_key=\"{0}\", ", Uri.EscapeDataString(oAuthConsumerKey));
dst += string.Format("oauth_nonce=\"{0}\", ", Uri.EscapeDataString(nonce));
dst += string.Format("oauth_signature=\"{0}\", ", Uri.EscapeDataString(GenerateOauthSignature(status, nonce, timestamp.ToString())));
dst += string.Format("oauth_signature_method=\"{0}\", ", Uri.EscapeDataString(signatureMethod));
dst += string.Format("oauth_timestamp=\"{0}\", ", timestamp);
dst += string.Format("oauth_token=\"{0}\", ", Uri.EscapeDataString(accessToken));
dst += string.Format("oauth_version=\"{0}\"", Uri.EscapeDataString(version));
return dst;
}
private string GenerateOauthSignature(string status, string nonce, string timestamp)
{
string signatureMethod = "HMAC-SHA1";
string version = "1.0";
string result = string.Empty;
string dst = string.Empty;
dst += string.Format("oauth_consumer_key={0}&", Uri.EscapeDataString(oAuthConsumerKey));
dst += string.Format("oauth_nonce={0}&", Uri.EscapeDataString(nonce));
dst += string.Format("oauth_signature_method={0}&", Uri.EscapeDataString(signatureMethod));
dst += string.Format("oauth_timestamp={0}&", timestamp);
dst += string.Format("oauth_token={0}&", Uri.EscapeDataString(accessToken));
dst += string.Format("oauth_version={0}&", Uri.EscapeDataString(version));
dst += string.Format("status={0}", Uri.EscapeDataString(status));
string signingKey = string.Empty;
signingKey = string.Format("{0}&{1}", Uri.EscapeDataString(oAuthConsumerSecret), Uri.EscapeDataString(accessTokenSecret));
result += "POST&";
result += Uri.EscapeDataString(oAuthUrl);
result += "&";
result += Uri.EscapeDataString(dst);
HMACSHA1 hmac = new HMACSHA1();
hmac.Key = Encoding.UTF8.GetBytes(signingKey);
byte[] databuff = System.Text.Encoding.UTF8.GetBytes(result);
byte[] hashbytes = hmac.ComputeHash(databuff);
return Convert.ToBase64String(hashbytes);
}
private string GenerateNonce()
{
string nonce = string.Empty;
var rand = new Random();
int next = 0;
for (var i = 0; i < 32; i++)
{
next = rand.Next(65, 90);
char c = Convert.ToChar(next);
nonce += c;
}
return nonce;
}
public static double ConvertToUnixTimestamp(DateTime date)
{
DateTime origin = new DateTime(1970, 1, 1, 0, 0, 0, 0);
TimeSpan diff = date.ToUniversalTime() - origin;
return Math.Floor(diff.TotalSeconds);
}
}
}
Note: You need to set up your App.config thusly:
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<appSettings>
<add key="ConsumerKey" value="xxx"/>
<add key="ConsumerSecret" value="xxx"/>
<add key="AccessToken" value="xxx"/>
<add key="AccessTokenSecret" value="xxx"/>
</appSettings>
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5.2" />
</startup>
</configuration>