Donate

Read Files From Google Photos Using Google Photos API, REST And C#.NET

Related Tutorials On Google Photos API
Read Files From Google Photos Using Google Photos API, REST and VB.NET
Upload Photos, Images Or Files To Google Photos Using Google Photos API, Rest and C#.NET

I've been working on a project last year to read and download images from Google Photos using the recent Google Photos API and C# as the programming language. During research, there was an existing .NET API called Picasa Web Albums API but has been deprecated and the docs suggested to migrate applications to the recent one. The examples in the current documentation provided are PHP, Java and REST API in which the example is written in Node.js. Since the requirement is to write a scheduled task or windows service in C#.NET, I decided to refresh my skills on sending requests to REST services using WebClient or HTTPWebRequest classes.

To access media items, read or even download files using Google Photos API, you need to enable the Google Photos Library API, create a Google Project and setup OAuth 2.0 credentials correctly. See Get started with REST documentation for a step by step guide on how to accomplish them.

Once the setup stage has been completed, you need to download the JSON file that contains your credentials such as Client Secret ID and Client Secret and then add them to your Visual Studio project. In the screenshot below, I attached the JSON file and renamed it to 'credentials'. Set the Copy to output directory of that file to Copy Always.
Using Google Photos API, REST and C#.NET
Next is to create the model classes that will convert the JSON result into a .NET object.
public class clsResponseRootObject
   {
      public List<MediaItem> mediaItems { get; set; }
      public string nextPageToken { get; set; }
   }

   public class MediaItem
   {
      public string id { get; set; }
      public string productUrl { get; set; }
      public string baseUrl { get; set; }
      public string mimeType { get; set; }
      public MediaMetadata mediaMetadata { get; set; }
      public string filename { get; set; }
   }

   public class MediaMetadata
   {
      public DateTime creationTime { get; set; }
      public string width { get; set; }
      public string height { get; set; }
      public Photo photo { get; set; }
   }

   public class Photo
   {
      public string cameraMake { get; set; }
      public string cameraModel { get; set; }
      public double focalLength { get; set; }
      public double apertureFNumber { get; set; }
      public int isoEquivalent { get; set; }
   }
To proceed with reading the files from Google Photos Library, install the Google.Apis.Auth package in your project via NuGet. The entire code to read the files is shown below.
using Google.Apis.Auth.OAuth2;
using Google.Apis.Util.Store;
using Newtonsoft.Json;
using System;
using System.IO;
using System.Net;
using System.Text;
using System.Threading;

namespace GooglePhotosAPISimpleDemo
{
   class Program
   {
      static void Main(string[] args)
      {
         string credPath = @"D:\StorePath\";
         clsResponseRootObject responseObject = new clsResponseRootObject();
         UserCredential credential;
         string[] scopes = {
            "https://www.googleapis.com/auth/photoslibrary.sharing",
            "https://www.googleapis.com/auth/photoslibrary.readonly"
         };
         string UserName = "your_googlemail_account";
         string ClientID = "your_client_id";
         string ClientSecret = "your_client_secret";

         using (var stream = new FileStream("credentials.json", FileMode.Open, FileAccess.Read))
         {
            credential = GoogleWebAuthorizationBroker.AuthorizeAsync(
                GoogleClientSecrets.Load(stream).Secrets,
                scopes,
                UserName,
                CancellationToken.None,
                new FileDataStore(credPath, true)).Result;
         }

         try
         {
            HttpWebRequest httpWebRequest = (HttpWebRequest)WebRequest.Create("https://photoslibrary.googleapis.com/v1/mediaItems");
            httpWebRequest.ContentType = "application/json";
            httpWebRequest.Headers.Add("client_id", ClientID);
            httpWebRequest.Headers.Add("client_secret", ClientSecret);
            httpWebRequest.Headers.Add("Authorization:" + credential.Token.TokenType + " " + credential.Token.AccessToken);
            httpWebRequest.Method = "GET";

            HttpWebResponse response = httpWebRequest.GetResponse() as HttpWebResponse;
            using (Stream responseStream = response.GetResponseStream())
            {
               StreamReader reader = new StreamReader(responseStream, Encoding.UTF8);

               responseObject = JsonConvert.DeserializeObject<clsResponseRootObject>(reader.ReadToEnd());

               if (responseObject != null)
               {
                  if (responseObject.mediaItems != null && responseObject.mediaItems.Count > 0)
                  {
                     Console.WriteLine("------------------------Retrieving media files--------------------------------");
                     foreach (var item in responseObject.mediaItems)
                     { 
                        Console.WriteLine(string.Format("ID:{0}, Filename:{1}, MimeType:{2}", item.id, item.filename, item.mimeType));
                     }
                  }
               }
            }
         }
         catch (Exception ex)
         {
            Console.WriteLine("Error occured: " + ex.Message);
         }

         Console.ReadLine();
      }
   }
}
If you run the application, an Internet Explorer Browser will show on your desktop and will ask you to enter your email address as confirmation.
Using Google Photos API, REST and C#.NET
Once you click Allow, the program will then display the files you uploaded in your Photos Library.
Using Google Photos API, REST and C#.NET

