How to get permissionId in Drive API v3? - google-drive-api

I want to delete permission from the file.
In Drive API v2,
PermissionId permissionId = service.permissions().getIdForEmail(account).execute();
service.permissions().delete(fileId, permissionId.getId()).execute();
But According to document, permissions().getIdForEmail(String email) is removed and alternate is nothing.
https://developers.google.com/drive/v3/web/migration
I can't find how to get permissionId from specific Email address in drive API v3.
Do you have any idea?

I found a simple solution:
PermissionList permissions = service.permissions().list(sharedFolderId).setFields("nextPageToken, permissions(id,emailAddress)").execute();
for (Permission p : permissions.getPermissions()) {
if (p.getEmailAddress().equals(adresseEmail)) {
service.permissions().delete(sharedFolderId, p.getId()).execute();
}
}

Two years later, but your question was the first result I found when searching for a solution. I found a workaround and I hope this will help others with the same issue. This is what I did to get the permission id:
this.getPermissionId = function(emailAddress) {
return new Promise((resolve, reject) => {
const input = {
q: '"' + emailAddress + '" in writers or "' + emailAddress + '" in readers',
fields: 'files(permissions)',
pageSize: 1
};
const request = gapi.client.drive.files.list(input);
request.execute(result => {
if(result.error) {
reject(result.error);
} else if(result.files && result.files[0] && result.files[0].permissions && result.files[0].permissions[0]) {
const permissions = result.files[0].permissions;
let permissionId;
permissions.forEach(permission => {
if(permission.emailAddress == emailAddress) {
permissionId = permission.id;
}
});
if(permissionId) {
resolve(permissionId);
}
else {
reject('permissionIdUndefined');
}
}
});
})
};

a .NET version that solved my needs
public static string GetPermissionIdForEmail(DriveService service, string emailAddress)
{
string pageToken = null;
do
{
var request = service.Files.List();
request.Q = $"'{emailAddress}' in writers or '{emailAddress}' in readers or '{emailAddress}' in owners";
request.Spaces = "drive";
request.Fields = "nextPageToken, files(id, name, permissions)";
request.PageToken = pageToken;
var result = request.Execute();
foreach (var file in result.Files.Where(f => f.Permissions != null))
{
var permission = file.Permissions.SingleOrDefault(p => string.Equals(p.EmailAddress, emailAddress, StringComparison.InvariantCultureIgnoreCase));
if (permission != null)
return permission.Id;
}
pageToken = result.NextPageToken;
} while (pageToken != null);
return null;
}

I have done this code in .NET using C#.
I hope you have already created the drive service using user's access token.
After that this code can help you to get permission ID:
var permissionFile = driveService.About.Get();
permissionFile.Fields = "*";
var perm = permissionFile.Execute();
permissionId = perm.User.PermissionId;
The permissionId will give you the required ID.

I use UrlFetchApp with Google Apps Script to replace Drive API v2 and Advanced Drive Service (based on v2).
With a company domain service account, the section getService(userEmail) uses the library https://github.com/googleworkspace/apps-script-oauth2 to send the request on behalf of userEmail.
/**
* Get user permission Id.
*
* #param {String} userEmail - Email address for About query.
* https://developers.google.com/drive/api/v3/reference/about
*/
function TEST_getIdForEmailV3() { getIdForEmailV3('YourEmail#CompanyDomain.com') }
function getIdForEmailV3(userEmail) {
var service = getService(userEmail);
if (service.hasAccess()) {
var url = 'https://www.googleapis.com/drive/v3/about' + '?fields=user/permissionId';
var options = {
'method': 'get',
'contentType': 'application/json',
'headers': { Authorization: 'Bearer ' + service.getAccessToken() }
};
var response = UrlFetchApp.fetch(url, options);
var resultParsed = JSON.parse(response.getContentText());
return resultParsed.user.permissionId;
} else {
return 0;
};
}

Related

question on accessing or getting specific google app script query parameter

