Lately I’ve been working on an app that uses the Google Docs GData API. I’ve found that Google Apps shares a lot of the properties that make SharePoint development particularly interesting:

  • Searching for error messages doesn’t help much because the platform and its bugs are quite new

  • The tools have pieces missing and don’t quite work as they should

  • Documentation is inadequate at best

One of the most obviously missing functions in the API is the ability to download a document. I found a workaround on google groups easily enough, creating the http request manually and setting the Authorization header, but unfortunately that doesn’t seem to work for hosted accounts.

With a few wrong turns trying to get a new auth token manually, it took me a full day of trial and error to find something that worked - setting a cookie and adding the hosted domain name to the start of the auth token.

To save anyone else from going through the same process, here’s the code:

  

        public static string DownloadDocumentFromAltUri(string altUri, string token)
        {
            var service = GetService(token);
            string docurl;
            string domain = null;

            var docId = altUri.ToDocumentId();


            if (altUri.Contains("docs.google.com/a/"))
            {
                // google apps

                var s1 = altUri.Substring(altUri.IndexOf("docs.google.com/a/") + 18);
                domain = s1.Substring(0, s1.IndexOf("/"));

                docurl = string.Format("http://docs.google.com/a/{0}/RawDocContents?revision=_latest&docID={1}&justBody=true&browserok=true", domain, docId);
            }
            else
            {
                // google docs
                docurl = string.Format("http://docs.google.com/RawDocContents?revision=_latest&docID={0}&justBody=true&browserok=true", docId);
            }

            Debug.WriteLine(string.Format("Downloading. DocId={0}, AltUri={1}, DocUri={2}", docId, altUri, docurl));

            HttpWebRequest wreq = (HttpWebRequest)HttpWebRequest.Create(docurl);
            if (UseAuthSub)
            {
                wreq.Headers.Add("Authorization", string.Format("AuthSub token={0}", token));
            }
            else
            {
                var authToken = ((GDataGAuthRequestFactory)service.RequestFactory).QueryAuthToken(service.Credentials);

                if (string.IsNullOrEmpty(domain))
                {
                    // unhosted accounts should accept this header
                    wreq.Headers.Add("Authorization", string.Format("GoogleLogin auth={0}", authToken));
                }
                else
                {
                    wreq.Headers.Add("Cookie",
                           string.Format("WRITELYH={0}={1}",
                                    domain,
                                    authToken
                                    )

                        );

                }

            }

            wreq.KeepAlive = true;
            var wresp = wreq.GetResponse();
            var stream1 = wresp.GetResponseStream();
            var cl = wresp.ContentLength;
            StreamReader sr = new StreamReader(stream1);
            var resp = sr.ReadToEnd();
            return resp;
        }