Getting a Twitter interface on your site
If you are using Twitter, you may want to mashup your tweets into your web
application. You may even want to give your site admin (you!) the facility to
update your Twitter status from within your application.
Fortunately, the Twitter API uses a straightforward interface which is easily
manipulated from an ASP.NET application. Full details of the Twitter API are
available from the Twitter API Wiki.
Getting your Twitter status into your ASP.NET application
The Twitter function calls use REST to allow a flexible mechanism for accessing
indformation. Information can be retrieved in several format, but for our
purposes the simplest formats are as an RSS formatted XML file or a plain XML
file. The RSS format provides a simplified format for the information, but the
XML format provides complete information about a user and their updates.
The simplest method is to call the Twitter user_timeline function. You can call
the function by requesting the information in either XML or RSS format. The
format for the call is:
http://twitter.com/statuses/user_timeline/userid.type
for a public Twitter feed, or:
http://twitter.com/statuses/user_timeline.type
for a private Twitter feed, though the private mechanism requires user
authentication.
Note: .type is replaced by either .rss or .xml, depending on the format you
want to get back.
The choice of RSS or XML depends on the level of information which you want
back from Twitter. The XML format provides more detail, but in either case it is
simply a matter of retrieving the response from the request and extracting the
relevant information from the XML tags which are returned.
Getting information from the RSS request
The first requirement is to make use of the WebClient class, optionally provide
authentication (if your tweets are not public), request the status using the URL
from above, and then unpack the reply, placing it into a suitable format within
your web page. The basic code for extracting status reports from the RSS request
and dropping them into a <dl> element is shown below:
WebClient twitter = new WebClient();
twitter.Credentials = // only needed for non-public tweets
new NetworkCredential("userid", "password");
Stream tweets = twitter.OpenRead
("http://twitter.com/statuses/user_timeline/userid.rss");
XmlDocument mytweets = new XmlDocument();
mytweets.Load(tweets);
litTweets.Text = "\n<dl>\n";
foreach (XmlNode status in mytweets.GetElementsByTagName("item"))
{
DateTime tim = Convert.ToDateTime
(status.SelectSingleNode("pubDate").InnerText);
string text = status.SelectSingleNode("description").InnerText;
text = text.Substring(text.IndexOf(":")+ 2);
litTweets.Text += string.Format
(" <dt>{0:D} {0:t}</dt>\n <dd>{1}</dd>\n", tim, text);
}
litTweets.Text += "</dl>\n";
Note how the pubDate element from the RSS feed is converted back to a DateTime
object so that it can be processed. If you want to display the time using
Twitter's conventional relative time format you can use the DateTime methods to
calculate the offset from the current time. For example:
WebClient twitter = new WebClient();
Stream tweets =
twitter.OpenRead
("http://twitter.com/statuses/user_timeline/johnpscott.rss");
XmlDocument mytweets = new XmlDocument();
mytweets.Load(tweets);
litTweets.Text = "\n <dl>\n";
foreach (XmlNode status in mytweets.GetElementsByTagName("item"))
{
DateTime pubDate =
Convert.ToDateTime
(status.SelectSingleNode("pubDate").InnerText);
long ticks = DateTime.UtcNow.Ticks - pubDate.Ticks;
TimeSpan elapsed = new TimeSpan(ticks);
string tim;
if (elapsed.Days > 1)
tim = string.Format("about {0} days ago", elapsed.Days);
else if (elapsed.Days > 0)
tim = "about a day ago";
else if (elapsed.Hours > 1)
tim = string.Format("about {0} hours ago", elapsed.Hours);
else if (elapsed.Hours > 0)
tim = "about an hour ago";
else if (elapsed.Minutes > 1)
tim = string.Format
("about {0} minutes ago", elapsed.Minutes);
else if (elapsed.Minutes > 0)
tim = "about 1 minute ago";
else if (elapsed.Seconds > 10)
tim = string.Format
("about {0} seconds ago", elapsed.Seconds);
else tim = "within the last 10 seconds";
string text = status.SelectSingleNode("description").InnerText;
text = text.Substring(text.IndexOf(":") + 2);
litTweets.Text += string.Format
(" <dt>{0}</dt>\n <dd>{1}</dd>\n", tim, text);
}
litTweets.Text += " </dl>\n";
Check out a demonstration of this code.
Getting information from the XML request
The advantage of the XML request is that the response from Twitter provides a
complete status record for each of the users updates, whereas the RSS request
only returns basic information. So the XML request allows you to include more
information about each update, including such thins as the origin of the update
and a link to the user's photo.
However, the main stumbling block is that the date/time format used in the XML
response doesn't get recognised by the ASP.NET Convert.ToDateTime method. This
means you have to do a bit of work to extract the Date Time from the response.
This is the date time format returned by the RSS response:
Fri, 06 Mar 2009 15:26:40 +0000
This is what is returned by the XML response:
Fri Mar 06 15:26:40 +0000 2009
It is a simple matter to convert the XML date format to match the RSS date
format. e.g.
protected DateTime CreatedAt(string raw)
{
string rssText = raw.Substring(8, 3) // Day
+ raw.Substring(4, 4) // Month
+ raw.Substring(26, 4) // Year
+ raw.Substring(10, 15); // Time & offset
return Convert.ToDateTime(rssText);
}
The demonstration page shows use of the following elements from the XML
response:
- created_at - the time of the update
- user/name - the full name of the user
- text - the text of the update
- user/profile_image_url - a URL to the users profile image
- source - the source of the update (web or txt)
Check out a demonstration of this code.
Updating your status on Twitter
The Twitter API allows you to POST updates from your applications, however, it
would be unwise to provide a generic update page for any user to to use to post
their updates unless you can demonstrate that your site is trusted. After all,
your application would be handling usernames and passwords for end users. This
mini-tutorial will show how you can provide an admin only page (secured by some
user authentication on the site of course) which will allow you to update your
(or your site's) status on Twitter.
We can use the same mechanism to generate a WebClient call to the Twitter API,
but in this case you must make sure the call uses POST to pass the update
string, and of course the call requires authentication with Twitter. You just
need a TextBox to hold your status message, and a button to call the update
code. The code
is very straightforward:
System.Net.ServicePointManager.Expect100Continue
= false; // Fixes problem with Twitter POST calls
WebClient twitter = new WebClient();
twitter.Headers.Add
("Content-Type", "application/x-www-form-urlencoded");
twitter.Credentials =
new NetworkCredential("twitterid", "password");
byte[] response = twitter.UploadData
("http://twitter.com/statuses/update.xml",
"POST",
Encoding.UTF8.GetBytes("status=" + TextBox1.Text));
At this point the response is in a byte array. If you want to use the response
to provide feedback from the call you can convert the byte array into a string
using the call:
XmlDocument responseXML = new XmlDocument();
responseXML.LoadXml(Encoding.UTF8.GetString(response));
At this point you are free to parse the results and display them on your page.