Resize An Instagram Image Using A Media Query Parameter

This is something I have been meaning to post for quite some time, ever since I first started working on integrating Instagram's API in web applications from 2013. - The ability to resize an image from Instagram without having to deal with registering for an API key and worrying about request limits.

This approach is ideal if you have no requirement to get further information about an image, such as description, comments, likes etc.

Believe it or not, Instagram contains quite a neat (somewhat hidden) feature that gives you the ability to output three different sized images directly into a webpage, by constructing the path to an image as so: https://www.instagram.com/p/<image-id>/media/?size=<size-parameter>.

The supported "size parameters" are:

  • t - for thumbnail (150px x 150px)
  • m - for medium (306px x 306px)
  • l - for large (640px x 640px) 

The great thing about using the media parameter is that the requested image size is served up immediately. For example, we could embed an Instagram image directly into our HTML markup as so:

<p style="text-align: center;">
  <img alt="Mr. Brown - The Office Dog" src="https://www.instagram.com/p/uz_8x2qW6E/media/?size=m">
</p>

Which will render the following output:

Mr. Brown - The Office Dog

In this case, this is a picture of Mr. Brown (the office dog) from my Instagram profile in medium size.

Some New Custom Form Controls I've Been Working On In Kentico...

Over the last few projects I've been working on, I started to notice that clients are requiring increased integration with social platforms that give them the ability to display key elements from well known social platforms, such as YouTube, Twitter and Instagram. Hence the reason why in the past I created a YouTube Form Control that would easily retrieve all information information about a video along with their screen caps by simply entering the YouTube URL.

Recently, I've been working on two more form controls involving Twitter and Instagram to further enhance social platform integration within Kentico from a user standpoint, which (I think) is quite neat!

Twitter

Using a combination of OAuth and Twitter's GET statuses/show/:id API endpoint, I was able to store within Kentico all JSON data relating to a tweet by just entering the ID. One major advantage to storing JSON data is that we can display the tweet as many times as we want throughout the site without worrying about breaching API limits.

In addition, individual elements of a tweet, such as the embedded image, hash tags and author information can be used when required.

Tweet Custom Form Control

As you can see (above), I am using Twitter's Embedded Tweet plugin to display the tweet in a nice graphical representation so that the site administrator is able to view contents of the tweet prior to publishing live.

Instagram

Like the Twitter control above, details of an Instagram image is retrieved in a similar fashion, whereby I'm storing all the details in JSON format.  In this case, I'm using a combination of two Instagram API endpoint's:

  • /oembed - to get the core information of an image by passing in the full URL of where the image resides. This will return important piece of information: the true ID of the image.
  • /media/media-id - to get all information about the media or video object. This information will be stored in Kentico.

Unlike Twitter, Instagram's API is a breeze to implement. There are no API limits (at time of writing) and all you need to access the endpoints is to generate a one time only access token.

Instagram Custom Form Control

By copying and pasting the link of an Instagram image will return all object information and display the image/video within CMS Desk.

I will at some point write a blog post on how I created these two controls once I have refactored all the code into one single control. At the moment, some key functionality is segregated into separate class libraries.

Instagram API: Get Access Token In ASP.NET

I've written some code that outputs images using Instagram's Developer API. The code can either output images based on a user's profile or via search term.

As you may already know, in order to get any form of information from any external API an access token is required. Before we dive into some code, the first thing that we need to do is register ourselves as an Instagram Developer by going to: http://instagram.com/developer/.

Next, we need to register a new client specifically for our intended use. In my case, all I want to do is to get all image information from my own Instagram profile.

Instagram API - Register New Client

Here, you will be supplied with Client ID and Client Secret codes. But most importantly, you will need to set an OAuth Redirect URL (or Callback URL) for user's to authenticate your application.

The strange thing I've noticed about the Instagram API is that a callback page is a compulsory requirement. Even if you are planning on carrying out something as simple as listing some images from your own profile where a public users intervention is not required.