I was wondering if I can access a specific query parameter from a method from activities.list API
specifically this piece of code
activity.events[0].parameters
I've already tried accessing through array like this:
activity.events[0].parameters[2]
but the output is not consistent, for instance index 2 is not what I need instead its a different query parameter. What I need is for example I need to access
organizer_email
parameter specifically from the API (https://developers.google.com/admin-sdk/reports/v1/appendix/activity/meet)
I'll attach my sample code here. its from google api examples
(https://developers.google.com/admin-sdk/reports/v1/quickstart/apps-script)
/**
* List login events for a G Suite domain.
* #see https://developers.google.com/admin-sdk/reports/reference/rest/v1/activities/list
*/
function getData() {
var today = new Date();
var oneWeekAgo = new Date(today.getTime() - 7 * 24 * 60 * 60 * 1000);
var timezone = Session.getScriptTimeZone();
var date = Utilities.formatDate(oneWeekAgo, timezone, 'yyyy-MM-dd');
const userKey = 'all';
const applicationName = 'meet';
var pageToken;
const optionalArgs = {
maxResults: 10,
pageToken: pageToken,
};
try {
const response = AdminReports.Activities.list(userKey, applicationName, optionalArgs);
const activities = response.items;
if (!activities || activities.length === 0) {
Logger.log('No logins found.');
return;
}
// Print login events
Logger.log('MEET LOGS:');
for (const activity of activities) {
Logger.log('(%s) %s %s', activity.events[0].parameters, activity.id.time, activity.id.time);
}
} catch (err) {
// TODO (developer)- Handle exception from the Report API
Logger.log('Failed with error %s', err.message);
}
}
sample array / json result (2 results)
[
{"name":"video_send_seconds","intValue":"40"},
{"name":"screencast_recv_bitrate_kbps_mean","intValue":"128"},
{"value":"email_address","name":"identifier_type"},
{"name":"audio_send_bitrate_kbps_mean","intValue":"2"},
{"name":"video_send_packet_loss_max","intValue":"1"},
{"value":"meetings_android_214151224321356190","name":"endpoint_id"},
{"name":"device_type","value":"android"},{"intValue":"0","name":"video_send_packet_loss_mean"},
{"intValue":"240","name":"video_recv_long_side_median_pixels"},
{"name":"screencast_recv_long_side_median_pixels","intValue":"1072"},
{"name":"screencast_send_seconds","intValue":"0"},
{"name":"video_send_fps_mean","intValue":"15"},
{"intValue":"4","name":"audio_send_packet_loss_max"},
{"intValue":"132","name":"video_recv_short_side_median_pixels"},
{"intValue":"0","name":"video_recv_packet_loss_mean"},
{"name":"screencast_recv_fps_mean","intValue":"8"},
{"intValue":"1267","name":"audio_recv_seconds"},
{"intValue":"0","name":"network_congestion"},
{"name":"network_estimated_download_kbps_mean","intValue":"1398"},
{"intValue":"0","name":"audio_send_packet_loss_mean"},
{"name":"network_transport_protocol","value":"udp"},
{"intValue":"1269","name":"duration_seconds"},
{"intValue":"103","name":"video_send_bitrate_kbps_mean"},
{"name":"identifier","value":"xxxxxx.xxxxx#xxxx.xxx"},
{"intValue":"78","name":"audio_recv_packet_loss_max"},
{"intValue":"10","name":"video_recv_fps_mean"},
{"intValue":"3","name":"audio_recv_packet_loss_mean"},
{"name":"network_recv_jitter_msec_max","intValue":"205"},
{"name":"organizer_email","value":"xxxxxx#xxxxx.xxx"},
{"name":"screencast_recv_short_side_median_pixels","intValue":"480"},
{"name":"network_recv_jitter_msec_mean","intValue":"19"},
{"name":"audio_send_seconds","intValue":"1267"},
{"value":"xxxxxxxxxx","name":"display_name"},
{"name":"screencast_recv_packet_loss_max","intValue":"0"},
{"name":"video_recv_seconds","intValue":"71"},
{"intValue":"35","name":"network_rtt_msec_mean"},
{"name":"video_send_long_side_median_pixels","intValue":"240"},
{"name":"screencast_recv_packet_loss_mean","intValue":"0"},
{"value":"fjqip32o1ru139DFSA2wer23","name":"conference_id"},
{"intValue":"883","name":"screencast_recv_seconds"},
{"name":"product_type","value":"meet"},
{"name":"network_estimated_upload_kbps_mean","intValue":"87"},
{"name":"video_send_short_side_median_pixels","intValue":"132"},
{"intValue":"0","name":"video_recv_packet_loss_max"},
{"name":"meeting_code","value":"ZXWEREHXSG"},
{"name":"is_external","boolValue":true}
]
2nd result:
[
{"name":"video_send_seconds","intValue":"0"},
{"name":"identifier_type","value":"email_address"},
{"name":"audio_send_bitrate_kbps_mean","intValue":"5"},
{"value":"meetings_android_23adjfuhvioalu23xpiow;","name":"endpoint_id"},
{"name":"device_type","value":"android"},
{"intValue":"0","name":"screencast_send_seconds"},
{"intValue":"0","name":"audio_recv_seconds"},
{"intValue":"0","name":"network_congestion"},
{"name":"network_estimated_download_kbps_mean","intValue":"0"},
{"value":"udp","name":"network_transport_protocol"},
{"name":"duration_seconds","intValue":"9"},
{"value":"xxxxxxxxxx.xxxxxxxxx#xxxxxx.xxxxxx","name":"identifier"},
{"value":"xxxxxxxxxxx#xxxxxxxx.xxxxx","name":"organizer_email"},
{"name":"audio_send_seconds","intValue":"7"},
{"name":"display_name","value":"xxxxxxxxxxxxx"},
{"intValue":"0","name":"video_recv_seconds"},
{"intValue":"30","name":"network_rtt_msec_mean"},
{"name":"conference_id","value":"4ersdfgwe3re43edf3s"},
{"name":"screencast_recv_seconds","intValue":"0"},
{"name":"product_type","value":"meet"},
{"name":"network_estimated_upload_kbps_mean","intValue":"0"},
{"name":"meeting_code","value":"43eradsfdas23hgrf"},
{"boolValue":true,"name":"is_external"}
]
found the answer
example usage:
activity.events[0].parameters.find(x => x.name ==='duration_seconds').intValue

Google analytics for Google apps-script doesn't show any data after a few weeks

I have an apps-script that I want to impression count in Google-Analytics.
I have created a new GA account + data stream.
Copied it's measurement id and put it in my app-script code:
/**
* Function to track all (internal/external) usage
* #param {string} page tracked
*/
function sendGA(page) {
var cid = Utilities.base64EncodeWebSafe(Utilities.computeDigest(
Utilities.DigestAlgorithm.SHA_256,
ScriptApp.getService().getUrl()));
try {
var data = {
'v': '1',
'tid': 'G-9S9...',
'z': Math.floor(Math.random()*10E7),
't':'pageview',
'dl': SpreadsheetApp.getActiveSpreadsheet().getUrl() + '/' + page,
'cid': cid
};
var payload = Object.keys(data).map(
function(key) {
return encodeURIComponent(key) + '=' + encodeURIComponent(data[key]);
}
).join('&');
var options = {
'method' : 'POST',
'payload' : payload
};
UrlFetchApp.fetch('http://www.google-analytics.com/collect', options);
} catch (err) {
Logger.log(err);
}
}
and
These were my installation steps, have I missed anything?
The measurement id goes in here? 'tid': 'G-9S9...',

Getting past permissions for a file through the API/Apps Script

I'm trying to create a list of files stored in my Google Drive and also a list of their current and previous permissions. Specifically, I want to create a list of files in my Google Drive which at any point in the past have had the 'Anyone with a link can view/edit (etc)' permission set.
I have created a Google Apps Script to do this and I can iterate through all the files OK and I can get files which currently have that permission set, but I can't see a way to get the history of the file's permissions.
I have found and activated the revisions list API: https://developers.google.com/drive/api/v2/reference/revisions/list
This gets revisions but I can't see anywhere that it lists the sharing history of a revision.
Is what I'm attempting to do possible?
It's definitely possible using the Drive Activity API. You can use the Quickstart for Google Apps Script to view all the activity of an item (file or folder) or done by a User. In this case I modified the Quickstart to show the Permissions changes of a given Drive Id.
function listDriveActivity() {
var request = {
itemName: "items/1bFQvSJ8pMdss4jInrrg7bxdae3dKgu-tJqC1A2TktMs", //Id of the file
pageSize: 10};
var response = DriveActivity.Activity.query(request);
var activities = response.activities;
if (activities && activities.length > 0) {
Logger.log('Recent activity:');
for (var i = 0; i < activities.length; i++) {
var activity = activities[i];
var time = getTimeInfo(activity);
var action = getActionInfo(activity.primaryActionDetail);
var actors = activity.actors.map(getActorInfo);
var targets = activity.targets.map(getTargetInfo);
if (action == "permissionChange"){ //Only show permissionChange activity
Logger.log(
'%s: %s, %s, %s', time, truncated(actors), action,
truncated(targets));
}
}
} else {
Logger.log('No activity.');
}
}
/** Returns a string representation of the first elements in a list. */
function truncated(array, opt_limit) {
var limit = opt_limit || 2;
var contents = array.slice(0, limit).join(', ');
var more = array.length > limit ? ', ...' : '';
return '[' + contents + more + ']';
}
/** Returns the name of a set property in an object, or else "unknown". */
function getOneOf(object) {
for (var key in object) {
return key;
}
return 'unknown';
}
/** Returns a time associated with an activity. */
function getTimeInfo(activity) {
if ('timestamp' in activity) {
return activity.timestamp;
}
if ('timeRange' in activity) {
return activity.timeRange.endTime;
}
return 'unknown';
}
/** Returns the type of action. */
function getActionInfo(actionDetail) {
return getOneOf(actionDetail);
}
/** Returns user information, or the type of user if not a known user. */
function getUserInfo(user) {
if ('knownUser' in user) {
var knownUser = user.knownUser;
var isMe = knownUser.isCurrentUser || false;
return isMe ? 'people/me' : knownUser.personName;
}
return getOneOf(user);
}
/** Returns actor information, or the type of actor if not a user. */
function getActorInfo(actor) {
if ('user' in actor) {
return getUserInfo(actor.user)
}
return getOneOf(actor);
}
/** Returns the type of a target and an associated title. */
function getTargetInfo(target) {
if ('driveItem' in target) {
var title = target.driveItem.title || 'unknown';
return 'driveItem:"' + title + '"';
}
if ('drive' in target) {
var title = target.drive.title || 'unknown';
return 'drive:"' + title + '"';
}
if ('fileComment' in target) {
var parent = target.fileComment.parent || {};
var title = parent.title || 'unknown';
return 'fileComment:"' + title + '"';
}
return getOneOf(target) + ':unknown';
}
Remember to enable the Drive Activity API in Resources > Advanced Google Services
In my example this returns the logs:
You can also look deeper into the Permissions by using the permissionChange Parameters in the query.
If you have a business/enterprise/edu account the admin audit logs will tell you this for 6 months of data. Or it will at least tell you when a permission was changed from x to y.
Can't think of a method for personal.

Successfully push the record into Firebase, but Google Chrome hangs while pushing the data

This is the controller file of my app. It adds the data perfectly, but when it reaches the then key word google chrome hangs but key parameter is also added to the data base. I can't figure out where the problem is.
.controller('recordsCtrl', ['$scope','$firebaseArray',function($scope,$firebaseArray) {
$scope.records = $firebaseArray(rootRef);
//show form
$scope.showAddForm = function(){
$scope.addFormShow = true;
}
// hide form
$scope.hide = function(){
$scope.addFormShow = false;
}
// submit contact
$scope.addFormSubmit = function() {
console.log("adding form...")
// Assign values
if ($scope.lname) { var lname = $scope.lname; } else { var lname = null; }
if ($scope.mname) { var mname = $scope.mname; } else { var mname = null; }
if ($scope.fname) { var fname = $scope.fname; } else { var fname = null; }
if ($scope.email) { var email = $scope.email; } else { var email = null; } if ($scope.conId) { var conId = $scope.conId; } else { var conId = null;}
// Build Object
$scope.records.$add({
fname: fname,
lname: lname,
mname: mname,
email: email,
company: company,
conId: conId
}).then(function(rootRef) {
***//this is not printed in the console but the key is assigned to the database***
console.log("Assign root key");
var id = rootRef.key();
console.log("Added Record with ID: " + id);
// clear Form
clearFields();
// Hide Form
$scope.addFormShow = false;
// send message to use
$scope.msg = "Record Added";
});
}
}]);
My team ran into this issue when we updated to Firebase 3.7.x. I believe this is a known bug.
Try downgrading to Firebase 3.6.x.

Building drive app from apps script - Whats wrong in the below code

Below is the code taken from Arun Nagarajan's Example: I am tried the same code to check.. But Its not installing properly. (I removed my redirect url, client id and secret in the below). Please tell me what wrong in the below code.
var AUTHORIZE_URL = 'https://accounts.google.com/o/oauth2/auth';
var TOKEN_URL = 'https://accounts.google.com/o/oauth2/token';
var REDIRECT_URL = 'exec';
var tokenPropertyName = 'GOOGLE_OAUTH_TOKEN';
var CLIENT_ID = '';
var CLIENT_SECRET = '';
function doGet(e) {
var HTMLToOutput;
if(e.parameters.state){
var state = JSON.parse(e.parameters.state);
if(state.action === 'çreate'){
var meetingURL = createMeetingNotes();
HTMLToOutput = '<html><h1>Meeting notes document created!</h1> <click here to open</html>';
}
else if (state.ids){
var doc = DocsList.getFileById(state.ids[0]);
var url = doc.getContentAsString();
HTMLToOutput = '"<html><a href="' +url+'"</a></html>"';
}
else {
zipAndSend(state.ecportIds.Session.getEffectUser().getEmail());
HTMLToOutput = '"<html><h1>Email sent. Check your Inbox.</h1></html>"';
}
}
else if(e.parameters.code){
getAndStoreAccessToken(e.parameters.code);
HTMLToOutput = '<html><h1>App is installed. You can close this window now or navigate to your </h1>Google Drive</html>';
}
else {
HTMLToOutput = '<html><h1>Install this App into your google drive </h1>Click here to start install</html>';
}
return HtmlService.createHtmlOutput(HTMLToOutput);
}
function getURLForAuthorization() {
return AUTHORIZE_URL + '?response_type=code&client_id=' + CLIENT_ID + '&redirect_uri=' + REDIRECT_URL + '&scope=https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fdrive.install+https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fuserinfo.email';
}
function getAndStoreAccessToken(code) {
var parameters = { method : 'post',
payload : 'client_id='+ CLIENT_ID + '&client_secret=' + CLIENT_SECRET + '&grant_type=authorization.code&redirect_uri=' + REDIRECT_URL};
var response = UrlFetchApp.fetch(TOKEN_URL.parameters).getContentText();
var tokenResponse = JSON.parse(response);
UserProperties.getProperty(tokenPropertyName, tokenResponse.access_token);
}
function getUrlFetchOptions() {
return {'contentType' : 'application/json',
'headers' : {'Authorization': 'Bearer ' + UserProperties.getProperty(tokenPropertyName),
'Accept' : 'application/json'}};
}
function IsTokenValid() {
return UserProperties.getProperty(tokenPropertyName);
}
The error showing is: Bad request:undefined
I think the error is inside the function called : getAndStoreAccessToken.
var parameters = { method : 'post',
payload : 'client_id='+ CLIENT_ID + '&client_secret=' + CLIENT_SECRET + '&grant_type=authorization.code&redirect_uri=' + REDIRECT_URL};
Please tell me the correct url format for payload.
The error seems in this line -
var response = UrlFetchApp.fetch(TOKEN_URL.parameters).getContentText();
I think you want TOKEN_URL , parameters (note the comma)
First, if you are trying to access Google Drive from within google apps script, what is the purpose of the authorization? Google drive is available w/o authorization. Are you trying to make your application utilize the gDrive of other users (or on behalf of other users)?
Second, instead of manually performing the authorization, which is very hard to troubleshoot, you can take advantage of Class OAuthConfig which simplifies the authorization/request process. The only disadvantage is that OAuthConfig currently uses OAuth1.0 (which is currently deprecated). Although it's particular use is Fusion Tables, and not drive, this library makes great use of OAuthConfig and .fetch and I have used it to model my own OAuth functions. My example below works great. The googleAuth() function sets up the authorization and then the rest of the application can make authorized requests using UrlFetchApp.fetch(url,options) while google does all the authorization stuff in the background.
function googleAuth(oAuthFields) {
var oAuthConfig = UrlFetchApp.addOAuthService(oAuthFields.service);
oAuthConfig.setRequestTokenUrl("https://www.google.com/accounts/"+
"OAuthGetRequestToken?scope=" + oAuthFields.scope);
oAuthConfig.setAuthorizationUrl("https://www.google.com/accounts/OAuthAuthorizeToken");
oAuthConfig.setAccessTokenUrl("https://www.google.com/accounts/OAuthGetAccessToken");
oAuthConfig.setConsumerKey(oAuthFields.clientId);
oAuthConfig.setConsumerSecret(oAuthFields.clientSecret);
return {oAuthServiceName:oAuthFields.service, oAuthUseToken:"always"};
}
function fusionRequest(methodType, sql, oAuthFields, contentType) {
var fetchArgs = OAL.googleAuth(oAuthFields);
var fetchUrl = oAuthFields.queryUrl;
fetchArgs.method = methodType;
if( methodType == 'GET' ) {
fetchUrl += '?sql=' + sql;
fetchArgs.payload = null;
} else{
fetchArgs.payload = 'sql='+sql;
}
if(contentType != null) fetchArgs.contentType = contentType;
Logger.log(UrlFetchApp.getRequest(oAuthFields.queryUrl, fetchArgs));
var fetchResult = UrlFetchApp.fetch(oAuthFields.queryUrl, fetchArgs);
if( methodType == 'GET' ) return JSON.parse(fetchResult.getContentText());
else return fetchResult.getContentText();
}