Getting activities list with a distances in Google Fit API (REST) - google-fit

I need to get a list of recent activities in Google Fit, including the distance traveled.
I am using direct REST API requests (PHP via cURL).
First, I do authorization via oAuth 2.0
https://accounts.google.com/o/oauth2/v2/auth?client_id=%CLIENT_ID%&redirect_uri=%REDIRECT_URI%&response_type=code&scope=https://www.googleapis.com/auth/fitness.activity.read%20https://www.googleapis.com/auth/fitness.location.read
After authorization, I'm redirected to my site %REDIRECT_URI%, where the GET request contains "code".
I use this "code" to get the auth token:
POST - https://www.googleapis.com/oauth2/v3/token
POST data: {
'code': %CODE_FROM_GET_PARAM%,
'client_id' => %CLIENT_ID%,
'client_secret' => %CLIENT_SECRET%,
'grant_type' => 'authorization_code',
'redirect_uri' => %REDIRECT_URI%
}
After completing the request, I receive an auth token of the form "ya29.a0ARrdaM-...", I use this token for header Bearer authorization.
I make a request https://www.googleapis.com/fitness/v1/users/me/sessions to get a list of activities:
"session": [
{
"id": "Run1629350880000",
"name": "Run",
"description": "",
"startTimeMillis": "1629350880000",
"endTimeMillis": "1629352020000",
"modifiedTimeMillis": "1629358291250",
"application": {
"packageName": "com.xiaomi.hm.health"
},
"activityType": 8
}, ...
]
Based on this list, I can see the running time (startTimeMillis, endTimeMillis), but I still need to get the distance.
What should I do next?

All actions taken from the question are correct.
Next, you need to send a request to https://www.googleapis.com/fitness/v1/users/me/dataset:aggregate
CURL request:
You can remove "<---" comments and push this CURL code to Postman to see this request with UI
curl --location --request POST 'https://www.googleapis.com/fitness/v1/users/me/dataset:aggregate' \
--header 'Authorization: Bearer %AUTH_TOKEN%' \ <--- Real Auth token
--header 'Content-Type: application/json' \
--data-raw '{
"aggregateBy": [
{
"dataTypeName": "com.google.distance.delta",
"dataSourceId": "derived:com.google.distance.delta:com.google.android.gms:merge_distance_delta"
}
],
"startTimeMillis": 1629350880000, <--- "startTimeMillis" from session data
"endTimeMillis": 1629352020000 <--- "endTimeMillis" from session data
}'
Response:
{
"bucket": [
{
"startTimeMillis": "1629350880000",
"endTimeMillis": "1629352020000",
"dataset": [
{
"dataSourceId": "derived:com.google.distance.delta:com.google.android.gms:merge_distance_delta",
"point": [
{
"startTimeNanos": "1629350880000000000",
"endTimeNanos": "1629352020000000000",
"dataTypeName": "com.google.distance.delta",
"originDataSourceId": "raw:com.google.distance.delta:com.xiaomi.hm.health:GoogleFitSyncHelper- distance0",
"value": [
{
"fpVal": 874, <--- distance in meters
"mapVal": []
}
]
}
]
}
]
}
]
}

Related

Eclipse Ditto - Create a MQTT Connection - fails with invalid json 400 response

