Skip to content
This repository has been archived by the owner on Apr 15, 2023. It is now read-only.
Nick Hodge edited this page May 25, 2013 · 44 revisions

Welcome to BoxKite.Twitter

boxkite logo

BoxKite.Twitter is a .NET Portable Class Library that provides an interface to Twitter, licensed MS-PL.

Supporting Windows 8, Windows Phone 8 and .NET 4.5

Questions? You can find me on Twitter, of course! @NickHodgeMSFT

##NuGet Package

Install-Package BoxKite.Twitter -Pre

Introduction

Written in C# as a Portable Class Library, BoxKite.Twitter uses two outstanding third party libraries: Newtonsoft's Json.NET and Microsoft's Portable version of the HTTP Client Libraries. Json.NET converts the incoming/outgoing data as JSON; and generates the objects. The Portable HTTP Client Libraries provides a single "view" of the underlying transport to the Twitter Service. OAuth and the creation of the REST GET/POST mechanisms are inbuilt into BoxKite.Twitter.

Additionally, BoxKite.Twitter uses two modern .NET mechanisms. Async/Await: which makes the programming of network access alarmingly easy and Microsoft's open sourced Reactive Extensions. The latter libraries provide a publish/subscribe model to data - especially streamed data.

The is a backstory on the project name

Twitter API Coverage

At the present time, BoxKite.Twitter supports the Twitter API version 1.1 of the following:

More indepth developer details are documented here

There are a few, small missing pieces documented here

"Live Fire" tests are explained here

Just Show me some Code

These are some snippets from a .NET 4.5 Console application, after installing BoxKite.Twitter via NuGet:

Example 1: Simple Get Tweets

System.Console.WriteLine("Welcome to BoxKite.Twitter from Console");

// Provide a platform specific adaptor for Web browser display and HMACSHA1
// example: https://github.com/nickhodge/BoxKite.Twitter/blob/master/src/Boxkite.Twitter.Console/Helpers/DesktopPlatformAdaptor.cs
// this class need to implement BoxKite.Twitter.IPlatformAdaptor
// source: https://github.com/nickhodge/BoxKite.Twitter/blob/master/src/BoxKite.Twitter/Interfaces/IPlatformAdaptor.cs
var desktopPlatformAdaptor = new DesktopPlatformAdaptor();

