Closed petr24 closed 9 years ago
After playing around with this and trying everything I could find, finally fixed the issue. I'll close this out, but someone could see this if they have the same problem. The main issue came from me having to use xml, and when using 'body' or 'data' it apparently treats that as json which is obviously incorrect since google contacts requires one to use xml when creating contacts.
//non working
var options = {
'headers': {
"Content-Type": "application/atom+xml"
},
//also tried 'data': atomEntry, which errors out
'body': atomEntry
}
//working
var options = {
'headers': {
"Content-Type": "application/atom+xml"
},
//use content for xml instead of body or data
content: atomEntry
}
Hi petr. Could you post full example. I am also having same issue response code is 201.
Hey @anurag-itsolvs,
Here is what I have, but remember the data needs to be formatted to proper xml before sending the post to google. Their contacts api isn't the best in my opinion, and the xml is very specific or it errors out. Here is the link for the xml format for creating a contact. https://developers.google.com/google-apps/contacts/v3/#creating_contacts
//Helper function I made where I pass data to a function, and it takes care of formatting the data to xml.
var atomEntry = createAtomEntry(infoData);
var url = 'm8/feeds/contacts/default/full?v=3.0&alt=json';
var options = {
'headers': {
"Content-Type": "application/atom+xml"
},
content: atomEntry
}
GoogleApi.post(url, options, function (err, data) {
if (err) {
console.log("create rror", err);
}else {
console.log('result', data);
}
});
Hi petr, Thanks for your quick reply. Still I am having issue, Here what I am sending. If I am doing anything wrong please help me.
var xmlData = '<atom:entry xmlns:atom="http://www.w3.org/2005/Atom"'+
'xmlns:gd="http://schemas.google.com/g/2005">'+
'<atom:category scheme="http://schemas.google.com/g/2005#kind"'+
'term="http://schemas.google.com/contact/2008#contact"/>'+
'gd:name'+
'gd:givenNameAnurag/gd:givenName'+
'gd:familyNameChoudhary/gd:familyName'+
'gd:fullNameAnurag Choudhary/gd:fullName'+
'/gd:name'+
'
var postheaders = {
'Content-Type': 'application/atom+xml'
};
var query = {
'oauth_token': oauth2Client.credentials.access_token,
'alt': 'json'
};
var stringifyQuery = qs.stringify(query);
var options = {
host: "www.google.com",
port: 443,
path: '/m8/feeds/contacts/default/full?'+ stringifyQuery,
method: 'POST',
headers: postheaders,
content: xmlData
}
//then call google rest API
var reqPost = https.request(options, function (response) {
// if err.code === 401 means that Access token has expired.
if(response.statusCode === 401) {
console.log("Access token exp!");
console.log(user.refresh_token);
// Try to fetch a new one with the help of refresh token.
refresh.requestNewAccessToken('google', user.refresh_token, function(err, accessToken) {
// if any error occors
if(err || !accessToken) {
console.log("rfs err: "+ err);
return send401Response();
}
// if successfully get the access token, update in database
User.findOne({_id: user._id}, function(err, user){
User.findByIdAndUpdate(
{_id: user._id},
{access_token :accessToken},
function(err, result) {
if(err)
throw err;
console.log(result);
console.log("result doneeee!");
//done(null, User);
makeRequest();
});
});
});
}
else {
// There was another error, handle it appropriately.
if(response.statusCode === 200)
{
var data = '';
response.on('data', function (moreData) {
data += moreData;
});
response.on('end', function () {
res.send(data);
})
}
else{
console.log(response.statusCode)
res.send("There is some other error!" + response.statusCode);
}
}
});
reqPost.on('error', function (e) {
console.error(e);
response.send({message:"err"});
});
reqPost.end();
It is creating new contact but its not sending the data to google.
in sort I am sending this:
{ host: 'www.google.com',
port: 443,
path: '/m8/feeds/contacts/default/full?oauth_token=ya29.IAL7TOXgFHXzDUaKsD42YP7Bmp_PJeoq3XeoHqeQU3oYwBqQVtenbtUvzGV1GQE94hRb97fK_qSAZMyUhLhO5QY&alt=json',
method: 'POST',
headers: { 'Content-Type': 'application/atom+xml' },
content: '
@anurag-itsolvs
Hey I was under the assumption that you were using this package. Thats the first recommandation I would give, is to use this package, it works really well and automatically handles your tokens. Your code will be much nicer using this vs going manual HTTP route.
I am pasting some code below, I just testing it and it works. So just copy and paste the code (make sure you add this package), inside a function, then call that function and it will create a contact called "Testing Bennet"
And anything inside the else block here means its successful. So in your case the code for success response just put that in the else, no need to check for a certain code for a successful callback.
//Making xml data for google sync.
var atomEntry = '<atom:entry xmlns:atom="http://www.w3.org/2005/Atom" xmlns:gd="http://schemas.google.com/g/2005"><atom:category scheme="http://schemas.google.com/g/2005#kind" term="http://schemas.google.com/contact/2008#contact"/><gd:name><gd:givenName>Testing</gd:givenName><gd:familyName>Bennet</gd:familyName><gd:fullName>Testing Bennet</gd:fullName></gd:name><atom:content type="text">Notes</atom:content><gd:email rel="http://schemas.google.com/g/2005#work" primary="true" address="liz@gmail.com" displayName="E. Bennet"/><gd:email rel="http://schemas.google.com/g/2005#home" address="liz@example.org"/><gd:phoneNumber rel="http://schemas.google.com/g/2005#work" primary="true">(206)555-1212</gd:phoneNumber><gd:phoneNumber rel="http://schemas.google.com/g/2005#home">(206)555-1213</gd:phoneNumber><gd:im address="liz@gmail.com" protocol="http://schemas.google.com/g/2005#GOOGLE_TALK" primary="true" rel="http://schemas.google.com/g/2005#home"/><gd:structuredPostalAddress rel="http://schemas.google.com/g/2005#work" primary="true"><gd:city>Mountain View</gd:city><gd:street>1600 Amphitheatre Pkwy</gd:street><gd:region>CA</gd:region><gd:postcode>94043</gd:postcode><gd:country>United States</gd:country><gd:formattedAddress>1600 Amphitheatre Pkwy Mountain View</gd:formattedAddress></gd:structuredPostalAddress></atom:entry>';
console.log('atomEntry', atomEntry);
var url = 'm8/feeds/contacts/default/full?v=3.0&alt=json';
var options = {
'headers': {
"Content-Type": "application/atom+xml"
},
content: atomEntry
}
GoogleApi.post(url, options, function (err, data) {
if (err) {
console.log('error ', err);
}else {
console.log('data ', data);
}
});
Hi petr, Thank you so much. Its working!. Contacts are creating in "Other Contacts" Group. Is there any way to create in "My Contacts" Group.
I was testing this : "gContact:groupMembershipInfo deleted='false' href='http://www.google.com/m8/feeds/groups/default/base/6'/"
But its giving namespace err in xml data.
@anurag-itsolvs
This is a case of poor documentation on googles end. Add this right before closing out the atom entry xml.
//I use Meteor.user().services.google.email to get users email, but if you have it on hand you can
//pass the email of user directly, and it should work.
<gContact:groupMembershipInfo deleted='false'
href='http://www.google.com/m8/feeds/groups/" + Meteor.user().services.google.email + "/base/6'/>
</atom:entry> //Closing Entry Tag
Hello petr, It is working!. You helped me a lot. Thank you for your nice answer, for my all the issues..
No problem, glad I could help :)
Hello Petr. I am having some issue related to update google contact API. could you assist me to resolve that. I am getting 400 response code. I am sending data like this:-
xml data is:-
<entry gd:etag=""Q3w4eDVSLyt7I2A9XRJVGE8OQgE."">
https method:-
{ host: 'www.google.com',
port: 443,
path: '/m8/feeds/contacts/anurag%40itsolvs.com/base/449a237c0fc6f288?oauth_token=ya29.JAL7JaqJsXmKae5_MMOGUDLhA1hmb8jO2mEqoItAls0bgO_MD7fhEh6meO8rNzbjFMjn&alt=json',
method: 'PUT',
'If-Match': '"Q3w4eDVSLyt7I2A9XRJVGE8OQgE."',
headers:
{ 'Content-Type': 'application/atom+xml',
'Content-Length': 1382,
'GData-Version': '3.0' } }
The gd:etag is individual gd$etag Which is each contact , should i use top level of gd$etag?
Looks like you are putting the if match in the wrong spot. Should be inside headers.
'headers' : {
"Content-Type": "application/atom+xml",
"If-Match": "etag value goes here"
}
I did try with this also, but still getting 400 err
{ host: 'www.google.com', port: 443, path: '/m8/feeds/contacts/anurag%40itsolvs.com/base/449a237c0fc6f288?oauth_token=ya29.JAL7JaqJsXmKae5_MMOGUDLhA1hmb8jO2mEqoItAls0bgO_MD7fhEh6meO8rNzbjFMjn&alt=json', method: 'PUT', headers: { 'Content-Type': 'application/atom+xml', 'Content-Length': 1370, 'GData-Version': '3.0', 'If-Match': '"Q3w4eDVSLyt7I2A9XRJVGE8OQgE."' } }
Should I use the top level of etag value? Is there any way to check my contact xml data?
Hi petr, I found https://developers.google.com/oauthplayground/ link, which is quite handy to test google Api's.
I tested my update contact api, I found the issue now its working. Thanks for help.
Hi petr, I am working on google push notification.I am trying to get notification if I create new event.
I am watching event like this:
googleCalendar.events.watch({ auth: oauth2Client, //accessToken calendarId: calendarId, // calendar ID resource: { id: uuID, // unique ID address: 'https://crm.itsolvs.com/google/calendar', // Callback URL type: 'web_hook' // The type of delivery mechanism } }, function(err, results) { console.log(err); if(err) { } });
I am getting google watch event response successfully :
{ expiration: "1451925670000" id: "c208d8c4-4701-4b9f-907b-edfb487a635c" kind: "api#channel" resourceId: "mZYd9lVa31BF1G8XMPIsqsh98dQ" resourceUri: "https://www.googleapis.com/calendar/v3/calendars/64udo0ukou686hf5fioettb698@group.calendar.google.com/events?alt=json" }
After that what should I do? as far as I understand the concept of google calendar push notification,
I should have get the sync message along with watch response but I am not getting. If you have any idea please help me how can I get push notification.
Thanks.
I am working with google contacts, and so far, getting contacts, updating them, and deleting them is all working, but for whatever reason when I use GoogleApi.post() its not sending the data to google, it goes through and successfully creates a contact, except that contact is completely blank. I know its not an xml issue when creating the contact because I put that through google playground and it worked smoothly. Not sure what might be causing this.