Twitter API from C#: Searching
Twitter API from C#: Searching
Following my post Twitter API From C#: Getting a User’s Time Line, I’ll talk about how to use the Twitter Search API.
The main difference between this post and the previous one, is that Twitter Search API currently does not support XML response, and supports only atom and json. So, in order to search for specific terms, I’ll have to take another approach than the one I took before.
Performing a Search
To perform a search in the browser for “DevAcademy3”, I can navigate to: http://search.twitter.com/search?q=devacademy3&show-user=true
In order to get the response in a json format, I’ll use: http://search.twitter.com/search.json?q=devacademy3&show-user=true (added “.json” after the work “search”).
Here’s a sample of the result that contains a list of results with 2 items in it:
{"results":
[
{"text":"Working on my Silverlight demo for #devacademy3",
"to_user_id":null,
"from_user":"bursteg",
"id":997265406,
"from_user_id":145367,
"iso_language_code":"en",
"profile_image_url":"http:\/\/s3.amazonaws.com\/twitter_production\/profile_images\/30327862\/Guy_Burstein_Small_normal.jpg",
"created_at":"Sun, 09 Nov 2008 08:06:24 +0000"},
{"text":"Registration for #devacademy3 should be open this week",
"to_user_id":null,
"from_user":"devacademy3",
"id":996482591,
"from_user_id":2271567,
"iso_language_code":"en",
"profile_image_url":
"http:\/\/s3.amazonaws.com\/twitter_production\/profile_images\/63650042\/DevAcademy3Logo_-_Copy_normal.jpg",
"created_at":"Sat, 08 Nov 2008 16:42:48 +0000"}
],
"since_id":0,
"max_id":998769058,
"refresh_url":"?since_id=998769058&q=devacademy3",
"results_per_page":15,
"page":1,
"query":
"devacademy3"
}
Using the DataContract and DataMember Attributes
In order to extract the data of of this result, I created a SearchResult Class, that will represent a single item in the result, decorated with the appropriate DataContract attributes, that indicate from which attribute in the result should the value be taken.
[DataContract]
public class SearchResult
{
[DataMember(Name = "text", Order = 0)]
public string Text { get; set; }
[DataMember(Name = "to_user_id", Order = 1)]
public int? ToUserId { get; set; }
[DataMember(Name = "from_user", Order = 2)]
public string FromUser { get; set; }
[DataMember(Name = "id", Order = 3)]
public int Id { get; set; }
[DataMember(Name = "from_user_id", Order = 4)]
public int? FromUserId { get; set; }
[DataMember(Name = "iso_language_code", Order = 5)]
public string IsoLanguageCode { get; set; }
[DataMember(Name = "profile_image_url", Order = 6)]
public string ProfileImageUrl { get; set; }
[DataMember(Name = "created_at", Order = 7)]
public string CreatedAt { get; set; }
}
In addition to that, since the items are encapsulated within a list inside an object, I also created the following SearchResults class:
[DataContract]
public class SearchResults
{
public SearchResults()
{
this.Results = new List<SearchResult>();
}
[DataMember(Name = "results")]
public List<SearchResult> Results { get; set; }
}
Using the DataContractJsonSerializer to Extract the Data
Using the WebHttpWegRequest (with the Get method I created in my previous post), I received the response as a string.
This is the code I used in order to deserialize the response into SearchReaults objects (using the DataContractJsonSerializer in System.Runtime.Serialization.Json namespace).
string response =
Get("http://search.twitter.com/search.json?q=devacademy3&show-user=true");
byte[] brr = ASCIIEncoding.UTF8.GetBytes(response);
StreamReader reader = new StreamReader(new MemoryStream(brr));
DataContractJsonSerializer serializer =
new DataContractJsonSerializer(typeof(SearchResults));
SearchResults searchResults =
(SearchResults)serializer.ReadObject(reader.BaseStream);
reader.Close();
Constructing a Meaningful List of Statuses
Now that I have the search results objects, I can construct a meaningful response using the UserStatus class I created in the previous post, and with some transformations and parsing, get the data I wanted to.
List<UserStatus> users =
(from u in searchResults.Results
select new UserStatus
{
UserName = u.FromUser,
ProfileImage = u.ProfileImageUrl,
Status = HttpUtility.HtmlDecode(u.Text),
StatusDate = DateTimeOffset.Parse(u.CreatedAt).UtcDateTime
}).ToList();
Notice I used HttpUtility (in System.Web namespace) in order to decode special characters such as > to their readable characters.
Wrapping it up...
The final version of the Search method looks like this:
public List<UserStatus> Search(string searchTerm)
{
string url =
string.Format("http://search.twitter.com/search.json?&q={0}", searchTerm);
string response = Get(url);
byte[] brr = ASCIIEncoding.UTF8.GetBytes(response);
StreamReader reader = new StreamReader(new MemoryStream(brr));
DataContractJsonSerializer serializer =
new DataContractJsonSerializer(typeof(SearchResults));
SearchResults searchResults =
(SearchResults)serializer.ReadObject(reader.BaseStream);
reader.Close();
List<UserStatus> users =
(from u in searchResults.Results
select new UserStatus
{
UserName = u.FromUser,
ProfileImage = u.ProfileImageUrl,
Status = HttpUtility.HtmlDecode(u.Text),
StatusDate = DateTimeOffset.Parse(u.CreatedAt).UtcDateTime
}).ToList();
return users;
}
Enjoy Twitter Searching with C#!