I have found an extremely good google script for a google form that allows me to retrieve the answers of a google form in a spreadsheet along with the "getEditResponseUrl()" that will help me build a database that can be modified through the google form.
However, I am struggling in getting the url of an "upload file question". The question where the user is supposed to upload a file is the fourth one "facture".
The answer I get in my spreadsheet is only "[Ljava.lang.Object;#508c8b8b" but not the file.
Any idea how to make this work so that I get the url of the file that was uploaded by the user ?
Thank you and Kind regards
var ss = SpreadsheetApp.openById("spreadsheeturl"); // to be customised
var responseSheet = "Database"; // to be customised
function submitFormFunc(e) {
var items = e.response.getItemResponses();
var responses={};
for(var i = 0; i< items.length; i++) {
responses[items[i].getItem().getTitle()]=items[i].getResponse();
}
var responseRow = [];
responseRow.push(e.response.getTimestamp().toString());
responseRow.push(e.response.getId());
responseRow.push(responses["Challenge"]); // to be customised
responseRow.push(responses["Client"]);
responseRow.push(responses["Date"]);
responseRow.push(responses["Facture"]);
// to be customised
// add as many as needed
responseRow.push(FormApp.getActiveForm().getResponse(e.response.getId()).getEditResponseUrl());
var isNewItem = alreadyExist(ss,e.response.getId());
if(isNewItem<0){
ss.getSheetByName(responseSheet).appendRow(responseRow);
}
else{
ss.getSheetByName(responseSheet).getRange(isNewItem+2, 1, 1, 6).setValues([responseRow]);
}
}
function alreadyExist(ss,id){
var ids = ss.getSheetByName(responseSheet).getRange("B2:B").getValues();
for(var i=0; i< ids.length; i++){
if(ids[i][0]===id){
return(i);
}
}
return(-1);
}
Here's a snippet from the Form Notifications add-on that converts the uploaded file ids into Google Drive URLs and concatenates the result in case of multiple uploads.
var urls = answer.toString().split(",").map(function(f) {
return "https://drive.google.com/open?id=" + f;
}).join(", ");
Related
need your help again..
so I have many student. and every week we have exam.
so I want to make individual Graphic of their progress for every week.. and send it ass attachment with autocrat to their email.
my problem is
how do I make an individual graphic continuedly (i mean not one by one change the name)
how to save that individual graphic to google drive
how to get the link image on google drive
those 3 problem is to make report for my student one by one like this pic
please share idea with me.. I'm really thank you for helping me here..
here the spreadsheet link : https://docs.google.com/spreadsheets/d/1fmS7PM65CMGGe5g00ojqqiK2CFr5HFgo_6L_Qki7QLw/edit#gid=1364826426
I can't understand and solve your problem all, since your problem seems a bit too complex.
However, I know how to save a sheet as a PDF easier and get the PDF's URL automatically.
It needs a script program.
I made a sample program based on another answer.
This is my code.
function exportPDF(){
// get parameters
var sheet = SpreadsheetApp.getActiveSheet();
var sheetName = sheet.getRange("B2").getValue();
var fileName = sheet.getRange("B3").getValue();
sheet.getRange("B4").setValue("");
// export the sheet
var fileUrl = exportSheet(sheetName, fileName);
// show the url
sheet.getRange("B4").setValue(fileUrl);
}
// based on https://stackoverflow.com/questions/38335143/export-single-sheet-to-pdf-in-apps-script
function exportSheet(sheetName, fileName) {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheets = ss.getSheets();
var fileUrl = "";
try{
for (var i = 0; i < sheets.length; i++) {
if (sheets[i].getSheetName() !== sheetName) {
sheets[i].hideSheet()
}
}
var file = DriveApp.createFile(ss.getBlob());
file.setName(fileName);
file.setSharing(DriveApp.Access.ANYONE, DriveApp.Permission.VIEW);
fileUrl = file.getUrl();
}
catch(e){
console.log(e);
throw e;
}
finally{
for (var i = 0; i < sheets.length; i++) {
sheets[i].showSheet()
}
}
return fileUrl;
}
If this can help, check this sample sheet and make a copy. ([File]-[Make a copy])
https://docs.google.com/spreadsheets/d/1lCxNSaXsd9tno4xdog6Usa0l1SZeuXrc62Oi6TK-VsY/edit?usp=sharing
I have created three charts in the spreadsheet for you.
Save or publish your chart
I want to get speaker notes from Google Slides by API, but I could not find any fields for speaker notes.
For reference: Method: presentations.pages.get
What would be a good way to do this?
Support for speaker notes is now available in the Slides API v1. Documentation is here: https://developers.google.com/slides/how-tos/notes
In the absence of the API, I wouldn't suggest this is a good way of doing it. In fact it is horrible. But here it is. If you absolutely had to do it. It is likely a bit flakey too.
Steps are:
Export the presentation, via the Drive API, as a PowerPoint .pptx file
Unpack the file - it is a zip file containing a directory structure with XML files in.
Identify the speaker notes files and process them as per your requirement (e.g. extract all text, or work on the XML etc).
Ugly right? Here's an example in Apps Script:
Enable Drive API in Advanced Services within your script (Resources > Advanced Google Services).
function example() {
// Print out the speaker notes
Logger.log(getNotes('123abc......asd'));
}
// Returns an array of strings, one string per slide
// representing the speaker notes.
function getNotes(presentationId) {
//DriveApp.createFile();
var notesRegex = /ppt\/notesSlides\/notesSlide\d+\.xml/;
var url = 'https://www.googleapis.com/drive/v2/files/' + presentationId +
'/export?mimeType=application%2Fvnd.openxmlformats-officedocument.presentationml.presentation';
var options = {
headers: {
Authorization : 'Bearer ' + ScriptApp.getOAuthToken()
}
};
var response = UrlFetchApp.fetch(url, options);
var zipBlob = Utilities.newBlob(response.getContent(), 'application/zip');
var data = Utilities.unzip(zipBlob);
var notes = [];
for (var i = 0; i < data.length; i++) {
if (notesRegex.test(data[i].getName())) {
// Example simply extracts text from speaker notes
// You could do something more complex.
notes.push(extractTextFromXml(data[i].getDataAsString()));
}
}
return notes;
}
function extractTextFromXml(xml) {
var doc = XmlService.parse(xml);
var root = doc.getRootElement();
var ns = root.getNamespace('a');
var text = [];
function walkNode(node) {
if (node.getText()) {
text.push(node.getText());
}
var children = node.getChildren();
if (children.length) {
children.forEach(function(child) {
walkNode(child);
});
}
}
walkNode(root);
return text.join('\n');
}
I m trying to use get and list method with google plus comment. In official site it said (All API calls require either an OAuth 2.0 token or an API key. ) and I have tried send GET request without the step of OAuth it works it returns json format data. My question is OAuth must require before using google+ API?
It depends on exactly what data you're trying to get.
https://developers.google.com/+/api/oauth documents the benefits of using OAuth, but in general, if you want to get private profile data, or if you wish to use the /me/ URL shortcut, you will need to use OAuth and may, if you wish, use an App Key in addition. If all you're interested in is public data, you can use the App Key.
The short answer to whether you can do it is that you can get comments from Google+ without OAuth.
As for the how would you do this, I'm not sure which language you're doing this in but the following code shows how this is done in JavaScript.
The API calls used here can be experimented with in the API explorer:
Listing Activities
Listing Comments
A demo of this code is here.
You will need an API key (the simple key) for a project with the Google+ APIs from the Google APIs console. When you set up the project, you will only need to enable the Google+ API from the services section.
First, grab the activities using the public data API:
// Gets the activities for a profile
function getActivities(profileID){
var activities = null;
var URL = "https://www.googleapis.com/plus/v1/people/" + profileID + "/activities/public?alt=json&key=" + key;
var request = new XMLHttpRequest();
request.open('GET', URL, false);
request.send(); // because of "false" above, will block until the request is done
// and status is available. Not recommended, however it works for simple cases.
if (request.status === 200) {
if (debug) console.log("retrieved activities \n\n");
var activities = jQuery.parseJSON(request.responseText).items;
console.log("Discovered " + activities.length + " activities");
}else{
handleRequestIssue(request);
}
return activities;
}
The following code loops through the activities
for (var i=0; i < activities.length; i++) {
console.log("trying to do something with an activity: " + i);
var activity = activities[i];
console.log(activity.id);
}
Next, you can use the activity IDs to retrieve the comments per activity:
function getCommentsForActivity(activityID){
var comments = "";
var URL = "https://www.googleapis.com/plus/v1/activities/" + activityID + "/comments?alt=json&key=" + key;
var request = new XMLHttpRequest();
request.open('GET', URL, false);
request.send(); // because of "false" above, will block until the request is done
// and status is available. Not recommended, however it works for simple cases.
if (request.status === 200) {
if (debug) console.log(request.responseText);
var comments = jQuery.parseJSON(request.responseText).items;
if (debug){
for (comment in comments){
console.log(comment);
}
}
}else{
handleRequestIssue(request);
}
return comments;
}
function manualTrigger(){
var activities = getActivities("109716647623830091721");
}
The following code brings it all together and retrieves activities and comments for a specific post:
$(document).ready(function () {
var renderMe = "";
var activities = getActivities("109716647623830091721");
console.log("activities retrieved: " + activities.length);
for (var i=0; i < activities.length; i++) {
console.log("trying to do something with an activity: " + i);
var activity = activities[i];
renderMe += "<br/><div class=\"article\"><p>" + activity.title + "</p>";
console.log(activity.id);
// get comments
var comments = getCommentsForActivity(activity.id);
for (var j=0; j<comments.length; j++){
renderMe += "<br/><div class=\"comment\">" + comments[j].object.content + "</div>";
}
renderMe += "</div>";
}
console.log("I'm done");
document.getElementById("ac").innerHTML = renderMe;
});
i`m trying use Twitter Stream Api for searching some hashtags in Google Spreadsheet. Twitter search api useless cause i wanna trak retweet count too. My function sample here. Can anybody explain me what i must do for working well..
function miniSearch(){
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sumSheet = ss.getSheetByName("Readme/Settings");
// Authorize to Twitter
var oauthConfig = UrlFetchApp.addOAuthService("twitter");
oauthConfig.setAccessTokenUrl("https://api.twitter.com/oauth/access_token");
oauthConfig.setRequestTokenUrl("https://api.twitter.com/oauth/request_token");
oauthConfig.setAuthorizationUrl("https://api.twitter.com/oauth/authorize");
oauthConfig.setConsumerKey(TWITTER_CONSUMER_KEY);
oauthConfig.setConsumerSecret(TWITTER_CONSUMER_SECRET);
// "twitter" value must match the argument to "addOAuthService" above.
var options = {
'method': 'POST',
"oAuthServiceName" : "twitter",
"oAuthUseToken" : "always"
};
var url = "https://stream.twitter.com/1/statuses/filter.json?track="+"twitterapi";
var response = UrlFetchApp.fetch(url, options);
var tweets = JSON.parse(response.getContentText());
sumSheet.getRange('B8').setValue(tweets[0]["text"]);
}
this function return error code 504;
I don't think Google Apps Script can keep a persistent HTTP connection open which is resulting in the 504 (See Twitter Streaming APIs Doc)
[I've a basic retweet counter in this Google Spreadsheet Template (TAGS v4.0). The filterUnique formula uses this code (the pseudocode is strip out any links from tweet text then extract 1st 90% of text (to take account of any old style RT+ annotation), then if not in unique array add or add 1 to existing value):
function filterUnique(tweets){
var output = [];
var temp = {};
for (i in tweets){
if (i>0){
var tmp = tweets[i][0];
var urlPattern = /(\b(https?|ftp|file):\/\/[-A-Z0-9+&##\/%?=~_|!:,.;]*[-A-Z0-9+&##\/%=~_|])/ig;
tmp = tmp.replace(urlPattern,"")
tmp = tmp.substring(0,parseInt(tmp.length*0.9));
if (temp[tmp] == undefined){
temp[tmp] = [tweets[i][0],0];
}
temp[tmp] = [tweets[i][0],temp[tmp][1]+1];
}
}
for (i in temp){
output.push([temp[i][0],temp[i][1]]);
}
output.sort(function(a,b) {
return b[1]-a[1];
});
return output.slice(0, 12);
}
]
i'm using a Rails backend with my App and getting a AsyncToken returned from it (a DB-Call to be specific)
As far as i know the AsyncToken returns a result event when done loading all data from the request, this way its possible to make sure all data was loaded before executing some function which uses the data.
i tried the following implementation to get the AsyncToken converted into an Array and plotting its objects as strings to the user:
var dataSrv:services.databaseservice.DatabaseService = new services.databaseservice.DatabaseService;
dataSrv.addEventListener(ResultEvent.RESULT, dbListener);
//DBOPERATION returns my AsyncToken
var listData:AsyncToken = dataSrv.DBOPERATION;
var responder:AsyncResponder = new AsyncResponder( resultHandler, faultHandler );
listData.addResponder(responder);
public function resultHandler(event:ResultEvent, token:Object=null):void{
var output: Array = (event.result as Array);
for (var i:int = 0; i<output.length; i++){
Alert.show( output[i].toString() );
}
}
public function faultHandler(event:FaultEvent, token:Object=null):void{
Alert.show( "FAULT: " + event.fault.message );
}
But i keep getting a "null object-pointer" error!
Ok here how it works:
var output:ArrayCollection = (event.result as ArrayCollection);
for (var i:int = 0; i<output.length; i++)
{
// where VARIABLE is the name of the transmitted data-variable
Alert.show(output[i].VARIABLE);
}
hope this helps others. Thx for Help Guys, stackoverflow is just awesome!
You could add a breakpoint on the following line
var output: Array = (event.result as Array);
Then go to the Flash Debug perspective, in the "Variables" pane you should be able to access the properties of the event and see the content of the result property.
If the result property is null, you may want to double check what is returned from Rails