3

I'm trying to update/add a photo to an existing contact using the Google Contacts API v3 and just can't figure out how to do it. I'm using ColdFusion.

I can authenticate thru the Google service, read a photo, display it, and even delete a photo. When I try to update or add a photo for a contact, I'm getting a status code 400 of Bad Request - Invalid image file.

This is the code I'm using:

<cfhttp method="put" url="https://www.google.com/m8/feeds/photos/media/myemail/contactid" result="chgphoto">
    <cfhttpparam type="header" name="Authorization" value="OAuth sessiontoken" >
    <cfhttpparam type="header" name="GData-Version" value="3.0">
    <cfhttpparam type="header" name="If-Match" value="*">
    <cfhttpparam name="Content-Type" type="header" value="image/jpeg">
    (THE NEXT LINE IS IS MY ISSUE - I THINK)
    <cfhttpparam type="body" value="E:\PATH\TO\FILE\image.jpg">
</cfhttp>

I've tried many, many combinations for the line I believe my issue is at, including:

1. <cfhttpparam type="body" value="E:\PATH\TO\FILE\image.jpg">
2. <cfhttpparam type="body" value="/9j/4AAQSkZJRgABAQAAAQABAAD/2wBDAAoHBwgHBgoICAgLCgoLDhgQDg0NDh0VFhEYIx8lJCIfIiEmKzcvJik0KSEiMEExNDk7Pj4+JS5ESUM8SDc9Pjv/2wBDAQoLCw4NDhwQEBw7KCIoOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozv/wAARCAAQABADASIAAhEBAxEB/8QAFwAAAwEAAAAAAAAAAAAAAAAAAAEFBv/EACMQAAEDAwQCAwAAAAAAAAAAAAECAwUEESEABjEyEhNBYbH/xAAUAQEAAAAAAAAAAAAAAAAAAAAF/8QAHREAAgEEAwAAAAAAAAAAAAAAAREAAgMTwUGBof/aAAwDAQACEQMRAD8A2O4NxOmpeYZqFstNKKAG1FJJBIJJGeQQACOL5+CKk5WHqo9uWqQtmSd9bbDqiXmyeqs5sTYEE4uPsacrTS8DL1FbQxxlKCqV7FMAeSm3L3vbntc3A/AdStv7fnZzc7U5OMuU7TCw4lLo8VKUOqQnkAHOjRTcytl+LcLJuZeW+luf/9k=">
3. <cfhttpparam type="header" name="body" value="E:\PATH\TO\FILE\image.jpg">
4. <cfhttpparam type="xml" value="<link rel='http://schemas.google.com/contacts/2008/rel##photo' type='image/*' href='https://www.google.com/m8/feeds/photos/media/myemail/contactid'>">

Of course, none of these are the correct way to do it. Can anyone help?

Scott
  • 29
  • 4

2 Answers2

1

You need to send the (binary) content of the image if you transfer the request with Content-Type: image/jpeg. So simply do this:

<cfhttpparam type="body" value="#fileRead("E:\PATH\TO\FILE\image.jpg")#">

Edit: Note that you may have to increase the buffer size with fileRead for larger images. You can provide the maximum size as the second argument.


If this doesn't work, you might need to send the content as HEX:

<cfhttpparam type="body" value="#binaryEncode(fileReadBinary("E:\PATH\TO\FILE\image.jpg"), "HEX")#">

Edit: Note that fileReadBinary has no buffer size limit and might crash the server when used with huge files.

Alex
  • 7,743
  • 1
  • 18
  • 38
  • Holy cow, that worked!!! Ok, so to clarity anyone reading this, the part that worked was the fileRead recommendation: fyi - I also tried to set the content as HEX but I couldn't get that to work. Anyway, thanks so much for the help Alexander. I spent a week on trying to solve this! – Scott Oct 10 '15 at 03:39
-1

So unfortunately, I found out the initial answer was not accurate since using #fileRead("E:\PATH\TO\FILE\image.jpg")#"> only reads a portion of the file and not all of it. The result is either an image that gets saved through the Google API garbled or not at all - ie 400 Bad Request. That being said, without the input from the original responder of this question, I would not have been able to figure out the correct answer.

What needs to happen is a two step process...

First, read the file as binary:

<cffile action="readbinary" file="E:\PATH\TO\FILE\image.jpg" variable="binimage">

Second, convert it back to a string in the 'body':

<cfhttpparam type="body" value="#ToString(ToBinary(binimage))#">

Once I did that, the image was saved properly through the Google API and not garbled since it was only a partial file before.

Hope this helps others.

Scott
  • 29
  • 4
  • `fileRead` has an optional argument for the buffer size (the number of characters to read). If you do not provide it, ColdFusion's server default is used. If your (large) images are truncated, simply increase the buffer size to read them completely. `fileReadBinary` is not meant for large files since it does not limit the buffer size and may crash the server as stated in Adobe's docs, so use your approach with caution. – Alex Oct 15 '15 at 01:07
  • Not sure I follow this. 1) Exactly what type of value is the Google API expecting? 2) Why are you using `ToBinary()`? The `binimage` variable should already *be* binary. – Leigh Oct 15 '15 at 01:31