I'm not interested in their images, I'm interested in my own. I hope Instagram changes this soon. If Twitter can allow you to retrieve tweets by simply registering your application, why can't Instagram?

From what I've read on Instagram's Google Group's is that an access token needs to only be generated once and they don't expire. But of course Instagram have stated:

"These tokens are unique to a user and should be stored securely. Access tokens may expire at any time in the future."

Just make sure you have some fail safe's in your code that carries out the re-authentication process within your application on the event access token has expired. In my own implementation, I've kept the callback page secret and new access token requests can be made within an Administration interface.

So lets get to the code.

Step 1: Authentication Request Classes

These strongly-typed classes mirror the exact structure of the JSON returned from our authentication request. Even though we only require the "access_token" property, I've added additional information, such as details on the Instagram user making the request.

public class AuthToken
{
    [JsonProperty("access_token")]
    public string AccessToken { get; set; }

    [JsonProperty("user")]
    public InstagramUser User { get; set; }
}
public class InstagramUser
{
    [JsonProperty("id")]
    public string ID { get; set; }

    [JsonProperty("username")]
    public string Username { get; set; }

    [JsonProperty("full_name")]
    public string FullName { get; set; }

    [JsonProperty("profile_picture")]
    public string ProfilePicture { get; set; }
}

It's worth noting at this point that I'm using Newtonsoft.Json framework.

Step 2: Callback Page

protected void Page_Load(object sender, EventArgs e)
{
    if (!String.IsNullOrEmpty(Request["code"]) && !Page.IsPostBack)
    {
        try
        {
            string code = Request["code"].ToString();

            NameValueCollection parameters = new NameValueCollection();
            parameters.Add("client_id", ConfigurationManager.AppSettings["instagram.clientid"].ToString());
            parameters.Add("client_secret", ConfigurationManager.AppSettings["instagram.clientsecret"].ToString());
            parameters.Add("grant_type", "authorization_code");
            parameters.Add("redirect_uri", ConfigurationManager.AppSettings["instagram.redirecturi"].ToString());
            parameters.Add("code", code);

            WebClient client = new WebClient();
            var result = client.UploadValues("https://api.instagram.com/oauth/access_token", "POST", parameters);

            var response = System.Text.Encoding.Default.GetString(result);

            var jsResult = JsonConvert.DeserializeObject(response);

            //Store Access token in database
            InstagramAPI.StoreAccessToken(jsResult.AccessToken);

            Response.Redirect("/CallbackSummary.aspx?status=success", false);
        }
        catch (Exception ex)
        {  
            EventLogProvider.LogException("Instagram - Generate Authentication Key", "INSTAGRAM", ex);

            Response.Redirect("/CallbackSummary.aspx?status=error");
        }
    }
}

As you can see, I'm redirecting the user to a "CallbackSummary" page to show if the authentication request was either a success or failure. (Remember, the page is secured within my own Administration interface.)

If the request is successful, the access token is stored.

Step 3: Request Callback Page

The last piece of the puzzle is to actually request our callback page by authorizing ourselves via Instagram API. In this case, I just have a simple page with the following mark up:

<p>If Instagram fails to output images to the page, this maybe because a new Authorisation key needs to be generated.</p>
<p>To generate a new key, press the button below and follow the required steps.</p>
<a onclick="window.open('https://api.instagram.com/oauth/authorize/?client_id=<%=ConfigurationManager.AppSettings["instagram.clientid"].ToString() %>&redirect_uri=<%=ConfigurationManager.AppSettings["instagram.redirecturi"].ToString() %>&response_type=code', 'newwindow', config='height=476,width=641,toolbar=no, menubar=no, scrollbars=no, resizable=no,location=no,directories=no, status=no'); return false;" href="#" target="_parent">Generate</a>

If all goes to plan, you should have successfully recieved the access token.

I will post more Instagram code in future posts.