Comments

  1. How can you do a POST call I am trying HttpWebRequest httpWebRequest = (HttpWebRequest)WebRequest.Create("https://photoslibrary.googleapis.com/v1/mediaItems:search");
    httpWebRequest.ContentType = "application/json; charset=utf-8";
    httpWebRequest.Headers.Add("client_id", ClientID);
    httpWebRequest.Headers.Add("client_secret", ClientSecret);
    httpWebRequest.Headers.Add("Authorization:" + credential.Token.TokenType + " " + credential.Token.AccessToken);
    //httpWebRequest.Headers.Add("albumId", "18545");
    //httpWebRequest.Headers.Add("pageSize", "100");
    httpWebRequest.Method = "POST";

    using (var streamWriter = new StreamWriter(httpWebRequest.GetRequestStream()))
    {
    string json = "{\"albumId\":\"18545\"," +
    "\"pageSize\":\"100\"}";

    streamWriter.Write(json);
    streamWriter.Flush();
    }
    but it is sending me a 400 error incorrect request

    ReplyDelete
    Replies
    1. Do you have these statements?

      var httpResponse = (HttpWebResponse)httpWebRequest.GetResponse();
      using (var streamReader = new StreamReader(httpResponse.GetResponseStream()))
      {
      var result = streamReader.ReadToEnd();
      }

      Delete
  2. How to use the pagination returned from API? I'm trying something like
    httpWebRequest.Headers.Add("pageToken", responseObject.nextPageToken);
    but get the same previous result.

    ReplyDelete
    Replies
    1. Hi, I believe to integrate pagination, get the nextpage token and use that token for the next HTTPWebrequest call.

      https://developers.google.com/photos/library/guides/list#pagination

      Delete
  3. I get a error as

    Error 400: redirect_uri_mismatch
    The redirect URI in the request, http://localhost:51289/authorize/, does not match the ones authorized for the OAuth client. To update the authorized redirect URIs, visit: https://console.developers.google.com/apis/credentials/oauthclient/1073821342213-qaprtgeelhu7ic88jucitfie75o59crf.apps.googleusercontent.com?project=1073821342213


    code is https://snipboard.io/oT3mqw.jpg

    url and actionresult id http://localhost:49837/Admin/GooglePhotos


    plz help

    ReplyDelete
    Replies
    1. Hi,

      Basing from the error "does not match the ones authorized for the OAuth client". It could be that something was missing or skipped or incorrect during the setup of OAuth credentials.

      Delete
  4. Huge timesaver, thanks for sharing!

    ReplyDelete
  5. I want to use blogger v3 api to create content from a db, I have tested and it's working, the problem that I'm facing is that there no way to upload images with the blogger api so I've read that google photo can help, but this is different because google photo and the blogger images are totally different things, also there is no official csharp code for managing the photo api, this is why you created this

    At this point I don't know what to do

    ReplyDelete
    Replies
    1. Tony,

      I haven't had the chance to work on this project for over a year now. And I regret that I haven't worked with blogger v3 api either. So, if you had found a solution in the future, please do share.

      Thanks

      Delete
  6. Thanks for this Sample.

    There were some bugs in main program like reading credentials.json before its created. Also using client_id and client_secret in header was not required after you have the token. I have corrected these and the revised code is available at below link.

    https://gist.github.com/sm1810/0d4c8d96e06ed0125456f067ad19d31c

    ReplyDelete
    Replies
    1. Cool!

      Thanks for sharing that piece of code. :-)

      Delete
  7. Is it really necessary to predefine user name?
    As I saw we need to auth with google anyway.
    Can we optimize that part of code?

    ReplyDelete
    Replies
    1. Yes, that part of code can be optimized and I believe there are other ways on how to authenticate using google api. The username is needed in the GoogleWebAuthorizationBroker.AuthorizeAsync() function.

      Delete

Post a Comment

Donate

Popular Posts From This Blog

WPF CRUD Application Using DataGrid, MVVM Pattern, Entity Framework, And C#.NET

How To Insert Or Add Emojis In Microsoft Teams Status Message

TypeScript Error Or Bug: The term 'tsc' is not recognized as the name of a cmdlet, function, script file, or operable program.