A netstandard2.0 library that consumes the new Instagram Basic Display API.
Also includes a Razor Pages Web example that shows how to use the library and a Static site example that shows how to consume the new Instagram Basic Display API with just vanilla JavaScript.
Browse sample Razor Pages Web and Static site code
To install via nuget using the dotnet cli
dotnet add package Solrevdev.InstagramBasicDisplay
To install via nuget using Visual Studio / Powershell
Install-Package Solrevdev.InstagramBasicDisplay
Before you begin you will need to create an Instagram client_id
and client_secret
by creating a Facebook app and configuring it so that it knows your https only redirect_url
.
See the Facebook and Instagram Setup page for detailed steps.
In your .NET Core library or application create an appsettings.json
file if one does not already exist and fill out the InstagramSettings
section with your Instagram credentials such as client_id, client_secret and redirect_url as mentioned above.
appsettings.json
{
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft": "Warning",
"Microsoft.Hosting.Lifetime": "Information"
}
},
"AllowedHosts": "*",
"InstagramCredentials": {
"Name": "friendly name or your app name can go here - this is passed to Instagram as the user-agent",
"ClientId": "client-id",
"ClientSecret": "client-secret",
"RedirectUrl": "https://localhost:5001/auth/oauth"
}
}
Add references to your startup.
services.AddScoped<Solrevdev.InstagramBasicDisplay.Core.InstagramApi>();
services.AddScoped<Solrevdev.InstagramBasicDisplay.Core.InstagramHttpClient>();
services.Configure<InstagramCredentials>(configuration.GetSection("InstagramCredentials"));
A full example:
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Configuration;
using Solrevdev.InstagramBasicDisplay.Core;
using Solrevdev.InstagramBasicDisplay.Core.Instagram;
namespace Web
{
public class Startup
{
public IConfiguration Configuration { get; }
public Startup(IConfiguration configuration)
{
Configuration = configuration;
}
// This method gets called by the runtime. Use this method to add services to the container.
// For more information on how to configure your application, visit https://go.microsoft.com/fwlink/?LinkID=398940
public void ConfigureServices(IServiceCollection services)
{
services.Configure<InstagramCredentials>(Configuration.GetSection("InstagramCredentials"));
services.AddScoped<InstagramHttpClient>();
services.AddScoped<InstagramApi>();
services.AddHttpClient();
services.AddRouting(option =>
{
option.AppendTrailingSlash = true;
option.LowercaseUrls = true;
});
services.AddSession();
services.AddRazorPages();
}
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
app.UseSession();
app.UseRouting();
app.UseEndpoints(endpoints => endpoints.MapRazorPages());
}
}
}
Get an Instagram User Access Token and permissions from an Instagram user
First, you send the user to Instagram to authenticate using the Authorize
method, they will be redirected to the RedirectUrl
set in InstagramCredentials
so ensure that is set-up correctly in the Instagram app settings page.
Instagram will redirect the user on a successful login to the RedirectUrl
page you configured in InstagramCredentials
and this is where you can call AuthenticateAsync
which exchanges the Authorization Code for a short-lived Instagram user access token or optionally a long-lived Instagram user access token.
You then have access to an OAuthResponse
which contains your access token and a user which can be used to make further API calls.
private readonly InstagramApi _api;
public IndexModel(InstagramApi api)
{
_api = api;
}
public ActionResult OnGet()
{
var url = _api.Authorize("anything-passed-here-will-be-returned-as-state-variable");
return Redirect(url);
}
Then in your RedirectUrl
page
private readonly InstagramApi _api;
private readonly ILogger<IndexModel> _logger;
public IndexModel(InstagramApi api, ILogger<IndexModel> logger)
{
_api = api;
_logger = logger;
}
// code is passed by Instagram, the state is whatever you passed in _api.Authorize sent back to you
public async Task<IActionResult> OnGetAsync(string code, string state)
{
// this returns an access token that will last for 1 hour - short-lived access token
var response = await _api.AuthenticateAsync(code, state).ConfigureAwait(false);
// this returns an access token that will last for 60 days - long-lived access token
// var response = await _api.AuthenticateAsync(code, state, true).ConfigureAwait(false);
// store in session - see System.Text.Json code below for sample
HttpContext.Session.Set("Instagram.Response", response);
}
If you want to store the OAuthResponse
in HttpContext.Session
you can use the new System.Text.Json
namespace like this
using System.Text.Json;
using Microsoft.AspNetCore.Http;
public static class SessionExtensions
{
public static void Set<T>(this ISession session, string key, T value)
{
session.SetString(key, JsonSerializer.Serialize(value));
}
public static T Get<T>(this ISession session, string key)
{
var value = session.GetString(key);
return value == null ? default : JsonSerializer.Deserialize<T>(value);
}
}
Get an Instagram user's profile
private readonly InstagramApi _api;
private readonly ILogger<IndexModel> _logger;
public IndexModel(InstagramApi api, ILogger<IndexModel> logger)
{
_api = api;
_logger = logger;
}
// code is passed by Instagram, the state is whatever you passed in _api.Authorize sent back to you
public async Task<IActionResult> OnGetAsync(string code, string state)
{
// this returns an access token that will last for 1 hour - short-lived access token
var response = await _api.AuthenticateAsync(code, state).ConfigureAwait(false);
// this returns an access token that will last for 60 days - long-lived access token
// var response = await _api.AuthenticateAsync(code, state, true).ConfigureAwait(false);
// store and log
var user = response.User;
var token = response.AccessToken;
_logger.LogInformation("UserId: {userid} Username: {username} Media Count: {count} Account Type: {type}", user.Id, user.Username, user.MediaCount, user.AccountType);
_logger.LogInformation("Access Token: {token}", token);
}
Get an Instagram user's images, videos, and albums
private readonly InstagramApi _api;
private readonly ILogger<IndexModel> _logger;
public List<Media> Media { get; } = new List<Media>();
public IndexModel(InstagramApi api, ILogger<IndexModel> logger)
{
_api = api;
_logger = logger;
}
// code is passed by Instagram, the state is whatever you passed in _api.Authorize sent back to you
public async Task<IActionResult> OnGetAsync(string code, string state)
{
// this returns an access token that will last for 1 hour - short-lived access token
var response = await _api.AuthenticateAsync(code, state).ConfigureAwait(false);
// this returns an access token that will last for 60 days - long-lived access token
// var response = await _api.AuthenticateAsync(code, state, true).ConfigureAwait(false);
// store and log
var media = await _api.GetMediaListAsync(response).ConfigureAwait(false);
_logger.LogInformation("Initial media response returned with [{count}] records ", media.Data.Count);
_logger.LogInformation("First caption: {caption}, First media url: {url}",media.Data[0].Caption, media.Data[0].MediaUrl);
//
// toggle the following boolean for a quick and dirty way of getting all a user's media.
//
if(false)
{
while (!string.IsNullOrWhiteSpace(media?.Paging?.Next))
{
var next = media?.Paging?.Next;
var count = media?.Data?.Count;
_logger.LogInformation("Getting next page [{next}]", next);
media = await _api.GetMediaListAsync(next).ConfigureAwait(false);
_logger.LogInformation("next media response returned with [{count}] records ", count);
// add to list
Media.Add(media);
}
_logger.LogInformation("The user has a total of {count} items in their Instagram feed", Media.Count);
}
}
Exchange a short-lived access token for a long-lived access token
private readonly InstagramApi _api;
private readonly ILogger<IndexModel> _logger;
public IndexModel(InstagramApi api, ILogger<IndexModel> logger)
{
_api = api;
_logger = logger;
}
// code is passed by Instagram, the state is whatever you passed in _api.Authorize sent back to you
public async Task<IActionResult> OnGetAsync(string code, string state)
{
// this returns an access token that will last for 1 hour - short-lived access token
var response = await _api.AuthenticateAsync(code, state).ConfigureAwait(false);
_logger.LogInformation("response access token {token}", response.AccessToken);
var longLived = await _api.GetLongLivedAccessTokenAsync(response).ConfigureAwait(false);
_logger.LogInformation("longLived access token {token}", longLived.AccessToken);
}
Refresh a long-lived access token for another long-lived access token
private readonly InstagramApi _api;
private readonly ILogger<IndexModel> _logger;
public IndexModel(InstagramApi api, ILogger<IndexModel> logger)
{
_api = api;
_logger = logger;
}
// code is passed by Instagram, the state is whatever you passed in _api.Authorize sent back to you
public async Task<IActionResult> OnGetAsync(string code, string state)
{
// this returns an access token that will last for 1 hour - short-lived access token
var response = await _api.AuthenticateAsync(code, state).ConfigureAwait(false);
_logger.LogInformation("response access token {token}", response.AccessToken);
var longLived = await _api.GetLongLivedAccessTokenAsync(response).ConfigureAwait(false);
_logger.LogInformation("longLived access token {token}", longLived.AccessToken);
var another = await _api.RefreshLongLivedAccessToken(response).ConfigureAwait(false);
_logger.LogInformation("response access token {token}", another.AccessToken);
}
For more information see InstagramApi.md
Facebook also provides tooling to quickly generate long-lived Instagram User Access Tokens for any of your public Instagram accounts.
For more information see User Token Generator.
From NuGet version 1.0.6 custom Exceptions
are thrown whenever Instagram returns a non success HttpStatusCode
.
These allow you to try
and catch
and handle fails gracefully as well as get an insight into what the issue was.
Look for InstagramApiException
InstagramOAuthException
and the more general InstagramException