Tag Archives: HttpClient

Azure Functions

Azure functions are Microsoft’s answer to “serverless” architecture. The concept behind Serverless Architecture being that you can create service functionality, but you don’t need to worry about a server. Obviously, there is one: it’s not magic; it’s just not your problem.

How?

Let’s start by creating a new Azure function app:

Once created, search “All resources”; you might need to give it a minute or two:

Next, it asks you to pick function type. In this case, we’re going to pick “Custom function”:

Azure then displays a plethora of options for creating your function. We’re going to go for “Generic Webhook” (and name it):

A Webhook is a http callback; meaning that you can use them in the same way as you would any other HTTP service.

This creates your function (with some default code):

We’ll leave the default code, and run it (because you can’t go wrong with default code – it always does exactly what you need… assuming what you need is what it does):

The right hand panel shows the output from the function. Which means that the function works; so, we now have a web based function that works… well… says hello world (ish). How do we call it?

Using the function

The function has an allocated URL:

Given that we have a service, and a connection URL; the rest is pretty straightforward. Let’s try to connect from a console application:

        static void Main(string[] args)
        {
            HttpClient client = new HttpClient();
            string url = "https://pcm-test.azurewebsites.net/api/pcm_GenericWebhookCSharp1?code=Kk2397soUoaK7hbxQa6qUSMV2S/AvLCvjn508ujAJMMZiita5TsjkQ==";

            var inputObject = new
            {
                first = "pcm-Test-input-first",
                last = "pcm-Test-input-last"
            };
            string param = JsonConvert.SerializeObject(inputObject);
            HttpContent content = new StringContent(param, Encoding.UTF8, "application/json");

            HttpResponseMessage response = client.PostAsync(url, content).Result;
            string results = response.Content.ReadAsStringAsync().Result;

            Console.WriteLine($"results: {results}");
            Console.ReadLine();
        }
    }

When run, this returns:

Conclusion

Let’s think about what we’ve just done here: we have set up a service, connected to that service from a remote source and returned data. Now, let’s think about what we haven’t done: any configuration; that is, other than clicking “Create Function”.

This “serverless” architecture seems to be the nth degree of SOA. If I wish, I can create one of these functions for each of the server activities in my application, they are available to anything with an internet connection. It then becomes Microsoft’s problem if my new website suddenly takes off and millions of people are trying to access it.

References

http://robertmayer.se/2016/04/19/azure-function-app-to-send-emails/

http://www.c-sharpcorner.com/article/azure-functions-create-generic-webhook-trigger/

Loading a Twitter Feed in WinRT

Recently, Twitter in their wisdom, discontinued the support for atom feed.  I have a couple of programs that were interrogating this, and they all suddenly (and gracefully I might add) stopped working.

The changeover is not that straightforward, especially if you don’t want to use third party libraries.

Introduction and Caveat

What I’m trying to achieve with this post is to collate all the information that I’ve gathered into a single place, so that switching from the old atom Twitter search:

string atomTweetSearchURL = string.Format("http://search.twitter.com/search.atom?q={0}", searchText);

…to the new OAuth2 can be achieved without looking anywhere else.

This is based on a Windows Store app.  There are some features that will be specific to a Store App, but I have no reason to believe this wouldn’t be generally applicable (and possible in a similar fashion) outside of the RT environment.  Having said that, there are other resources more applicable if you have access to the full .NET framework.

Finally, I have made use of lots of internet help. Where possible, I’ll link the appropriate articles, but if I forget to, just assume that the code you see here was either directly taken, or adapted from something I found online.

A last point, if you use libraries such as Linq to Twitter and JSON.NET, you’ll make your life easier; personally, I wanted to do this without a third party library.

Twitter Configuration

Previously, the URL above would allow you to simply interrogate the Twitter stream and Twitter didn’t need to know about who you were. That is now replaced. You don’t necessarily need to log-in as a user, you can use Application Only Identification. To set this up, visit https://apps.twitter.com/app/new

twitterappdetails

Only the first three boxes are required information. If you are developing a Windows 8 App then the Website can be a deep link to your application; for example, mine was here:

http://apps.microsoft.com/windows/app/geegeeeight/26d0e292-ca89-4ad6-bddc-cde3f2f9e7eb

Once you click on the button to create a new app:

CreateTwitterApp

You will be provided with a Key and a Secret. These are long strings of numbers and letters that will identify your app.

JSON Helpers

We’ll be dealing in JSON. As such, you need to be able to serialise and de-serialise JSON data. The first thing to do is to create a helper class such as follows:

    class JSonSerialiserHelper
    {

        public static T Deserialize<T>(string json)
        {
            var _Bytes = Encoding.Unicode.GetBytes(json);
            using (MemoryStream _Stream = new MemoryStream(_Bytes))
            {
                var _Serializer = new DataContractJsonSerializer(typeof(T));
                return (T)_Serializer.ReadObject(_Stream);
            }
        }

        public static string Serialize(object instance)
        {
            using (MemoryStream _Stream = new MemoryStream())
            {
                var _Serializer = new DataContractJsonSerializer(instance.GetType());
                _Serializer.WriteObject(_Stream, instance);
                _Stream.Position = 0;
                using (StreamReader _Reader = new StreamReader(_Stream)) 
                { return _Reader.ReadToEnd(); }
            }
        }
    }

