multiple permisions scope google fit api integration - google-fit

I am integrating Google fit API in an open source project am working on where I allow the user to login with the Google account credentials and through the user consent process. I have this error when I try to pass in additional scope permissions on the sign in Uri. I am not sure if it's a problem with my URL encoding because I am sure the API expects an array of scope urls. Is it possible to put multiple permissions in one oauth flow in Google fit API integration?
The first URL is working fine but the others get an error instead of redirecting.
https://accounts.google.com/ServiceLogin?passive=1209600&continue=https://accounts.google.com/o/oauth2/auth?access_type%3Doffline%26as%3D43045f60390ad399%26approval_prompt%3Dforce%26scope%3Dhttps://www.googleapis.com/auth/fitness.activity.read%26response_type%3Dcode%26redirect_uri%3Dhttps://developers.google.com/oauthplayground%26client_id%3D1086862838918-d6epsnkqrid4tu786geh3nfugpga2ii5.apps.googleusercontent.com%26from_login%3D1&oauth=1&sarp=1&scc=1
https://accounts.google.com/ServiceLogin?passive=1209600&continue=https://accounts.google.com/o/oauth2/auth?access_type%3Doffline%26as%3D43045f60390ad399%26approval_prompt%3Dforce%26scope%3D%5B%22https://www.googleapis.com/auth/fitness.activity.read%22%2%22https://www.googleapis.com/auth/fitness.activity.write%26response_type%3Dcode%22%5D%26redirect_uri%3Dhttps://developers.google.com/oauthplayground%26client_id%3D1086862838918-d6epsnkqrid4tu786geh3nfugpga2ii5.apps.googleusercontent.com%26from_login%3D1&oauth=1&sarp=1&scc=1

Have you check the Getting Started on Android documentation of Google? Here is their sample code for adding scope:
mClient = new GoogleApiClient.Builder(this)
.addApi(Fitness.SENSORS_API)
.addScope(new Scope(Scopes.FITNESS_LOCATION_READ))
.addConnectionCallbacks(this)
.build()
You can try using addApi() and addScope() to get permission of Scope to be used.
From this tutorial:Google Fit for Android: Sessions API, it is possible to add multiple permission scope for Google Fit API integration.
Here is their sample code:
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ButterKnife.bind(this);
mGoogleApiClient = new GoogleApiClient.Builder(this)
.addApi(Fitness.SESSIONS_API)
.addApi(Fitness.HISTORY_API)
.addScope(new Scope(Scopes.FITNESS_LOCATION_READ_WRITE))
.addScope(new Scope(Scopes.FITNESS_ACTIVITY_READ_WRITE))
.addConnectionCallbacks(this)
.enableAutoManage(this, 0, this)
.build();
}
EDIT:
For web I think you can use Requesting additional permissions via OAuth 2.0
auth2 = gapi.auth2.init({
client_id: 'CLIENT_ID.apps.googleusercontent.com',
cookiepolicy: 'single_host_origin', /** Default value **/
scope: 'profile' }); /** Base scope **/
Wherever additional scopes are needed, request them by constructing an options builder with the scopes you want to add and then calling user.grant({scope: [OPTIONS BUILDER]}).then(successFunction, failFunction);:
var options = new gapi.auth2.SigninOptionsBuilder(
{'scope': 'email https://www.googleapis.com/auth/drive'});
googleUser = auth2.currentUser.get();
googleUser.grant(options).then(
function(success){
console.log(JSON.stringify({message: "success", value: success}));
},
function(fail){
alert(JSON.stringify({message: "fail", value: fail}));
});
Add this to you node.js then here is the list of scope for Google FIT web
HTH

Related

Implementing Revit to Excel Exporter in Autodesk Forge