Establishing a connection to an MQTT 3.1.1 endpoint following the description here and
the Operating Devops Commands end up in an invalid json 400 response. Even the example MQTT-Bidirectional gets refused with a 400. So this is why i am posting this question here to get hints what i am currently doing wrong and what i can do to get it right to help others running in the same issue. Here is my curl request:
gd#gd:~/ditto/mosquitto$ curl -X POST 'http://{ditto-url}/devops/piggyback/connectivity?timeout=10000' -u devops:foobar -H 'Content-Type: application/json' -d createMQTT_connection.json
{"status":400,"error":"json.invalid","message":"Failed to parse JSON string 'createMQTT_connection.json'!","description":"Check if the JSON was valid (e.g. on https://jsonlint.com) and if it was in required format."}
The hint to check my json file gives back that my json is valid.
Here is how my json file currently looks like:
{
"targetActorSelection": "/system/sharding/connection",
"headers": {
"aggregate": false
},
"piggybackCommand": {
"type": "connectivity.commands:createConnection",
"connection": {
"id": "mqtt-example-connection-123",
"name": "mmqtt-example-connection-123",
"connectionType": "mqtt",
"connectionStatus": "open",
"failoverEnabled": true,
"uri": "tcp://{mqtt-broker-url}:1883",
"sources": [
{
"addresses": [
"{ditto-url}/#"
],
"authorizationContext": ["nginx:ditto"],
"qos": 0,
"filters": []
}
],
"targets": [
{
"address": "{ditto-url}/{{ thing:id }}",
"topics": [
"_/_/things/twin/events"
],
"authorizationContext": ["nginx:ditto"],
"qos": 0
}
]
}
}
}
Someone got an idea why this json is not valid?
Thanks for the support and hints to solve this issue!
[EDIT]
First of all a "-f" makes more sense for the curl request:
curl -X POST -u devops:foobar 'http://{ditto-url}:8080/devops/piggyback/connectivity?timeout=10000' -f createMQTT_connection_1.json
curl: (22) The requested URL returned error: 400 Bad Request
curl: (6) Could not resolve host: createMQTT_connection_1.json
Second here the update json (with the result shown above)
{
"targetActorSelection": "/system/sharding/connection",
"headers": {
"aggregate": false
},
"piggybackCommand": {
"type": "connectivity.commands:createConnection",
"connection": {
"id": "mqtt-example-connection-123",
"connectionType": "mqtt",
"connectionStatus": "open",
"failoverEnabled": true,
"uri": "tcp://{MQTT-Broker-url}:1883",
"sources": [{
"addresses": ["ditto-tutorial/#"],
"authorizationContext": ["nginx:ditto"],
"qos": 0,
"filters": []
}],
"targets": [{
"address": "ditto-tutorial/{{ thing:id }}",
"topics": [
"_/_/things/twin/events",
"_/_/things/live/messages"
],
"authorizationContext": ["nginx:ditto"],
"qos": 0
}]
}
}
}
I think the problem you face is curl related.
Please have a look here on how to send json data from a file: https://stackoverflow.com/a/18614411/5058051
Seems the # is missing in your case when specifying the file location.

Can we used google drive's 'watch' API for polling data? How can we use 'watch' API to track changes?

I am using changes API to track my G-Drive changes, but it's not giving the complete resource data. Can I use 'watch' API to poll my resources?
Below is my request for changes API:
curl -X GET \
'https://www.googleapis.com/drive/v3/changes?pageToken=46' \
-H 'Accept: */*' \
-H 'Accept-Encoding: gzip, deflate' \
-H 'Authorization: Bearer <Token>' \
Here's the response:
"changes": [
{
"kind": "drive#change",
"type": "file",
"changeType": "file",
"time": "2019-10-10T09:15:12.313Z",
"removed": false,
"fileId": "<File_ID>",
"file": {
"kind": "drive#file",
"id": "<File_ID>",
"name": "shared",
"mimeType": "application/vnd.google-apps.folder"
}
}
]
But using this, I cannot decide the file is created or updated..
When you get a Changes resource, the response has a specific format.
You can see that the Changes has the property file that is of type Files.
What you want to do is inspect the Files resource returned by the change to monitor the state of the file between changes.
Hope this helps!

Potential Error in Forge Post Job Docs with destination

Looking at the documentation for the Forge Post Job. The examples show that region is a sub object of destination. However the docs seem to show that they are on the same level.
Doc was uploaded as image.
Curl Request Example:
curl -X 'POST' \
[![enter image description here][2]][2]-H 'Content-Type: application/json; charset=utf-8' \
-H 'Authorization: Bearer PtnrvrtSRpWwUi3407QhgvqdUVKL'
-v 'https://developer.api.autodesk.com/modelderivative/v2/designdata/job' \
-d
'{
"input": {
"urn": "dXJuOmFkc2sub2JqZWN0czpvcy5vYmplY3Q6bW9kZWxkZXJpdmF0aXZlL0E1LnppcA",
"compressedUrn": true,
"rootFilename": "A5.iam"
},
"output": {
"destination": {
"region": "us"
},
"formats": [
{
"type": "svf",
"views": [
"2d",
"3d"
]
}
]
}
}'
Thanks for reporting this.
I've let our Dev Portal team know to take a look and will get back to you once they fix this up. Thanks!

Authenticate to custom OpenAM 12 authentication plugin via REST

