Here’s another Google Docs API trick. Using the standard .NET API only word documents can be uploaded with embedded images. Embedding images in the HTML doesn’t work, and any images linked in the html will not be copied to the Google server.

However, if you upload an image file to Google docs, it will be converted into a document - the image gets a file id and a document is created containing a link to that image. This feature can be used to upload any necessary images before sending the html with the full content.

  1. Upload an image, naming it “Temporary Image Upload Doc” or something similarly obviously temporary

  2. Download the resulting document and parse the content to find the img tag with src starting with File?id=

  3. Delete the temporary document

  4. Update the main html content to use the file url obtained from the temporary document

  5. Upload the complete html document.

Image upload code is below. Note that I had to create the request manually rather than using service.UploadDocument - even though the server will accept images, the .NET api does not list them as valid content types.

        ///
        /// Upload an image for embedding in a document
        ///
        ///
        ///
        /// The id of the uploaded image
        public static string UploadImage(string notesFolderId, Stream imageStream, string contentType, string token)
        {

            var service = GetService(token);


            // upload
            // standard .net api won't accept png

            var respstr = service.StreamSend(new Uri("http://docs.google.com/feeds/documents/private/full"), imageStream, GDataRequestType.Insert, "image/png", "Temporary Image Upload File");
            var rssr = new StreamReader(respstr);

            var se = rssr.ReadToEnd();

            // get ids from response


            var tempDocId = GetDocIdFromResponseString(se);

            // Download document


            // TODO: this can be made a bit more efficient if we get the media uri from
            // the original response
            var e = service.Get(string.Format("http://docs.google.com/feeds/documents/private/full/document%3A{0}", tempDocId));

            var resp = DownloadDocumentFromAltUri(e.AlternateUri.Content, token);

            // delete temp doc

            var tempDocEditUri = e.EditUri.Content;
            var tempDocMediaUri =
                string.Format("http://docs.google.com/feeds/media/private/full/document%3A{0}/{1}",
                tempDocId,
                tempDocEditUri.Substring(tempDocEditUri.LastIndexOf("/") + 1));


            service.Delete(new Uri(tempDocMediaUri));

            //<img><br></br>
            var mc = Regex.Matches(resp, "File\\?id=(.*?)'");

            if (mc.Count < 1 || mc[0].Groups.Count < 2) {
                throw new Exception("Unable to get image id from response");
            }
            return mc[0].Groups[1].Value;

        }