3

I'm trying to upload an image file to Photos library using C#.

Scopes used: https://www.googleapis.com/auth/photoslibrary https://www.googleapis.com/auth/photoslibrary.appendonly

I'm generating uploadToken using below:

FileStream fS = new FileStream(fullPath, FileMode.Open, FileAccess.Read);
                byte[] b = new byte[fS.Length];
                fS.Read(b, 0, (int)fS.Length);
                fS.Close();
                var httpWebRequest = (HttpWebRequest)WebRequest.Create("https://photoslibrary.googleapis.com/v1/uploads");
                httpWebRequest.ContentType = "application/octet-stream";

                httpWebRequest.Headers.Add("Authorization:" + "Bearer " + auth_Token);
                httpWebRequest.Headers.Add("X-Goog-Upload-File-Name:" + imageName);
                httpWebRequest.Headers.Add("X-Goog-Upload-Protocol:" + "raw");
                httpWebRequest.Method = "POST";
                using (var streamWriter = new StreamWriter(httpWebRequest.GetRequestStream()))
                {
                    streamWriter.Write(b);
                    streamWriter.Flush();
                    streamWriter.Close();
                }
                var httpResponse = (HttpWebResponse)httpWebRequest.GetResponse();

Here i'm getting uploadToken successfully. After this i proceeded to create mediaItem like below:

 httpWebRequest = (HttpWebRequest)WebRequest.Create("https://photoslibrary.googleapis.com/v1/mediaItems:batchCreate");
                    httpWebRequest.ContentType = "application/json";
                    httpWebRequest.Headers.Add("Authorization:" + "Bearer " + auth_Token);
                    httpWebRequest.Method = "POST";
                    using (var streamWriter = new StreamWriter(httpWebRequest.GetRequestStream()))
                    {
                        string albumID = "someid";
                        string itemDesc = "somedesc";
                        string jsonString = "{\"albumId\": \"" + albumID + "\",\"newMediaItems\": [{ \"description\": \"" + itemDesc + "\", \"simpleMediaItem\": { \"uploadToken\": \"" + uploadToken + "\" }}]}";

                        streamWriter.Write(jsonString);
                        streamWriter.Flush();
                        streamWriter.Close();
                    }
                    httpResponse = (HttpWebResponse)httpWebRequest.GetResponse();

Now as a response i'm getting:

status": { "code": 3, "message": "NOT_IMAGE: There was an error while trying to create this media item." }

I have googled much but couldn't found any solution for this issue OR any code block for mediaUpload using Google Photos Library API with example.

Please suggest me where i'm doing wrong.

-Reading/writing file bytes in a wrong way?

-Using Json strings and writing in a wrong way?

Please help me. Thank you.

  • What is the value of uploadToken? (Also, I have the exact same issue, except I'm using react-native) – mbunch Dec 15 '18 at 00:32
  • Similar: https://stackoverflow.com/questions/51746830/can-upload-photo-when-using-the-google-photos-api?rq=1 – mbunch Dec 15 '18 at 00:33
  • A bit late I know, but to make life easier I have created a .NET library (nuget package) for the Google Photos API which handles all of this for you... https://github.com/f2calv/CasCap.Apis.GooglePhotos – alv Sep 18 '20 at 07:57

3 Answers3

1

I managed to have this work by doing the below instead when writing the image to the body during the upload step. Hope this helps!

 using (var stream = httpWebRequest.GetRequestStream())
    {
        stream.Write(b, 0, b.Length);
        stream.Flush();
        stream.Close();
    }
je123c
  • 11
  • 2
0

5 GET UPLOAD TOKEN API works find, just the description is wrong on Google Documentation. Instead of Base64 the input is in form of Binary. I have tried in Postman(below screenshot):

Get Upload Token API: https://i.stack.imgur.com/axC7c.png

Upload Media: https://i.stack.imgur.com/5vDnF.png

Pramod Mali
  • 1,588
  • 1
  • 17
  • 29
  • 1
    While this link may answer the question, it is better to include the essential parts of the answer here and provide the link for reference. Link-only answers can become invalid if the linked page changes. Screenshots in general are not helpful at all, please copy & paste the text contents as code or quote blocks into your answer. – Stefan Becker Feb 01 '19 at 09:47
  • @StefanBecker thank you for suggestions. Unfortunately I didn't found this in documentations. I found this by trial and error method. – Pramod Mali Jun 05 '19 at 07:14
0

After searching in quite a few places, I finally stumbled upon this "IssueTracker" entry at Google, that appears related to this post:

https://issuetracker.google.com/issues/117437699

In it, there is a response from Google that the problem with this code is the use of StreamWriter in this line of code

 (var streamWriter = new StreamWriter(httpWebRequest.GetRequestStream()))

When StreamWriter is changed to BinaryWriter it works. The explanation offered from Google's response:

Looking at the documentation for StreamWriter - this seems to be doing some extra encoding that is suitable for writing strings, but not for binary data

Der Wolf
  • 1,171
  • 9
  • 11