Would like to know how to authenticate to (for example):
http://www.example.com:8080/openam/UI/Login?realm=CUR&module=CURAuthn
preferably by POSTing JSON via REST over /json/authenticate.
I'm guessing it would be http://www.example.com:8080/openam/UI/Login?realm=CUR&authIndexType=module&authIndexValue=CURAuthn correct?
In any case this module doesn't take the standard X-OpenAM-Username or X-OpenAM-Password headers.
It takes a bunch of custom fields, called ID tokens. For instance it uses IDToken1, IDToken2, IDToken3, ...
How should I go about submitting the tokens to this plugin using the json authentication service? Thanks
All this is explained in the OpenAM's Developer's Guide section 3.4.
The REST URL for your custom module would be:
http://www.example.com:8080/openam/json/authenticate?authIndexType=module&authIndexValue=CURAuthn
If you module doesn't use the standard username/password credentials you'll have to pass your credentials in the request body as JSON.
You would start by sending a empty POST request to OpenAM:
$ curl \
--request POST \
--header "Content-Type: application/json" \
http://www.example.com:8080/openam/json/authenticate?authIndexType=module&authIndexValue=CURAuthn
You should get a response similar to this (based on your custom callbacks):
{
"authId": "eyAid...GDYaEQ",
"template": "",
"stage": "Module11",
"header": "Using CURAuthn",
"callbacks": [
{
"type": "NameCallback",
"output": [
{
"name": "prompt",
"value": "FirstCallback"
}
],
"input": [
{
"name": "IDToken1",
"value": ""
}
]
},
{
"type": "NameCallback",
"output": [
{
"name": "prompt",
"value": "SecondCallback"
}
],
"input": [
{
"name": "IDToken2",
"value": ""
}
]
},
//More callbacks here
]
}
After that just collect the credentials from the user input, fill in the empty values and submit the JSON payload back to the same URL. Make sure you use the same "authId" throughout the authentication process.
I wrote a blog post about custom authentication chains and how to communicate with them via REST. Take a look, it might be helpful.

Unable to list memberships for groups which are collaborators through the box API

I'm getting an error trying to list membership of Groups which are collaborators on a folder. Here's a sample folder collaborators request -
curl https://api.box.com/2.0/folders/1531887577/collaborations -H "Authorization: Bearer ACCESS_TOKEN"
And the response -
{
"total_count":6,
"entries":[
{
"type":"collaboration",
"id":"25306820",
"created_by":null,
"created_at":"2012-09-06T09:48:20-07:00",
"modified_at":"2013-10-19T09:37:14-07:00",
"expires_at":null,
"status":"accepted",
"accessible_by":{
"type":"user",
"id":"184577095",
"name":"Clayton C",
"login":"clayc#xxxxxxx.com"
},
"role":"editor",
"acknowledged_at":"2012-09-06T09:48:20-07:00",
"item":{
"type":"folder",
"id":"379625555",
"sequence_id":"7",
"etag":"7",
"name":"Business"
}
},
.... more users ....,
{
"type":"collaboration",
"id":"39809829",
"created_by":null,
"created_at":"2013-05-27T09:20:32-07:00",
"modified_at":"2013-10-23T04:20:34-07:00",
"expires_at":null,
"status":"accepted",
"accessible_by":{
"type":"group",
"id":"120995",
"name":"IT"
},
"role":"editor",
"acknowledged_at":"2013-05-27T09:20:32-07:00",
"item":{
"type":"folder",
"id":"379625555",
"sequence_id":"7",
"etag":"7",
"name":"NewBusiness"
}
},
.... more groups ....,
]
}
Note group "IT" with ID "120995" in the list of collaborators. Now I request membership for the group
curl https://api.box.com/2.0/groups/120995/memberships -H "Authorization: Bearer ACCESS_TOKEN"
And I get this weird error response.
{
"type":"error",
"status":404,
"code":"not_found",
"context_info":{
"errors":[
{
"reason":"invalid_parameter",
"name":"group_tag",
"message":"Invalid value 'g_120995'. 'group_tag' with value 'g_120995' not found"
}
]
},
"help_url":"http:\/\/developers.box.com\/docs\/#errors",
"message":"Not Found",
"request_id":"184613996752e9780c42c3f"
}
Has anyone seen similar behavior and found a solution?
The docs say: "Note this is only available to group admins."