尝试使用node.js导入gmail联系人

时间:2013-06-11 07:44:08

标签: node.js api gmail google-api contacts

我正在尝试导入gmail联系人。我已成功获取access_token,但在尝试获取联系人浏览器时不断抛出错误。 invalid_grant

我的代码如下。

用于身份验证和回调。

    authorize: function(req, res){
    var CLIENT_ID = '927112080821-vhsphqc79tb5ohfgpuvrp8uhh357mhad.apps.googleusercontent.com';
    var CLIENT_SECRET = 'gdgofL0RfAXX0in5JEiQiPW8';
    var SCOPE = 'https://www.google.com/m8/feeds';
        oa = new oauth.OAuth2(CLIENT_ID,
              CLIENT_SECRET,
              "https://accounts.google.com/o",
              "/oauth2/auth",
              "/oauth2/token");
    res.redirect(oa.getAuthorizeUrl({scope:SCOPE, response_type:'code', redirect_uri:'http://localhost:1234/callback'}));
  },
  callback: function(req, res){
    console.log(req.query.code);
    oa.getOAuthAccessToken(req.query.code, {grant_type:'authorization_code', redirect_uri:'http://localhost:1234/callback'}, function(err, access_token, refresh_token) {
    if (err) {
        res.end('error: ' + JSON.stringify(err));
    } else {
          getContactsFromGoogleApi(access_token);

        //res.write('access token: ' + access_token + '\n');
        //res.write('refresh token: ' + refresh_token);
        //res.end();
    }
    });

  },

用于导入联系人

function getContactsFromGoogleApi (access_token, req, res, next) {
console.log('access_token ' + access_token);
request.get({
    url: 'https://www.google.com/m8/feeds/contacts/default/full',
    qs: { 
      alt:           'json', 
      'max-results':  1000,
      'orderby':     'lastmodified'
    },
    headers: { 
      'Authorization': 'OAuth ' + access_token,
      'GData-Version': '3.0'
    }
  }, function (err, res, body) {
    if(res.statusCode === 401){
      return res.redirect('index');
    }
    var feed = JSON.parse(body);

    var users = feed.feed.entry.map(function (c) {
      var r =  {};
      if(c['gd$name'] && ['gd$fullName']){
        r.name = c['gd$name']['gd$fullName']['$t'];
      }
      if (c['gd$email'] && c['gd$email'].length > 0) {
        r.email    = c['gd$email'][0]['address'];
        r.nickname = r.email;//c['gd$email'][0]['address'].split('@')[0];
      }
      if(c['link']){
        var photoLink = c['link'].filter(function (link) {
          return link.rel == 'http://schemas.google.com/contacts/2008/rel#photo' && 
                 'gd$etag' in link; 
        })[0];
        if(photoLink) {
          r.picture = '/users/photo?l=' + encodeURIComponent(photoLink.href);
        } else if (r.email) {
          r.picture = gravatar.url(r.email, {
            s: 40, 
            d: "https://ssl.gstatic.com/s2/profiles/images/silhouette80.png"});
        }
      }
      return r;
    }).filter(function (u) {
      return !!u.email &&                  //we can only give access to persons with email at this point
             !~u.email.indexOf('@reply.');  //adress with @reply. are usually temporary reply address for forum kind of websites.
    });

    res.json(users);
  });

}

非常感谢帮助。

1 个答案:

答案 0 :(得分:0)

在你的getContactsFromGoogleApi函数中,将Authorization标题更改为以下内容;

headers: { 
      'Authorization': 'Bearer ' + access_token,
      'GData-Version': '3.0'

以下是C#中用来做同样事情的代码

        webClient = new WebClient();
        webClient.Headers.Add("user-agent", "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.2; .NET CLR 1.0.3705;)");
        webClient.Headers.Add(HttpRequestHeader.Authorization, String.Format("Bearer {0}", AccessToken));

        do
        {

            contactStream = webClient.DownloadData(String.Format("{0}?start-index={1}", BaseApiEndpoints[Applications.Contacts], startIndex));

            contactDocument = System.Text.Encoding.Default.GetString(contactStream);

            contacts = new XmlDocument();
            contacts.LoadXml(contactDocument);


            // TODO: use xsl to convert results to ContactSearchResults
            xslt             = new XslCompiledTransform();
            resultStream     = new MemoryStream();
            writer           = new XmlTextWriter(resultStream, Encoding.ASCII);
            translateContact = new XmlDocument();

            xslStream        = GetRequest("GoogleContacts.xslt");
            xslStream.Seek(0, SeekOrigin.Begin);
            templateReader = XmlReader.Create(xslStream);
            xslt.Load(templateReader);

            xslt.Transform(contacts,writer);
            resultStream.Seek(0, SeekOrigin.Begin);

            TranslatedContacts = ConvertByteArrayToString(ReadFully(resultStream));

            csr = (ContactSearchResults)Deserialize(typeof(ContactSearchResults), TranslatedContacts);

            foreach (Contact contact in csr.Contacts)
            {
                contact.RecordId = Guid.NewGuid();
                // now we want to get the image
                contact.Picture = GetImage(contact.PictureUrl, AccessToken);


                if ((!String.IsNullOrEmpty(contact.Name)) || (!String.IsNullOrEmpty(contact.Email)))
                    results.Add(contact);

            }

            startIndex += csr.ItemsPerPage;

        } while (startIndex < totalResults);

我在这里使用的网址与您的代码相同; http://www.google.com/m8/feeds/

当我在C#中执行此操作时,我不需要通过该版本。