I am attempting to implement the Revit to Excel exporter discussed here. The button is working and passing urn and token to
ForgeXLS.downloadXLSX(urn, token, callback /*Optional*/);
I receive an error" "GET " 403 (forbidden)"
I am extending the Extensions Skeleton tutorial found here.
Is it possible that there is an issue with the scopes... if so can you guide me as to how to adjust the scope of the access token I am pulling?
Code for ForgeXLSX.downloadXLSX is:
downloadXLSX: function (urn, token, status) {
var fileName = decodeURIComponent(atob(urn).replace(/^.*[\\\/]/, '')) + '.xlsx';
if (fileName.indexOf('.rvt') == -1) {
if (status) status(true, 'Not a Revit file, aborting.');
return;
}
if (status) {
status(false, 'Preparing ' + fileName);
status(false, 'Reading project information....');
}
this.prepareTables(urn, token, function (tables) {
if (status) status(false, 'Building XLSX file...');
var wb = new Workbook();
jQuery.each(tables, function (name, table) {
if (name.indexOf('<')==-1) { // skip tables starting with <
var ws = ForgeXLS.sheetFromTable(table);
wb.SheetNames.push(name);
wb.Sheets[name] = ws;
}
});
var wbout = XLSX.write(wb, {bookType: 'xlsx', bookSST: true, type: 'binary'});
saveAs(new Blob([s2ab(wbout)], {type: "application/octet-stream"}), fileName);
if (status) status(true, 'Downloading...');
})
},
Scope wise, you will need both data:read bucket:read to have sufficient access to model metadata:
Token with insufficient scope ends up with a 403:
Make sure your server sets scope up properly in the request body to fetch access tokens.
And your best bet to observe the URN and Token variables in the process of calling the Forge endpoints is here at ForgeXLS.forgeGetRequest:
After digging around a bit (and some help from a friend) figured out that it was the scopes after all. Adding 'data:read' scope to the public scope in the config.js file provided the needed access and the exporter now works.
scopes: {
// Required scopes for the server-side application
internal: ['bucket:create', 'bucket:read', 'data:read', 'data:create', 'data:write'],
// Required scope for the client-side viewer
public: ['viewables:read', 'data:read']
}

GMail OAUTH not asking for permission when published

I've started using the GMail API and it's working fine on my local machine; it will open the Google permissions page and I can select my account. It then stores the return json token and only asks again if this token is removed.
When I publish to the server, the OAUTH page is never displayed and the application appears to timeout with a 'Thread was being aborted' exception.
My code;
try
{
using (var stream = new FileStream(HttpContext.Current.Server.MapPath("~/credentials/client_id.json"), FileMode.Open, FileAccess.Read))
{
string credPath = HttpContext.Current.Server.MapPath("~/credentials/gmail_readonly_token.json");
_credential = GoogleWebAuthorizationBroker.AuthorizeAsync(
GoogleClientSecrets.Load(stream).Secrets,
Scopes,
"user",
CancellationToken.None,
new FileDataStore(credPath, true)).Result;
db.writeLog("INFO", "Gmail Credentials Saved","Credential file saved to: " + credPath);
}
// Create Gmail API service.
service = new GmailService(new BaseClientService.Initializer()
{
HttpClientInitializer = _credential,
});
}
catch (Exception e)
{
db.writeLog("Error", "Failure when creating Gmail class", e.Message, null, _username, null);
}
Is there something I need to change within the 'client_id.json' (formally client_secret.json) file? The only thing I have altered is the redirect_uris line.
Any other suggestions would be welcome, the only other question I could find that is similar is here but there is no answer.
Thanks,
Danny.
The first one worked because you followed the intended use case, which is client-side. But, to implement authorization on the server, follow the Implementing Server-Side AUthorization guide.

Replace Video Resource with VIMEO API