// Using consumerkey and consumersecret, start the OAuth1.0a process
var twitterauth = new TwitterAuthenticator(//CONSUMERKEYHERE//, //CONSUMERSECRETHERE//, desktopPlatformAdaptor);
var authstartok = twitterauth.StartAuthentication();

// if OK
if (authstartok.Result)
{
	// Now the User will see a Web browser asking them to log in to Twitter, authorise your app
	// and remember a PIN
	// This PIN is then entered here to complete the Authentication of the Credentials
	System.Console.Write("pin: ");
	var pin = System.Console.ReadLine();
	var twittercredentials = await twitterauth.ConfirmPin(pin);

	// Credentials OK, now OK to communicate with Twitter
	if (twittercredentials.Valid)
	{
		// Create a new "session" using the OK'd credentials and the platform specific stuff
		var session = new UserSession(twittercredentials, desktopPlatformAdaptor);

		// Let's check the user is OK
		var checkUser = await session.GetVerifyCredentials();
		if (!checkUser.twitterFaulted)
		{
			System.Console.WriteLine(twittercredentials.ScreenName +
				" is authorised to use BoxKite.Twitter.");

			// START GOOD STUFF HAPPENS HERE	
			// grab the latest 10 mentions for the Auth'd user
			var mentionslist = await session.GetMentions(count: 10);

			foreach (var tweet in mentionslist)
			{
				System.Console.WriteLine(String.Format("ScreenName: {0}, Tweet: {1}", tweet.User.ScreenName,
					tweet.Text));
			}
			// END GOOD STUFF HAPPENS HERE
		}
		else
		{
			System.Console.WriteLine("Credentials could not be verified");
		}
	}
	else
	{
		System.Console.WriteLine(
			"Authenticator could not start. Do you have the correct Client/Consumer IDs and secrets?");
	}
	System.Console.WriteLine("Press return to exit");
	System.Console.ReadLine();
}

This example starts a fresh client authentication, including the Twitter OAuth1.0 PIN login flow. Then it displays the most recent 10 mentions for the authenticated user.

Note that the twittercredentials can be saved (please do this securely) and be re-used, so much of the OAuth 'ceremony' is once-off.

The other thing to note is the "DesktopPlatformAdaptor". Portable Class Libraries have limits; so to provide an interface to the underlying operating system, BoxKite.Twitter uses an Interface mechanism.

A PlatformAdaptor must implement the BoxKite.Twitter.IPlatformAdaptor interface; and example Desktop adaptor is here

As at BoxKite.Twitter 0.8.0, there is a .NET 4.5 Full version that has the IPlatformAdaptor "pre-installed" to make starting out quicker.

The intellisense when typing var mentionslist = session. you will see all of the calls available to Twitter.

Example 2: Upload a new Avatar

(note: only the code between the // START ... //END GOOD STUFF HAPPENS HERE from Example 1 is shown)

var fileName = @"C:\Users\Nick\Pictures\My Online Avatars\666.jpg";
if (File.Exists(fileName))
{
	var newImage = File.ReadAllBytes(fileName);

	var uploadedimage = await session.ChangeAccountProfileImage("666.jpg", newImage);

	if (uploadedimage.twitterFaulted)
	{
		System.Console.WriteLine(String.Format("Twitter Error: {0} {1}",
		uploadedimage.TwitterControlMessage.twitter_error_code,
		uploadedimage.TwitterControlMessage.twitter_error_message));
	}
	else
	{
		System.Console.WriteLine("All is well");
	}
}

Example 2a Send Tweet with Image, using a FileStream

var fileName = /* some file path here */;

using (var fileStream = new FileStream(fileName, FileMode.Open, FileAccess.Read))
{                               
	var tw = await session.SendTweetWithImage(/* Text of tweet in here */, Path.GetFileName(fileName), fileStream);

	if (!tw.twitterFaulted)
	{
		System.Console.WriteLine(String.Format("Tweet sent: ScreenName: {0}, Tweet: {1}", tw.User.ScreenName, tw.Text))
	}

}

These examples takes a picture from the local file system, and uploads it to Twitter. The current authenticated user's Avatar changes to the new image.

Also shown is the error mechanism. Rather than throwing exceptions everywhere, which makes it difficult to finely manage REST responses, each response to a BoxKite.Twitter call can quickly check:

uploadedimage.twitterFaulted

If true, something is wrong. The attached TwitterControlMessage can be interrogated to determine what is going on.

A good example of a potential response is a "Rate Limit Exceeded" error.

Example 3: User Streams

(note: only the code between the // START ... //END GOOD STUFF HAPPENS HERE from Example 1 is shown)

userstream = session.GetUserStream();
userstream.Tweets.Subscribe(t => System.Console.WriteLine(String.Format("ScreenName: {0}, Tweet: {1}", t.User.ScreenName, t.Text)));
userstream.Start();

while (userstream.IsActive)
{
	 Thread.Sleep(TimeSpan.FromSeconds(0.5));
} 

What is even going on here?

Here, again once the session has been authenticated, we can create a UserStream.

The userstream.Tweets.Subscribe... uses the Reactive Extensions to "listen" for published tweets. BoxKite.Twitter send the t=> ... mechanism each tweet in turn.

There are other things that can be .Subscribed to from the userstream including DirectMessages, etc.

Example 4: Search Streams

(note: only the code between the // START ... //END GOOD STUFF HAPPENS HERE from Example 1 is shown)

searchstream = session.StartSearchStream(track: "xbox");
searchstream.FoundTweets.Subscribe(t => System.Console.WriteLine(String.Format("ScreenName: {0}, Tweet: {1}", t.User.ScreenName, t.Text)));
searchstream.Start();

while (searchstream.IsActive)
{
	Thread.Sleep(TimeSpan.FromMinutes(3));
	var sr = new StreamSearchRequest();
	sr.tracks.Add("windows8");
	searchstream.SearchRequests.Publish(sr);
} 

Similar to Example 3, this creates a Search stream from an authenticated session. Again, using the Reactive Extensions Publish/Subscribe mechanism.

The "track: xbox" is quite self explanatory; in the while loop, we wait for 3 minutes before changing the Search request. You will see the resulting tweets in the stream change.

Clone this wiki locally