Below code is working fine. I can upload the data into Google Drive. Instead of Upload a data into Google Drive.
How to import data or ImportRows into Google Fusion Table directly? Can anyone help me and correct what I need to do.
E.g:
var request = gapi.client.request({
'path': '/upload/drive/v2/files',
'method': 'POST',
'params': {'uploadType': 'multipart'},
'headers': {
'Content-Type': 'multipart/mixed; boundary="' + boundary + '"'
},
Working Code :
<html>
<head>
<meta http-equiv="Content-type" content="text/html;charset=UTF-8">
<script type="text/javascript">
var CLIENT_ID = '607567025394-rmte05500pvsoj12dsrie1cbei5te506.apps.googleusercontent.com';
//var SCOPES = 'https://www.googleapis.com/auth/drive';
var SCOPES = 'https://www.googleapis.com/auth/fusiontables';
/**
* Called when the client library is loaded to start the auth flow.
*/
function handleClientLoad() {
window.setTimeout(checkAuth, 1);
}
/**
* Check if the current user has authorized the application.
*/
function checkAuth() {
gapi.auth.authorize(
{'client_id': CLIENT_ID, 'scope': SCOPES, 'immediate': true},
handleAuthResult);
}
/**
* Called when authorization server replies.
*
* #param {Object} authResult Authorization result.
*/
function handleAuthResult(authResult) {
var authButton = document.getElementById('authorizeButton');
var filePicker = document.getElementById('filePicker');
authButton.style.display = 'none';
filePicker.style.display = 'none';
if (authResult && !authResult.error) {
// Access token has been successfully retrieved, requests can be sent to the API.
filePicker.style.display = 'block';
filePicker.onchange = uploadFile;
} else {
// No access token could be retrieved, show the button to start the authorization flow.
authButton.style.display = 'block';
authButton.onclick = function() {
gapi.auth.authorize(
{'client_id': CLIENT_ID, 'scope': SCOPES, 'immediate': false},
handleAuthResult);
};
}
}
/**
* Start the file upload.
*
* #param {Object} evt Arguments from the file selector.
*/
function uploadFile(evt) {
gapi.client.load('drive', 'v2', function() {
var file = evt.target.files[0];
insertFile(file);
});
}
/**
* Insert new file.
*
* #param {File} fileData File object to read data from.
* #param {Function} callback Function to call when the request is complete.
*/
function insertFile(fileData, callback) {
const boundary = '-------314159265358979323846';
const delimiter = "\r\n--" + boundary + "\r\n";
const close_delim = "\r\n--" + boundary + "--";
var reader = new FileReader();
reader.readAsBinaryString(fileData);
reader.onload = function(e) {
var contentType = fileData.type || 'application/octet-stream';
var metadata = {
'title': fileData.name,
'mimeType': contentType
};
var base64Data = btoa(reader.result);
var multipartRequestBody =
delimiter +
'Content-Type: application/json\r\n\r\n' +
JSON.stringify(metadata) +
delimiter +
'Content-Type: ' + contentType + '\r\n' +
'Content-Transfer-Encoding: base64\r\n' +
'\r\n' +
base64Data +
close_delim;
var request = gapi.client.request({
'path': '/upload/drive/v2/files',
'method': 'POST',
'params': {'uploadType': 'multipart'},
'headers': {
'Content-Type': 'multipart/mixed; boundary="' + boundary + '"'
},
'body': multipartRequestBody});
if (!callback) {
callback = function(file) {
console.log(file)
};
}
request.execute(callback);
}
}
</script>
<script type="text/javascript" src="https://apis.google.com/js/client.js?onload=handleClientLoad"></script>
</head>
<body>
<!--Add a file picker for the user to start the upload process -->
<input type="file" id="filePicker" style="display: none" />
<input type="button" id="authorizeButton" style="display: none" value="Authorize" />
</body>
</html>
Fusion Tables also have a REST API. you can make the calls in the same way you are calling the Drive REST API.
For example to import rows you would need modify the api call and change the path to "upload/fusiontables/v2/tables/tableId/import"
It also uses POST method.
I see you have the correct scope for fusion tables: https://www.googleapis.com/auth/fusiontables
You'll also need to provide the data you want to import.
Hope this helps.
Related
I have tried making a web application using Google Drive and Gmail APIs.
When I ask for Google Drive or Gmail permission, all works correctly, but when I try asking for both permissions , the program only asks for one of them (either Google Drive or Gmail).
This is the code which asks for Google Drive permissions, extracted from:https://developers.google.com/drive/api/v3/quickstart/js
<!DOCTYPE html>
<html>
<head>
<title></title>
<meta charset="utf-8" />
</head>
<body>
<p></p>
<!--Add buttons to initiate auth sequence and sign out-->
<button id="authorize_button" style="display: none;">Authorize</button>
<button id="signout_button" style="display: none;">Sign Out</button>
<pre id="content" style="white-space: pre-wrap;"></pre>
<script type="text/javascript">
// Client ID and API key from the Developer Console
var CLIENT_ID = '<YOUR_CLIENT_ID>';
var API_KEY = '<YOUR_API_KEY>';
// Array of API discovery doc URLs for APIs used by the quickstart
var DISCOVERY_DOCS = ["https://www.googleapis.com/discovery/v1/apis/drive/v3/rest"];
// Authorization scopes required by the API; multiple scopes can be
// included, separated by spaces.
var SCOPES = 'https://www.googleapis.com/auth/drive.metadata.readonly';
var authorizeButton = document.getElementById('authorize_button');
var signoutButton = document.getElementById('signout_button');
/**
* On load, called to load the auth2 library and API client library.
*/
function handleClientLoad() {
gapi.load('client:auth2', initClient);
}
/**
* Initializes the API client library and sets up sign-in state
* listeners.
*/
function initClient() {
gapi.client.init({
apiKey: API_KEY,
clientId: CLIENT_ID,
discoveryDocs: DISCOVERY_DOCS,
scope: SCOPES
}).then(function () {
// Listen for sign-in state changes.
gapi.auth2.getAuthInstance().isSignedIn.listen(updateSigninStatus);
// Handle the initial sign-in state.
updateSigninStatus(gapi.auth2.getAuthInstance().isSignedIn.get());
authorizeButton.onclick = handleAuthClick;
signoutButton.onclick = handleSignoutClick;
}, function(error) {
appendPre(JSON.stringify(error, null, 2));
});
}
/**
* Called when the signed in status changes, to update the UI
* appropriately. After a sign-in, the API is called.
*/
function updateSigninStatus(isSignedIn) {
if (isSignedIn) {
authorizeButton.style.display = 'none';
signoutButton.style.display = 'block';
listFiles();
} else {
authorizeButton.style.display = 'block';
signoutButton.style.display = 'none';
}
}
/**
* Sign in the user upon button click.
*/
function handleAuthClick(event) {
gapi.auth2.getAuthInstance().signIn();
}
/**
* Sign out the user upon button click.
*/
function handleSignoutClick(event) {
gapi.auth2.getAuthInstance().signOut();
}
/**
* Append a pre element to the body containing the given message
* as its text node. Used to display the results of the API call.
*
* #param {string} message Text to be placed in pre element.
*/
function appendPre(message) {
var pre = document.getElementById('content');
var textContent = document.createTextNode(message + '\n');
pre.appendChild(textContent);
}
/**
* Print files.
*/
function listFiles() {
gapi.client.drive.files.list({
'pageSize': 10,
'fields': "nextPageToken, files(id, name)"
}).then(function(response) {
appendPre('Files:');
var files = response.result.files;
if (files && files.length > 0) {
for (var i = 0; i < files.length; i++) {
var file = files[i];
appendPre(file.name + ' (' + file.id + ')');
}
} else {
appendPre('No files found.');
}
});
}
</script>
<script async defer src="https://apis.google.com/js/api.js"
onload="this.onload=function(){};handleClientLoad()"
onreadystatechange="if (this.readyState === 'complete') this.onload()">
</script>
</body>
</html>
And this is the code which asks for Gmail permissions, extracted from:https://developers.google.com/gmail/api/quickstart/js
<!DOCTYPE html>
<html>
<head>
<title></title>
<meta charset="utf-8" />
</head>
<body>
<p></p>
<!--Add buttons to initiate auth sequence and sign out-->
<button id="authorize_button" style="display: none;">Authorize</button>
<button id="signout_button" style="display: none;">Sign Out</button>
<pre id="content" style="white-space: pre-wrap;"></pre>
<script type="text/javascript">
// Client ID and API key from the Developer Console
var CLIENT_ID = '<YOUR_CLIENT_ID>';
var API_KEY = '<YOUR_API_KEY>';
// Array of API discovery doc URLs for APIs used by the quickstart
var DISCOVERY_DOCS = ["https://www.googleapis.com/discovery/v1/apis/gmail/v1/rest"];
// Authorization scopes required by the API; multiple scopes can be
// included, separated by spaces.
var SCOPES = 'https://www.googleapis.com/auth/gmail.readonly';
var authorizeButton = document.getElementById('authorize_button');
var signoutButton = document.getElementById('signout_button');
/**
* On load, called to load the auth2 library and API client library.
*/
function handleClientLoad() {
gapi.load('client:auth2', initClient);
}
/**
* Initializes the API client library and sets up sign-in state
* listeners.
*/
function initClient() {
gapi.client.init({
apiKey: API_KEY,
clientId: CLIENT_ID,
discoveryDocs: DISCOVERY_DOCS,
scope: SCOPES
}).then(function () {
// Listen for sign-in state changes.
gapi.auth2.getAuthInstance().isSignedIn.listen(updateSigninStatus);
// Handle the initial sign-in state.
updateSigninStatus(gapi.auth2.getAuthInstance().isSignedIn.get());
authorizeButton.onclick = handleAuthClick;
signoutButton.onclick = handleSignoutClick;
}, function(error) {
appendPre(JSON.stringify(error, null, 2));
});
}
/**
* Called when the signed in status changes, to update the UI
* appropriately. After a sign-in, the API is called.
*/
function updateSigninStatus(isSignedIn) {
if (isSignedIn) {
authorizeButton.style.display = 'none';
signoutButton.style.display = 'block';
listLabels();
} else {
authorizeButton.style.display = 'block';
signoutButton.style.display = 'none';
}
}
/**
* Sign in the user upon button click.
*/
function handleAuthClick(event) {
gapi.auth2.getAuthInstance().signIn();
}
/**
* Sign out the user upon button click.
*/
function handleSignoutClick(event) {
gapi.auth2.getAuthInstance().signOut();
}
/**
* Append a pre element to the body containing the given message
* as its text node. Used to display the results of the API call.
*
* #param {string} message Text to be placed in pre element.
*/
function appendPre(message) {
var pre = document.getElementById('content');
var textContent = document.createTextNode(message + '\n');
pre.appendChild(textContent);
}
/**
* Print all Labels in the authorized user's inbox. If no labels
* are found an appropriate message is printed.
*/
function listLabels() {
gapi.client.gmail.users.labels.list({
'userId': 'me'
}).then(function(response) {
var labels = response.result.labels;
appendPre('Labels:');
if (labels && labels.length > 0) {
for (i = 0; i < labels.length; i++) {
var label = labels[i];
appendPre(label.name)
}
} else {
appendPre('No Labels found.');
}
});
}
</script>
<script async defer src="https://apis.google.com/js/api.js"
onload="this.onload=function(){};handleClientLoad()"
onreadystatechange="if (this.readyState === 'complete') this.onload()">
</script>
</body>
</html>
I have tried different ways to ask for both permissions, but no one of them has worked.
How do I ask for Gmail and Google Drive permissions at the same time?
PD: sorry for my English and for making a very long question :(
The difference between the two codes are the discovery docs and scopes used for the initiation of the gapi client
If you want to initialize a gapi client that it capable of performing both Gmail and Drive requests, you need to merge the respective discovery docs and scopes.
As stated in the comments of the code samples:
// Array of API discovery doc URLs for APIs used by the quickstart
and
// Authorization scopes required by the API; multiple scopes can be //
included, separated by spaces.
This means:
var DISCOVERY_DOCS = ["https://www.googleapis.com/discovery/v1/apis/drive/v3/rest", "https://sheets.googleapis.com/$discovery/rest?version=v4"];
and
var SCOPES = "https://www.googleapis.com/auth/drive.metadata.readonly https://www.googleapis.com/auth/spreadsheets.readonly";
Also, if the signIn is successful, either the function listFiles(); or listMajors(); is called, but to combine both functionalities, you probably want to call both functions (or merge them into one).
So in summary:
<!DOCTYPE html>
<html>
<head>
<title></title>
<meta charset="utf-8" />
</head>
<body>
<p></p>
<!--Add buttons to initiate auth sequence and sign out-->
<button id="authorize_button" style="display: none;">Authorize</button>
<button id="signout_button" style="display: none;">Sign Out</button>
<pre id="content" style="white-space: pre-wrap;"></pre>
<script type="text/javascript">
// Client ID and API key from the Developer Console
var CLIENT_ID = '199656296815-7rivr6cr4oj1fhprdptrq9evi6gvrrji.apps.googleusercontent.com';
var API_KEY = 'AIzaSyCpC-SyaoUN95t8gANPgPQptEW-7B57aCI';
// Array of API discovery doc URLs for APIs used by the quickstart
var DISCOVERY_DOCS = ["https://www.googleapis.com/discovery/v1/apis/drive/v3/rest", "https://sheets.googleapis.com/$discovery/rest?version=v4"];
// Authorization scopes required by the API; multiple scopes can be
// included, separated by spaces.
var SCOPES = "https://www.googleapis.com/auth/drive.metadata.readonly https://www.googleapis.com/auth/spreadsheets.readonly";
var authorizeButton = document.getElementById('authorize_button');
var signoutButton = document.getElementById('signout_button');
/**
* On load, called to load the auth2 library and API client library.
*/
function handleClientLoad() {
gapi.load('client:auth2', initClient);
}
/**
* Initializes the API client library and sets up sign-in state
* listeners.
*/
function initClient() {
gapi.client.init({
apiKey: API_KEY,
clientId: CLIENT_ID,
discoveryDocs: DISCOVERY_DOCS,
scope: SCOPES
}).then(function () {
// Listen for sign-in state changes.
gapi.auth2.getAuthInstance().isSignedIn.listen(updateSigninStatus);
// Handle the initial sign-in state.
updateSigninStatus(gapi.auth2.getAuthInstance().isSignedIn.get());
authorizeButton.onclick = handleAuthClick;
signoutButton.onclick = handleSignoutClick;
}, function(error) {
appendPre(JSON.stringify(error, null, 2));
});
}
/**
* Called when the signed in status changes, to update the UI
* appropriately. After a sign-in, the API is called.
*/
function updateSigninStatus(isSignedIn) {
if (isSignedIn) {
authorizeButton.style.display = 'none';
signoutButton.style.display = 'block';
listFiles();
listMajors();
} else {
authorizeButton.style.display = 'block';
signoutButton.style.display = 'none';
}
}
/**
* Sign in the user upon button click.
*/
function handleAuthClick(event) {
gapi.auth2.getAuthInstance().signIn();
}
/**
* Sign out the user upon button click.
*/
function handleSignoutClick(event) {
gapi.auth2.getAuthInstance().signOut();
}
/**
* Append a pre element to the body containing the given message
* as its text node. Used to display the results of the API call.
*
* #param {string} message Text to be placed in pre element.
*/
function appendPre(message) {
var pre = document.getElementById('content');
var textContent = document.createTextNode(message + '\n');
pre.appendChild(textContent);
}
/**
* Print files.
*/
function listFiles() {
gapi.client.drive.files.list({
'pageSize': 10,
'fields': "nextPageToken, files(id, name)"
}).then(function(response) {
appendPre('Files:');
var files = response.result.files;
if (files && files.length > 0) {
for (var i = 0; i < files.length; i++) {
var file = files[i];
appendPre(file.name + ' (' + file.id + ')');
}
} else {
appendPre('No files found.');
}
});
}
function listMajors() {
gapi.client.sheets.spreadsheets.values.get({
spreadsheetId: '1BxiMVs0XRA5nFMdKvBdBZjgmUUqptlbs74OgvE2upms',
range: 'Class Data!A2:E',
}).then(function(response) {
var range = response.result;
if (range.values.length > 0) {
appendPre('Name, Major:');
for (i = 0; i < range.values.length; i++) {
var row = range.values[i];
// Print columns A and E, which correspond to indices 0 and 4.
appendPre(row[0] + ', ' + row[4]);
}
} else {
appendPre('No data found.');
}
}, function(response) {
appendPre('Error: ' + response.result.error.message);
});
}
</script>
<script async defer src="https://apis.google.com/js/api.js"
onload="this.onload=function(){};handleClientLoad()"
onreadystatechange="if (this.readyState === 'complete') this.onload()">
</script>
</body>
</html>
Trying to rename all files in folder, nothing much, just want to add an prefix in all files, using Javascript. Getting error as: "Uncaught TypeError: gapi.client.drive.files.patch is not a function"
listFiles Function is able to fetch the file id and current name, but gapi.client.drive.files.patch throws above error.
Tried with gapi.client.drive.properties.patch but it also gave an error.!
Code:
<button id="authorize-button" style="display: none;">Authorize</button>
<button id="signout-button" style="display: none;">Sign Out</button>
<p id="list" style="display: none;">Enter Folder ID:
<input type="text" id="listInput" size="40" />
<button id="list-button" onClick="listFiles();">Get List</button></p>
<pre id="content"></pre>
<script type="text/javascript">
var CLIENT_ID = '';
var DISCOVERY_DOCS = ["https://www.googleapis.com/discovery/v1/apis/drive/v3/rest"];
var SCOPES = 'https://www.googleapis.com/auth/drive https://www.googleapis.com/auth/drive.appdata https://www.googleapis.com/auth/drive.apps.readonly https://www.googleapis.com/auth/drive.file https://www.googleapis.com/auth/drive.metadata https://www.googleapis.com/auth/drive.scripts';
var authorizeButton = document.getElementById('authorize-button');
var signoutButton = document.getElementById('signout-button');
var pre = document.getElementById('content');
var list = document.getElementById('list');
var listInput = document.getElementById('listInput');
var listButton = document.getElementById('list-button');
function handleClientLoad() {
gapi.load('client:auth2', initClient);
}
function initClient() {
gapi.client.init({
discoveryDocs: DISCOVERY_DOCS,
clientId: CLIENT_ID,
scope: SCOPES
}).then(function () {
// Listen for sign-in state changes.
gapi.auth2.getAuthInstance().isSignedIn.listen(updateSigninStatus);
// Handle the initial sign-in state.
updateSigninStatus(gapi.auth2.getAuthInstance().isSignedIn.get());
authorizeButton.onclick = handleAuthClick;
signoutButton.onclick = handleSignoutClick;
});
}
function updateSigninStatus(isSignedIn) {
if (isSignedIn) {
authorizeButton.style.display = 'none';
signoutButton.style.display = 'block';
list.style.display = 'block';
} else {
authorizeButton.style.display = 'block';
signoutButton.style.display = 'none';
list.style.display = 'none';
clearPre();
}
}
function handleAuthClick(event) {
gapi.auth2.getAuthInstance().signIn();
}
function handleSignoutClick(event) {
gapi.auth2.getAuthInstance().signOut();
}
function appendPre(message) {
var textContent = document.createTextNode(message + '\n');
pre.appendChild(textContent);
}
function clearPre() {
pre.innerHTML = "";
}
function listFiles() {
clearPre();
appendPre('Getting Files List......');
gapi.client.drive.files.list({
'q' : "'" + listInput.value + "' in parents",
'orderBy' : 'name',
'pageSize': 1000,
'fields': "nextPageToken, files(id, name, parents, mimeType)"
}).then(function(response) {
clearPre();
var files = response.result.files;
console.log(files);
if (files && files.length > 0) {
var currentFile;
var currentFileId;
appendPre('Count: ' + files.length + ' Files:');
for (var i = 0; i < files.length; i++) {
currentFile = files[i].name;
currentFileId = files[i].id;
appendPre(currentFile);
alert(currentFileId + ' Rename ' + currentFile);
*********Getting Error here*********
var request = gapi.client.drive.files.patch({
'fileId': currentFileId,
'resource': {'title': 'Rename ' + currentFile}
});
request.execute(function(resp) {
console.log('New Title: ' + resp.title);
});
}
} else {
appendPre('No files found.');
}
});
}
</script>
<script async defer src="https://apis.google.com/js/api.js" nload="this.onload=function(){};handleClientLoad()" onreadystatechange="if this.readyState === 'complete') this.onload()">
</script>
I can see in your code that you are using V3.
gapi.client.drive.files.patch is deprecated in the said version, you can use Files: update instead, to update the desired filenames.
Or other way around, you can switch to V2 and use the code provided in the documentation.
/**
* Rename a file.
*
* #param {String} fileId <span style="font-size: 13px; ">ID of the file to rename.</span><br> * #param {String} newTitle New title for the file.
*/
function renameFile(fileId, newTitle) {
var body = {'title': newTitle};
var request = gapi.client.drive.files.patch({
'fileId': fileId,
'resource': body
});
request.execute(function(resp) {
console.log('New Title: ' + resp.title);
});
}
Appreciate the original question was Javascript and V2 of the Google Drive API...
Trying to use Python and V3, it took me a while to work out how to do this. The bit I was missing was the body={} keyword argument that you need to submit the name property.
Assuming you've already gotten the file_id you want to rename in a separate call, like this:
drive.files().update(
fileId=file_id,
supportsAllDrives='true',
body={'name': 'new name for this file'}
).execute()
After 3 attempts to use other folks NPM modules for Google Drive, I decided it was time to do my own and I was JUST adding mv() functionality so I had this fight and here's what I came up with and use in my library. It isn't public today and will change names, but if anyone wants to try a beta version, hit me up on twitter by this same name.
note:
You only need addParents and removeParents if you're "moving" a file and you only need name if you're actually going to rename it.
drive.files.update({
fileId: driveFileId,
addParents: commaStringOfParents,
removeParents: commaStringOfParents,
resource: { name: newFileName }
}, (err, res) => {
if (err) handleError(err);
let files = res.data
// Do stuff here
}
Right now I have the google classroom API working fine to get the name and section for each course that I have. I want to get the homework in a list for each course. How can I do this?
I currently have:
// Your Client ID can be retrieved from your project in the Google
// Developer Console, https://console.developers.google.com
var CLIENT_ID = '<CLIENTID>';
var SCOPES = ["https://www.googleapis.com/auth/classroom.courses.readonly"];
/**
* Check if current user has authorized this application.
*/
function checkAuth() {
gapi.auth.authorize(
{
'client_id': CLIENT_ID,
'scope': SCOPES.join(' '),
'immediate': true
}, handleAuthResult);
}
/**
* Handle response from authorization server.
*
* #param {Object} authResult Authorization result.
*/
function handleAuthResult(authResult) {
var authorizeDiv = document.getElementById('authorize-div');
if (authResult && !authResult.error) {
// Hide auth UI, then load client library.
authorizeDiv.style.display = 'none';
loadClassroomApi();
} else {
// Show auth UI, allowing the user to initiate authorization by
// clicking authorize button.
authorizeDiv.style.display = 'inline';
}
}
/**
* Initiate auth flow in response to user clicking authorize button.
*
* #param {Event} event Button click event.
*/
function handleAuthClick(event) {
gapi.auth.authorize(
{client_id: CLIENT_ID, scope: SCOPES, immediate: false},
handleAuthResult);
return false;
}
/**
* Load Classroom API client library.
*/
function loadClassroomApi() {
gapi.client.load('classroom', 'v1', listCourses);
}
/**
* Print the names of the first 10 courses the user has access to. If
* no courses are found an appropriate message is printed.
*/
function listCourses() {
var request = gapi.client.classroom.courses.list({
pageSize: 10
});
request.execute(function(resp) {
var courses = resp.courses;
if (courses.length > 0) {
for (i = 0; i < courses.length; i++) {
var course = courses[i];
var div = document.createElement('div');
div.className = 'class="col-md-4"';
div.innerHTML = '<div class="col-md-4"> \
<div class="jumbotron"> \
<h2>' + course.name + '</h2> \
<p>' + course.section + '</p> \
</div> \
</div> \
</div>';
document.getElementById('output').appendChild(div);
}
} else {
appendPre('No courses found.');
}
});
}
/**
* Append a pre element to the body containing the given message
* as its text node.
*
* #param {string} message Text to be placed in pre element.
*/
function appendPre(message) {
var pre = document.getElementById('output');
var textContent = document.createTextNode(message + '\n');
pre.appendChild(textContent);
}
I can't confirm if the Javascript client of Google API already has the Classroom API functionalities (since its still in Beta), but you can try to call out
gapi.client.[classroom/classroom.courses].courseWork.list({..parameters..},function(){...callback...});
Or, call the REST API directly in Javascript, without using the JS client.
I am new to API's and I am trying to make an application to practice. I am trying to format the data coming from an event request to my google calendar. It is currently coming back in ISO format, but I would like it to be in a more basic date format (preferably just the time range of the event).
Here is the function:
function listUpcomingEvents() {
var request = gapi.client.calendar.events.list({
'calendarId': 'primary',
'timeMin': (new Date()).toISOString(),
'showDeleted': false,
'singleEvents': true,
'maxResults': 10,
'orderBy': 'startTime'
});
When I try to alter the toISOString method to a toDateSring(), the information does not display at all.
Here is the full code:
<html>
<head>
<script type="text/javascript">
// Your Client ID can be retrieved from your project in the Google
// Developer Console, https://console.developers.google.com
var CLIENT_ID = 'INSERT_YOUR_CLIENT_ID';
var SCOPES = ["https://www.googleapis.com/auth/calendar.readonly"];
/**
* Check if current user has authorized this application.
*/
function checkAuth() {
gapi.auth.authorize(
{
'client_id': CLIENT_ID,
'scope': SCOPES.join(' '),
'immediate': true
}, handleAuthResult);
}
/**
* Handle response from authorization server.
*
* #param {Object} authResult Authorization result.
*/
function handleAuthResult(authResult) {
var authorizeDiv = document.getElementById('authorize-div');
if (authResult && !authResult.error) {
// Hide auth UI, then load client library.
authorizeDiv.style.display = 'none';
loadCalendarApi();
} else {
// Show auth UI, allowing the user to initiate authorization by
// clicking authorize button.
authorizeDiv.style.display = 'inline';
}
}
/**
* Initiate auth flow in response to user clicking authorize button.
*
* #param {Event} event Button click event.
*/
function handleAuthClick(event) {
gapi.auth.authorize(
{client_id: CLIENT_ID, scope: SCOPES, immediate: false},
handleAuthResult);
return false;
}
/**
* Load Google Calendar client library. List upcoming events
* once client library is loaded.
*/
function loadCalendarApi() {
gapi.client.load('calendar', 'v3', listUpcomingEvents);
}
/**
* Print the summary and start datetime/date of the next ten events in
* the authorized user's calendar. If no events are found an
* appropriate message is printed.
*/
function listUpcomingEvents() {
var request = gapi.client.calendar.events.list({
'calendarId': 'primary',
'timeMin': (new Date()).toISOString(),
'showDeleted': false,
'singleEvents': true,
'maxResults': 10,
'orderBy': 'startTime'
});
request.execute(function(resp) {
var events = resp.items;
appendPre('Upcoming events:');
if (events.length > 0) {
for (i = 0; i < events.length; i++) {
var event = events[i];
var when = event.start.dateTime;
if (!when) {
when = event.start.date;
}
appendPre(event.summary + ' (' + when + ')')
}
} else {
appendPre('No upcoming events found.');
}
});
}
/**
* Append a pre element to the body containing the given message
* as its text node.
*
* #param {string} message Text to be placed in pre element.
*/
function appendPre(message) {
var pre = document.getElementById('output');
var textContent = document.createTextNode(message + '\n');
pre.appendChild(textContent);
}
</script>
<script src="https://apis.google.com/js/client.js?onload=checkAuth">
</script>
</head>
<body>
<div id="authorize-div" style="display: none">
<span>Authorize access to Google Calendar API</span>
<!--Button for the user to click to initiate auth sequence -->
<button id="authorize-button" onclick="handleAuthClick(event)">
Authorize
</button>
</div>
<pre id="output"></pre>
</body>
</html>
Should I perhaps format the data after the request?
The code below is working at loading a PDF file (created with jsPDF) into my Google Drive folder. It is essentially Google Drive the Quickstart code modified.
The PDF generated looks OK when viewed inside the browser that is opened with "docMenu.output('dataurlnewwindow');"
The PDF file appears OK in my Google Drive folder, but when I go to view it I get a grey screen with "Failed to load PDF document". I have no execution errors in console / inspect.
What have I missed? Have I messed up by pulling the Blob (data URI) and feeding it to Google Drive upload?
Many thanks!
<script type="text/javascript">
var CLIENT_ID = 'my-client-id';
var SCOPES = 'https://www.googleapis.com/auth/drive';
var FOLDER_ID = 'my-folder-id';
/**
* Called when the client library is loaded to start the auth flow.
*/
function handleClientLoad() {
window.setTimeout(checkAuth, 1);
}
/**
* Check if the current user has authorized the application.
*/
function checkAuth() {
gapi.auth.authorize(
{'client_id': CLIENT_ID, 'scope': SCOPES, 'immediate': true},
handleAuthResult);
}
/**
* Called when authorization server replies.
* #param {Object} authResult Authorization result.
*/
function handleAuthResult(authResult) {
if (authResult && !authResult.error) {
// Access token has been successfully retrieved, requests can be sent to the API.
var docMenu = new jsPDF('p', 'cm', 'a5'); <-- Create PDF document
docMenu.text(2, 1, "Testing"); <-- Add text here...
docMenu.text(2, 5, "Testing");
docMenu.text(2, 10, "Testing");
docMenu.text(2, 15, "Testing");
docMenu.text(2, 20, "Please order and pay at the counter.");
docMenu.output('dataurlnewwindow'); <-- Displays PDF perfectly
var MyBlob = docMenu.output('blob'); <-- get PDF Blob
MyBlob.name = "test.pdf"; <-- Give it a file name
insertFile(MyBlob); <-- send it to Google Drive upload routine
} else {
alert("FAILED AUTHORIZING");
}
}
/**
* Start the file upload.
* #param {Object} evt Arguments from the file selector.
*/
function uploadFile(evt) {
gapi.client.load('drive', 'v2', function() {
var file = evt.target.files[0];
insertFile(file);
});
}
/**
* Insert new file.
* #param {File} fileData File object to read data from.
* #param {Function} callback Function to call when the request is complete.
*/
function insertFile(fileData, callback) {
const boundary = '-------314159265358979323846';
const delimiter = "\r\n--" + boundary + "\r\n";
const close_delim = "\r\n--" + boundary + "--";
var reader = new FileReader();
reader.readAsBinaryString(fileData);
reader.onload = function(e) {
var contentType = fileData.type || 'application/octet-stream';
var metadata = {
'title': fileData.name,
'mimeType': contentType,
'parents': [{"id":FOLDER_ID}]
};
var base64Data = btoa(reader.result);
var multipartRequestBody =
delimiter +
'Content-Type: application/json\r\n\r\n' +
JSON.stringify(metadata) +
delimiter +
'Content-Type: ' + contentType + '\r\n' +
'Content-Transfer-Encoding: base64\r\n' +
'\r\n' +
base64Data +
close_delim;
var request = gapi.client.request({
'path': '/upload/drive/v2/files/',
'method': 'POST',
'params': {'uploadType': 'multipart'},
'headers': {
'Content-Type': 'multipart/mixed; boundary="' + boundary + '"'
},
'body': multipartRequestBody});
if (!callback) {
callback = function(file) {
console.log(file)
};
}
request.execute(callback);
}
}
</script>
Do you think you need to change the file's permissions in Google Drive when it is created so that "anyone with a link" can view it or make it public?
Could it be the file is corrupt and Google Drive can't read it, but the docMenu.output method somehow isn't affected by the corruption? I have had something similar happen before.
I don't really have any experience with creating PDFs, but I hope my suggestion may at least point you in the right direction if it's correct.
For those who it may help, the above code works perfectly for me in creating and uploading PDF files to Google Drive using jsPDF.
The issue I was facing was one of Drive not liking this PDF for some reason (as it is reported with other PDFs in forums).
The file downloads OK and opens perfectly in Acrobat, Foxit and others... the problem is with Google.