You’ll also need to deal with dates, so add this, too:

        internal static DateTime ConvertDate(string dateIn)
        {
            // http://blog.kevinyu.org/2012/07/handling-json-in-net.html
            const string Const_TwitterDateTemplate = "ddd MMM dd HH:mm:ss +ffff yyyy";
            DateTime createdAt = DateTime.ParseExact(dateIn, Const_TwitterDateTemplate, new System.Globalization.CultureInfo("en-GB"));

            return createdAt;
        }

Obviously if you’re not in Britain you may wish to change the culture.

Get a Token

There is now a two step authentication; it works like this:
1. Send your application details (key and secret) to Twitter and get an Authorisation Token
2. Use the token to search Twitter with your criteria

The Key and Secret are what you obtained above when you registered your app; the code below should get you a token with that information:

        // http://stackoverflow.com/questions/22733283/twitter-oauth2-using-winrt
        private async Task<TwitAuthenticateResponse> TwitterOAuth(string key, string secret)
        {
            var client = new HttpClient();
            var uri = new Uri("https://api.twitter.com/oauth2/token");

            var encodedConsumerKey = WebUtility.UrlEncode(key);
            var encodedConsumerSecret = WebUtility.UrlEncode(secret);
            var combinedKeys = String.Format("{0}:{1}", encodedConsumerKey, encodedConsumerSecret);
            
            var utfBytes = System.Text.Encoding.UTF8.GetBytes(combinedKeys);
            var encodedString = Convert.ToBase64String(utfBytes);

            client.DefaultRequestHeaders.Add("Authorization", string.Format("Basic {0}", encodedString));

            var data = new List<KeyValuePair<string, string>> 
            { 
                new KeyValuePair<string, string>("grant_type", "client_credentials") 
            };

            var postData = new FormUrlEncodedContent(data);

            var response = await client.PostAsync(uri, postData);
            TwitAuthenticateResponse authenticationResponse;
            using (response)
            {
                if (response.StatusCode != System.Net.HttpStatusCode.OK)
                    throw new Exception("Error.  Authentication Failed.");

                var content = await response.Content.ReadAsStringAsync();
                authenticationResponse = JSonSerialiserHelper.Deserialize<TwitAuthenticateResponse>(content);
                if (authenticationResponse.token_type != "bearer")
                    throw new Exception("Wrong result type.  Authentication failed.");

                return authenticationResponse;
            }            
        }

TwitAuthenticateResponse looks like this:

    public class TwitAuthenticateResponse
    {
        public string token_type { get; set; }
        public string access_token { get; set; }        
    }

If you call that, you should have a valid token:

var auth = await TwitterOAuth("key", "secret");

Now the search

Now you have the authentication, you can use that to call the search; here’s the code:

        // http://stackoverflow.com/questions/23671600/using-a-token-to-search-on-twitter-with-oauth2
        private async Task<string> SearchTwitter(string accessToken, string srchStr)
        {
            var client = new HttpClient();
            var searchUrl = string.Format("https://api.twitter.com/1.1/search/tweets.json?q={0}", srchStr);
            var uri = new Uri(searchUrl);

            client.DefaultRequestHeaders.Add("Authorization", string.Format("Bearer {0}", accessToken));

            HttpResponseMessage response = await client.GetAsync(uri);
            string content = await response.Content.ReadAsStringAsync();

            return content;
        }

And here’s the call:

string srch = await SearchTwitter(auth.access_token, searchText);

What to do with the results?

Okay – you can use JSON.NET as mentioned before; however, here’s a way to do it without.

First, you need to declare some classes to hold the data:

    public class TwitSearchResult
    {
        public StatusClass[] statuses { get; set; }

    }

    public class TwitUser
    {
        public string ScreenName { get; set; }
    }

    public class StatusClass
    {
        public string text { get; set; }
        public string source { get; set; }
        public TwitUser user { get; set; }
        public string created_at { get; set; }
    }

Finally, use the helper classes above to deserialise what you get back:

            TwitSearchResult srchResult = JSonSerialiserHelper.Deserialize<TwitSearchResult>(srch);

Summary

The final top level call now looks like this:

            var auth = await TwitterOAuth("key", "secret");
            string srch = await SearchTwitter(auth.access_token, searchText);

            TwitSearchResult srchResult = JSonSerialiserHelper.Deserialize<TwitSearchResult>(srch);

Conclusion

Like I said before, if I’ve used your code and not credited you then it’s not intentional. My aim was just to get all this into a single place for future reference. If you’d like me to reference anything that isn’t referenced then contact me or leave a message.