Google Contacts, eTags, Updated changing on every access - google-contacts-api

I am trying to use the eTag from a call to get Google Contacts. Since there is an eTag on the "top level", I was hoping that I could check it to determine if anything in the contacts dataset had changed. Here is my request:
Request URL: https://www.google.com/m8/feeds/contacts/default/full/?max-results=0
Request headers:
Authorization: Bearer
Depth: 1
GData-Version: 3.0
Content-Type: text/xml
My thought is that if I request for 0 results, I'll have just the information I need. I can check the eTag against the one that I stored, and if there is no change, there were no changes to any contacts. The XML I get back:
<?xml version="1.0" encoding="UTF-8"?>
<feed gd:etag=""QXYyfzVSLyt7I2A9XRRQFkwJRAA."" xmlns="http://www.w3.org/2005/Atom" xmlns:batch="http://schemas.google.com/gdata/batch" xmlns:gContact="http://schemas.google.com/contact/2008" xmlns:gd="http://schemas.google.com/g/2005" xmlns:openSearch="http://a9.com/-/spec/opensearch/1.1/">
<id><email address here></id>
<updated>2015-02-11T00:09:00.897Z</updated>
<category scheme="http://schemas.google.com/g/2005#kind" term="http://schemas.google.com/contact/2008#contact"/>
<title>Joe's Contacts</title>
<link rel="alternate" type="text/html" href="https://www.google.com/"/>
<link rel="http://schemas.google.com/g/2005#feed" type="application/atom+xml" href="https://www.google.com/m8/feeds/contacts/joe%40ihouseweb.com/full"/>
<link rel="http://schemas.google.com/g/2005#post" type="application/atom+xml" href="https://www.google.com/m8/feeds/contacts/joe%40ihouseweb.com/full"/>
<link rel="http://schemas.google.com/g/2005#batch" type="application/atom+xml" href="https://www.google.com/m8/feeds/contacts/joe%40ihouseweb.com/full/batch"/>
<link rel="self" type="application/atom+xml" href="https://www.google.com/m8/feeds/contacts/joe%40ihouseweb.com/full?max-results=0"/>
<link rel="next" type="application/atom+xml" href="https://www.google.com/m8/feeds/contacts/joe%40ihouseweb.com/full?max-results=0&start-index=1"/>
<author>
<name>Joe</name>
<email>joe#ihouseweb.com</email>
</author>
<generator version="1.0" uri="http://www.google.com/m8/feeds">Contacts</generator>
<openSearch:totalResults>42</openSearch:totalResults>
<openSearch:startIndex>1</openSearch:startIndex>
<openSearch:itemsPerPage>0</openSearch:itemsPerPage>
</feed>
Everything looks good.. except that each time I make the call, the updated date and the eTag come back different. I can make 10 calls in a row, and each time the eTag is different. Is this not a valid way to use the API? If the eTag comes back different every time for anything, then I can't use it to determine if something has changed. Isn't that what the eTag is for?
andy
Here is a sample - I am making the request above 10 times, at 5 second intervals. This is my personal account, so I'm pretty sure that no-one is changing any values on me. Note that the eTag and "updated" values are different each time. The first column is the time I made the request (PST), the second and third are the resultant eTags and updated values.
16:38:30 : "SHYyfTVSLyt7I2A9XRRQGEoORAQ." : 2015-02-14T00:38:29.895Z
16:38:36 : "RHY-fjVSLyt7I2A9XRRQGEoORAU." : 2015-02-14T00:38:35.856Z
16:38:42 : "QHk9ezVSLyt7I2A9XRRQGEoORAY." : 2015-02-14T00:38:41.763Z
16:38:47 : "Rns6cTVSLyt7I2A9XRRQGEoORAY." : 2015-02-14T00:38:47.519Z
16:38:53 : "Qnw-fzVSLyt7I2A9XRRQGEoORAc." : 2015-02-14T00:38:53.257Z
16:38:59 : "SXc5ezVSLyt7I2A9XRRQGEoORAc." : 2015-02-14T00:38:58.923Z
16:39:05 : "RXg5ezVSLyt7I2A9XRRQGEoORAA." : 2015-02-14T00:39:04.623Z
16:39:10 : "QX06cTVSLyt7I2A9XRRQGEoORAE." : 2015-02-14T00:39:10.319Z
16:39:16 : "R346eDVSLyt7I2A9XRRQGEoORAE." : 2015-02-14T00:39:16.010Z
16:39:22 : "QHgyfjVSLyt7I2A9XRRQGEoORAI." : 2015-02-14T00:39:21.696Z