I am trying to replace existing video on VIMEO with
advanced api from : https://github.com/vimeo/vimeo.php#replace-videos-from-the-server.
The code is:
$vimeo = new \Vimeo\Vimeo('xxxxxxxxxxxxxxx', 'xxxxxxxxxxxxxxx');
$vimeo->setToken("xxxxxxxxxxxxxxx");
$video_id_on_vimeo = 123456; // not real id
$vimeo->replace("/videos/" . $video_id_on_vimeo, $path_to_file, false);
However it throws me an error "Unable to get an upload ticket.[The requested user could not be found]'
All other commands do work. I am using OAUTH 2 and scopes configured for using apis are:
public private purchased create edit delete interact upload.
in order to run example, just execute POST request to http://panels.veedi.com/api/video/test
Vimeo development team fixed the bug.
Now everything is working. In addition in API description of replacement process, they have mistake.
Instead of:
$response = $lib->upload('/videos/12345', '/home/aaron/Downloads/ada.mp4', false);
You should use:
$response = $lib->replace('/videos/12345', '/home/aaron/Downloads/ada.mp4', false);

How can I pass data between two Chrome apps?

I have created two Chrome apps and I want to pass some data (string format) from one Chrome app to another Chrome app. Appreciate if someone can help me with showing the correct way of doing this?
It's an RTFM question.
From Messaging documentation (note that it mentions extensions, but it works for apps):
In addition to sending messages between different components in your extension, you can use the messaging API to communicate with other extensions. This lets you expose a public API that other extensions can take advantage of.
You need to send messages using chrome.runtime.sendMessage (using app ID) and receive them using chrome.runtime.onMessageExternal event. If required, long-lived connections can also be established.
// App 1
var app2id = "abcdefghijklmnoabcdefhijklmnoab2";
chrome.runtime.onMessageExternal.addListener(
// This should fire even if the app is not running, as long as it is
// included in the event page (background script)
function(request, sender, sendResponse) {
if(sender.id == app2id && request.data) {
// Use data passed
// Pass an answer with sendResponse() if needed
}
}
);
// App 2
var app1id = "abcdefghijklmnoabcdefhijklmnoab1";
chrome.runtime.sendMessage(app1id, {data: /* some data */},
function(response) {
if(response) {
// Installed and responded
} else {
// Could not connect; not installed
// Maybe inspect chrome.runtime.lastError
}
}
);

Chromecast subtitles on default receiver applications

I am trying to include subtitles on a Chromecast application I'm building.
I am using the default receiver application.
I am writing a chrome sender application using v1 of the chrome sender api.
According to the Chromecast Sender Api documentation, I should be passing in an array of track objects into the chrome.cast.media.MediaInfo object. My issue is, whenever I call chrome.cast.media.Track(trackId, trackType), it returns undefined. When I look through the public methods in chrome.cast.media, through console, I don't see anything related to Track. Link to documentation here.
Below is my loadMedia method where I try to include an array of track objects along with my LoadRequest as specified by the cast api. The commented out code is how I've seen closed-captioning handled in one of the cast Github repositories, but unfortunately I believe you have to handle that customData in your own custom receiver application.
Are subtitles through the chrome sender SDK possible yet, or does one have to build their own receiver application and specifically handle text tracking through passed in customData? Am I potentially using the wrong sender api?
function loadMedia() {
mediaUrl = decodeURIComponent(_player.sources.mp4);
var mediaInfo = new chrome.cast.media.MediaInfo(mediaUrl);
mediaInfo.contentType = 'video/mp4';
var track1 = new chrome.cast.media.Track(1, chrome.cast.media.TrackType.TEXT);
track1.trackContentId = "https://dl.dropboxusercontent.com/u/35106650/test.vtt";
mediaInfo.tracks = [track1];
var request = new chrome.cast.media.LoadRequest(mediaInfo);
// var json = {
// cc: {
// tracks: [{
// src: "https://dl.dropboxusercontent.com/u/35106650/test.vtt"
// }],
// active: 0
// }
// };
// request.customData = json;
session.loadMedia(request, onMediaDiscovered.bind(this, 'loadMedia'), onMediaError);
}
Currently, neither the Default nor the Styled Receivers support Closed Caption; you need to create your own. We have a sample in our GitHub repo that can be used for doing exactly that.
Update: Styled and Default receivers now support Tracks, see our documentations.