Related

How to post json formatted data into a specific website using R?

First time I try to upload data in JSON format from "R" to the website but after some days spent on this one, I do not manage to make it work and see the output reflected in the website itself.
Note: The numbers and letters provided in the example are not real
Here it is what I am doing:
1) This is the JSON format I am trying to upload/post to the server using R (which has the requested form by the website and it works as I've tried to call it directly from the internal website through an already set up button for performing this POST action).
{
"warehouseId": ["BNA5"],
"planType": ["OP2"],
"lineItemPlans": [
{
"lineItemId": ["ppr.detail.outbound.pack.chuting.medium"],
"type": ["BaseUnitCount"],
"values": [2]
},
{
"lineItemId": ["ppr.detail.outbound.pack.chuting.medium"],
"type": ["BaseRate"],
"values": [0.4]
}
],
"planDates": [1516921200]
}
2) This is the current code I am running to post the data (using library(httr)):
r <- POST("http://fclm-labor-reporting-service.integ.amazon.com/explorer/index.html",
body = '{
"warehouseId": ["BNA5"],
"planType": ["OP2"],
"lineItemPlans": [
{
"lineItemId": ["ppr.detail.outbound.pack.chuting.medium"],
"type": ["BaseUnitCount"],
"values": [2]
},
{
"lineItemId": ["ppr.detail.outbound.pack.chuting.medium"],
"type": ["BaseRate"],
"values": [0.4]
}
],
"planDates": [1516921200]
}')
where the website is internal and it is a false one just for tries. You do not have access to it, Although I guess you can help me to build up the code likewise :)
3) To me, after running the code, it seems that it worked (I see for instance Status: 200). Here below the response:
Response [http://fclm-labor-reporting-service.integ.amazon.com/explorer/index.html]
Date: 2018-01-29 18:02
Status: 200
Content-Type: text/html
Size: 54.6 kB
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml11-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta name="author" content="Coral"/>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
<meta http-equiv="X-UA-Compatible" content="IE=edge"/>
<title>FCLMLaborReportingService Explorer</title>
<link rel="stylesheet" type="text/css" href="style.css"/>
<script type="text/javascript" src="https://internal-cdn.amazon.com/sentry.amazon.com/public/javascripts/openid.xhr.js"></...
...
However, I see, when checking the resulting output in the website, that no modification shows up.
I would appreciate so much whether you could provide your thoughts and help with the code as you'll be certainly wiser than me on this one :D
thanks!
Most likely problem is the data isn't readable by the server. Ensure you're setting the correct Content-Type header:
POST(
url = "http://fclm-labor-reporting-service.integ.amazon.com/explorer/index.html",
config = content_type("application/json"),
body = ...
)
Also worth mentioning that you can automatically turn R data structures into JSON by adding the encode parameter to the POST call. You didn't specify where your data came from, but it could save you an extra step. E.g. something like this:
the_data <- list(
warehouseId = c("BNA5"),
planType = c("OP2"),
lineItemPlans = data.frame(
lineItemId = c("ppr.detail.outbound.pack.chuting.medium", "ppr.detail.outbound.pack.chuting.medium"),
type = c("BaseUnitCount", "BaseRate"),
values = c(2, 0.4)
),
planDates = c(1516921200)
)
POST(
url = "http://fclm-labor-reporting-service.integ.amazon.com/explorer/index.html",
body = the_data,
encode = "json"
)

IBM Worklight 6.0 - FWLSE0099E: An error occurred while invoking procedure

I'm studying the worklight (6.0) tutorial (Insurance App) and in the chapter "Lab6_Integrate_With_Worklight_Apdaters_Part1_HTTPAdapter.pdf" I am instructed on how to create a procedure and invoke it. getting the json file strait from the worklight console URL works fine but when I build the procedure according to the tutorial I cant get the json file (in the "Invoke worklight procedure"), and receive an error:
[ERROR ] FWLSE0099E: An error occurred while invoking procedure [project InsuranceProj]CustomerDataAdapter/HttpRequestFWLSE0100E: parameters: [project InsuranceProj]{ "arr": [
{
"method": "get",
"path": "\/apps\/services\/www\/Insurance\/mobilewebapp\/default\/json\/Customer.json",
"returnedContentType": "json"
} ] } Failed to parse JSON string <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en-US" lang="en-US"> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <meta content="en-us" name="DC.Language" />...... "
I am doing the exact steps in the tutorial and can't find out what's wrong....
I cant find any solution for this problem, Hope to get some answers here
XML file:
<?xml version="1.0" encoding="UTF-8"?>
<!--
Licensed Materials - Property of IBM
5725-G92 (C) Copyright IBM Corp. 2011, 2013. All Rights Reserved.
US Government Users Restricted Rights - Use, duplication or
disclosure restricted by GSA ADP Schedule Contract with IBM Corp.
-->
<wl:adapter name="CustomerDataAdapter"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:wl="http://www.worklight.com/integration"
xmlns:http="http://www.worklight.com/integration/http">
<displayName>CustomerDataAdapter</displayName>
<description>CustomerDataAdapter</description>
<connectivity>
<connectionPolicy xsi:type="http:HTTPConnectionPolicyType">
<protocol>http</protocol>
<domain>localhost</domain>
<port>10080</port>
<!-- Following properties used by adapter's key manager for choosing specific certificate from key store
<sslCertificateAlias></sslCertificateAlias>
<sslCertificatePassword></sslCertificatePassword>
-->
</connectionPolicy>
<loadConstraints maxConcurrentConnectionsPerNode="2" />
</connectivity>
<procedure name="getCustomerData">
<displayName>GetCustomerData</displayName>
</procedure>
</wl:adapter>
implementation file:
function getCustomerData() {
WL.Logger.debug("CustomerDataAdapter.getCustomerData procedure invoked");
var input = {
//headers : 'Content-Type: application/json',
method : 'get',
returnedContentType : 'json',
path : "/apps/services/www/Insurance/mobilewebapp/default/json/Customer.json"
};
return WL.Server.invokeHttp(input);
}
Your adapter is trying to get the JSON from
http://localhost:10080/apps/services/www/Insurance/mobilewebapp/default/json/Customer.json
Which is a reference back into your project (a fairly strange thing to do, but I guess in a lab …)
In any case, your path is missing an element. It should be:
path : "/Insurance/apps/services/www/Insurance/mobilewebapp/default/json/Customer.json"
When the adapter procedure makes its HTTP request to the back-end it is expecting a JSON encoded data string to be returned. From the snippet of data that you show, it appears that what is actually returned is an HTML fragment. What I would suggest is examining the data returned from the back-end service provider very carefully to determine if you are getting the data that you expected to see.

JQuery/Zepro $.ajax request always fails in Firefox/Chrome works in Safari

I've just started trying to convert my first and still in development Webapp into a mobile app with Phonegap. I'm very confused with going from Server side page generation to client side page generation so I'm starting to do some basic stuff as test stubs, so I'll actually be able to get started writing my apps.
I'm trying to do an AJAX post with data to a Ruby Sinatra web service and receive a response in the browser. I can't get Firefox or Chrome to ever take the success path.
This is just testing right now, so it doesn't do anything useful or logical. The Sinatra route looks like this:
post "/auth/check" do
status 200
content_type :json
{ :login => true }.to_json
end
The html/javascript looks like this:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<link rel="stylesheet" type="text/css" href="css/index.css" />
<!-- <script src="js/lib/zepto.min.js"></script> -->
<script src="http://code.jquery.com/jquery-2.0.3.min.js"</script>
<script src="http://code.jquery.com/mobile/1.3.1/jquery.mobile-1.3.1.min.js"</script>
<script>
var BASEURL = "http://localhost:4567";
function login(){
debugger;
$.ajax({
dataType: "jsonp",
url: BASEURL + '/auth/check',
type: "POST",
data: { email: 'somedude#example.com',
password: 'e'
},
success: function (result) {
alert(result);
},
error: function(xhr, type){
alert('Y U NO WORK?')
}
});
}
</script>
</head>
<body>
<input type="button" onClick="login()">Click Me</input"
</body>
</html>
I can't get Firefox or Chrome to do anything other than give the "Y U NO WORK?" alert. Any help would be much appreciated. I've tried switching from Zepto.js to JQuery/JQuery mobile, I've tried changing the data type to jsonp, using curl I've confirmed that the Sinatra route is returning something and a 200 status code which is what JQuery should be checking for.
The answer, based on help by Jan Dvorak, firstly I needed Sinatra to actually return JSONP data. Add a GEM for JSONP support:
require 'sinatra/jsonp'
Secondly the route can only be a HTTP GET, use the JSONP function to return something:
get "/auth/check/" do
content_type :json
status 200
#data = true
JSONP #data
end

REST HATEOAS: How to determine and set media-type while browsing links?

I was going through what was described as an example of a good REST API.
A GET was sent on the base URI and with a media-type that was already known to the client somehow (which is fine, as per REST principles).
To server:
GET /
Host: xrgy.cloud.sun.com
Authorization: Basic xxxxxxxxxxxxxxxxxxx
Accept: application/vnd.com.sun.cloud.Cloud+json
X-Compute-Client-Specification-Version: 0.1
From Server:
HTTP/1.1 200 OK
Content-Type: application/vnd.com.sun.cloud.Cloud+json
Content-Length: nnn
{
"implementation_version": "597",
"vdcs": [
{
"name": "XRGY Virtual Data Center",
"uri": "/vdc"
}
{
"name": "R&D sandbox"
"uri": "/sandbox"
}
],
"uri": "http://xrgy.cloud.sun.com/",
"specification_version": [
"0.5"
]
}
But what I got stuck in was how the client set the media-type for the subsequent request.
I understand that the client got the URI for the next request from the previous response.
But where did it get the media-type from ? If it is prior knowledge to the client, then how do clients typically maintain such URI:media-type mappings ?
It seems I am definitely missing out on some basic knowledge here.
Here is the subsequent request sent with a media-type of : application/vnd.com.sun.cloud.Vdc+json !
To server:
GET /vdc
Host: xrgy.cloud.sun.com
Authorization: Basic xxxxxxxxxxxxxxxxxxx
Accept: application/vnd.com.sun.cloud.Vdc+json
X-Compute-Client-Specification-Version: 0.1
From server:
HTTP/1.1 200 OK
Content-Type: application/vnd.com.sun.cloud.Vdc+json
Content-Length: nnn
{
"name" : "XRGY Virtual Data Center",
"uri" : "http://xrgy.cloud.sun.com/vdc",
"vm_templates" : "http://cloud.sun.com/resources/template-cat.json",
"addresses" : [
{
"name": "144.34.100.199",
"uri": "/addresses/144.34.100.199",
"ip_address": "144.34.100.199"
}
],
"cluster" : {
"name" : "ROOT",
"uri" : "/vdc/",
"tags" : [ ],
"volumes" : [ ],
"clusters" : [
]
"tags" : [ ],
"controllers" : [
"start" : "/vdc/ops/start",
"stop" : "/vdc/ops/stop",
]
"vnets" : [
{
"name": "vnet1",
"uri": "/vnets/10.31.145.0",
"netmask": "255.255.255.0",
"network": "10.31.145.0"
}
],
"vms": [
{
* SNIPPED *
}
]
}
}
I have seen other examples where the media-type is also part of the links in the response, such as this following response and i can understand that.
201 Created
Content-Type: application/vnd.bank.org.transfer+xml;charset=UTF-8
<transfer xmlns="urn:org:bank:accounts">
<link rel="self"
href="http://bank.org/transfer/XTA8763"/>
<link rel="http://bank.org/rel/transfer/from"
type="application/vnd.bank.org.account+xml"
href="http://bank.org/account/AZA12093"/>
<link rel="http://bank.org/rel/transfer/to"
type="application/vnd.bank.org.account+xml"
href="http://bank.org/account/ADK31242"/>
<link rel="http://bank.org/rel/transfer/status"
type="application/vnd.bank.org.status+xml"
href="http://bank.org/check/XTA8763"/>
<id>transfer:XTA8763</id>
<amount currency="USD">100</amount>
<note>RESTing</note>
</transfer>
Simply put, yes, the client needs to have some a priori knowledge of the media types involved. Since the client actually sets the media types that it can consume. Since the client only understands "some" media types, if it sends a request with a media type that the application does not support, then the client is pretty much out of luck.
Since, in the the real world, we try to not have clients make blind calls to services returning payloads that they don't understand, the client will have some fore knowledge of the payloads involved, especially very specific types (vs plain/text or application/xml).
Finally, recall that the media type will effectively tell you the SYNTAX of the payloads but not how to interpret the payloads. Those semantics your client will have to know up front as well, so the burden of having an initial understanding of a media type is in fact not particularly a barrier to participation, it's just a fact of life.
Clients are responsible for telling servers what kind of response they understand/prefer. That is what the Accept header indicates. Servers respond with content that attempts to satisfy the client's request. The Content-Type header indicates what is actually returned. Ideally, the value of this header is the same as that of the Accept header.
See sections 14.1 and 14.17 in RFC 2616.
In your example, the client author probably is injecting knowledge into the client and this is not truly a 100% RESTful client.

Google plus moments api adding activity with only url in the target is not showing up in the history tab

I created an activity json as following and posting to the google plus moments api
var activity = {
"type": "http://schemas.google.com/AddActivity",
"target": {
"url": "http://www.qontext.com"
}};
POST is successful but the moment is not shown the history. Authentication is taken care of.
Example url works fine. Can somebody help.
As long as the provided target url does not return (html) content that includes the required meta data (http://schema.org/Thing) your inserted element will not show up in the Google+ History (no matter if the Response will be a HTTP 200 or not).
Providing your meta data in the request body (as "result" JSON) does not work either. So you have to ensure that the target url will return HTML that contains the data that you would like to post.
E.g. this can be done via a simple PHP script like this:
<?php
$name = $_GET["name"];
$desc = $_GET["desc"];
echo('
<!DOCTYPE html>
<html>
<head>
<title>emacberry DATA</title>
</head>
<body itemscope itemtype="http://schema.org/Thing">
<section>Name: <div itemprop="name">'.$name.'</div></section>
<section>Description: <div itemprop="description">'.$desc.'</div></section>
<section>
Thumbnail: <img itemprop="image" src="YOUR_LOGO_HERE"/>
</section>
</body>
</html>
');
?>
so then just post
{
"type":"http://schemas.google.com/AddActivity",
"target":{
"url":"http://YOUR_SERVER/YOUR_SCRIPT.PHP?name=A_NAME&desc=A_DESC"
}
}
by doing so you activity will be added to the Google+ History - but of course that implies interactivity with your server - which can also have some benefits for you.
There isn't enough information to be sure, but I would investigate the following:
1) Make sure you have debug=true in the call to the moments API. As in:
path: '/plus/v1moments/people/me/moments/vault?debug=true'
and then make sure that you're looking at what comes back to see if there are any errors.
2) Make sure you have schema.org markup in the target page. While usually they're good about getting something from the page, it could just be that the page is too complex or large for them to get useful info out of the whole thing.
I tried submitting your moment:
{
"type":"http://schemas.google.com/AddActivity",
"target":{
"url":"http://www.qontext.com"
}
}
to the demo application at:
http://plus-history-examples.appspot.com/client-side-flow/index.html
And the returned response was:
{
"error": {
"errors": [
{
"domain": "global",
"reason": "badRequest",
"message": "Unable to fetch metadata."
}
],
"code": 400,
"message": "Unable to fetch metadata."
}
}
So I suspect the problem is lack of metadata at http://www.qontext.com