getting Exception: Invalid ID error, when using getFileById - google-apps-script

I am trying to use a script from a tutorial online that will put URLs in a google forms response sheet so I can go back and edit responses after they have been submitted.
The script comes from this guy https://www.youtube.com/watch?v=nqOE_FIMd_w
and his instructions are here: https://docs.google.com/document/d/1m9V_AHZdA24pUAR1xGxQNt_y3k7J9RKoSG5v_9oFvcU/edit
here is the script from the tutorial:
function assignEditUrls() {
var form = FormApp.openById('Your form ke goes here');
var sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName('Your responses Google Sheet name goes here - The tab name, not the file name');
var data = sheet.getDataRange().getValues();
var urlCol = Column number where URLs get entered goes here;
var responses = form.getResponses();
var timestamps = [], urls = [], resultUrls = [];
for (var i = 0; i < responses.length; i++) {
timestamps.push(responses[i].getTimestamp().setMilliseconds(0));
urls.push(responses[i].getEditResponseUrl());
}
for (var j = 1; j < data.length; j++) {
resultUrls.push([data[j][0]?urls[timestamps.indexOf(data[j][0].setMilliseconds(0))]:'']);
}
sheet.getRange(2, urlCol, resultUrls.length).setValues(resultUrls);
}
It seems all simple enough, but the script keeps giving me an error:
Invalid ID (line 2, file "getEditLinks")
Seems to be a problem with the document key.
I have already given the script permission and I have concentrated my attemtps to resolve this by grabbing different parts of this URL for the file. (I remember that Google used to need the whole URL at some point in the past)
Mine is
*https://docs.google.com/spreadsheets/d/1pKmad.....VtT3GaM/edit#gid=1905774080*
(where ..... is more of the doc key. I am not putting the whole lot for security reasons)
According to the tutorial, and all other research into this, it seems this part is the correct part from the URL to use.
1pKmad.....VtT3GaM
But this is what bring the error.
I tried the whole URL, the URL just up to the doc key part, and a few other subsets of this, but none work.
Can anyone see what I am doing wrong here?

Issue:
Based on your description you are trying to access a spreadsheet file by its id but you are using FormApp.
Instead you should be using SpreadsheetApp instead:
var form = SpreadsheetApp.openById('1pKmad.....VtT3GaM'); // form is now a spreadsheet object
but the new issue now is that the variable is not form anymore but a spreadsheet object and as a result you will get other errors down the road when calling form.getResponses().
Solution:
You need to use your existing script and put the id of the form instead of the spreadsheet, which can be found on the form url:
var form = FormApp.openById('Form ID here not Spreadsheet ID');
Note:
The form url looks like this:
https://docs.google.com/forms/d/formID/edit
and you can find the form that is attached to the spreadsheet file by the spreadsheet file menu:

Related

How to find Google Form ID

Update! The Form ID is in the web address.
Someone kindly pointed out to me (outside of Stack Overflow) that the Form ID which identifies the form can be found in the web address. Example:
https://docs.google.com/forms/d/1y9XMjvZi_wlFC2FN64cdafIyGuM_7UOsn1Q61PXv5MQ/edit
Where the bolded text is the Form ID.
Original:
Apologies in advance, as I am not an experienced script writer and may use improper jargon.
But - I found the response to this question when googling about how to find the Form ID element in a Google Form, but the answer is old and my problem is similar. I have tried searching the "Inspect Element" data and still cannot identify the ID attribute. I've tried searching the code for:
data-item-id="##########", or
aria-describedby="i.desc.########## i3"
for="entry_XXXXXXX"
Still no luck. Does anyone have an updated suggestion for finding the Form ID? For reference, I am using the script below as my starting point. This is taken from a different/old form, but is similar in functionality so I was hoping to leverage it. I am trying to find my Form's ID (such as that as in line 6-7).
/**
* #NotOnlyCurrentDoc
* Limit OAuth scope to only current spreadsheet rather than all sheets in drive
*/
function onSubmit(e) {
var form = FormApp.openById('1eccBQ7Bs34Z54keGHeR8HDXmiP1UqxMi9vSDWNv6zgs');
var sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName('Master');
var data = sheet.getDataRange().getValues();
//var urlCol = 26;
var responses = form.getResponses();
var timestamps = [], urls = [], resultUrls = [];
for (var i = 0; i < responses.length; i++) {
timestamps.push(responses[i].getTimestamp().setMilliseconds(0));
urls.push(responses[i].getEditResponseUrl());
}
for (var j = 1; j < data.length; j++) {
resultUrls.push([data[j][0]?urls[timestamps.indexOf(data[j][0].setMilliseconds(0))]:'']);
}
sheet.getRange(2, urlCol = 27, resultUrls.length).setValues(resultUrls);
return resultUrls;
};
As the OP mentioned in the question body, the Form ID could be found in the Google Form URL, but hte OP missed to mention that this URL is the edit URL, not the "view" URL.
The form owner also could find the form ID by using the web-browser developer tools by searching for data-redirect-url which has assigned the Form URL:
data-redirect-url="https://docs.google.com/forms/d/form_id/edit?usp=redirect_edit_m2"
As mentioned by the OP the Form ID is between https://docs.google.com/forms/d/and /edit.
Besides looking at the Form URL, the form ID could be retrieved by using Google Apps Script. The easier way is to use a bounded script similar to this:
function getActiveFormID(){
const id = FormApp.getActiveForm().getId();
console.log(id);
}
Another way is by using the Drive Service. The following example assumes that there is only one file named "My Form":
function getFormId(){
const id = DriveApp.searchFiles(`title contains "My Form"`).next().getId();
console.log(id);
}
From Google Chrome, open the form (view mode, not edit).
Hit F12.
In the Elements window pain,
expand <body>
expand <script type = "text/javascript" nonce> == $0
You should see:
var FB_PUBLIC_LOAD_DATA with each element you created on their form and their respective Element ID.

Google form file uploads: getting filenames

Other users posted similar questions here and here. I tried to replicate the answer but received it as undefined. My users are permitted to upload up to 5 files, I would like to append the filenames as responses in (up to) 5 columns in a spreadsheet.
I presume that I would be able to get the filenames once I have the URLs using the following example.
function driveFile(){
//e.values[1] is apparently the file URL
var url = "https://drive.google.com/open?id=1bVbNAnES33oY4gx8npdp51ZSMekQalk"
var id = url.split("=")[1];
var file = DriveApp.getFileById(id);
var fileName = file.getName();
}
I tried this as suggested in the other question and it returned undefined.
I also tried using 0 as it made sense to get the URLs of the different files as 0 to 4.
var file = e.values[1]
I also tried the example from the other question but to no avail. I'm also not sure if it would return the URLs concatenated or in an array.
var fileBlob = e.parameter.thefile;
I would appreciate any guidance in this topic. Get URL → Filenames for (up to) 5 files submitted via Google Forms.
Answer:
This can be done using an onSubmit() trigger attached to the Google Form.
Further information:
The problem you are encountering is that values is not a parameter of the event object obtained on form submission - this is why you are getting an undefined return.
Form responses are a little more complicated than this - they are objects with predefined methods and in order to obtain the information out of them you need to use the methods provided in the Apps Script Documentation for Forms.
Code:
function onSubmit(e) {
// Assumiung the question which asks for the file upload is question 1
// Change this to the correct question number:
var uploadQuestionNumber = 1;
var formResponses = e.response.getItemResponses();
var names = [];
var fileUploads = formResponses[uploadQuestionNumber - 1];
for (i = 0; i < fileuploads.getResponse().length; i++) {
name.push(DriveApp.getFileById(fileUploads.getResponse()[i]));
}
return name;
}
Variable name will return an array of all the file names of the uploaded files. You can then use this to put into a Sheet using SpreadsheetApp.
References:
Google Forms events - Form submit
Class FormResponse
Class ItemResponse
Class DriveApp
getFileById(id) method
Class File

Recurring generic error message Google Apps Script

EDIT: Not sure if this matters but I am using G Suite for Nonprofits.END EDIT:::
I keep getting this error message upon attempting to manually run this script for the first time:
We're sorry, a server error occurred. Please wait a bit and try again. (line 2, file "Code")).
I have saved it and authorized its permissions already. I am simply trying to execute the script to get all of the existing responses' edit URLs.
There are no triggers associated with this. The script is intended to get the edit response URLs from a Google Form. "Edit after submit" is enabled in the Form, and it is set to public in regards to who can complete the form (not that this should matter since I am the owner of the form).
I use this script in this exact form on many other projects with no issues at all. I have also tried a different script for this task that I know works, with the same error message returned. The error message always references the line of code with the form ID/URL. I have verified the form ID. Thanks for your help.
function assignEditUrls() {
var form = FormApp.openById('some id');
var sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName('Form Responses 1');
var data = sheet.getDataRange().getValues();
var urlCol = 6;
var responses = form.getResponses();
var timestamps = [], urls = [], resultUrls = [];
for (var i = 0; i < responses.length; i++) {
timestamps.push(responses[i].getTimestamp().setMilliseconds(0));
urls.push(responses[i].getEditResponseUrl());
}
for (var j = 1; j < data.length; j++) {
resultUrls.push([data[j][0] ?
urls[timestamps.indexOf(data[j][0].setMilliseconds(0))] : ''
]);
}
sheet.getRange(2, urlCol, resultUrls.length).setValues(resultUrls);
}
Thanks to Rubén, I was able to solve my problem. In my script I was using the incorrect Form ID. When running a script to obtain the edit response URLs from a Google Form you must view the edit form URL in the editing mode of your specific form. Extract the Form ID from this edit URL NOT the view URL or share URL etc. This is the only way your script will access the correct form with the correct permissions. Thanks again to Rubén and all others who assisted.

When using the FormResponse class, a unexpected Id is returned for a response depending on how the response is retrieved

I'm hoping someone has seen this before, I'm using Google Forms, and on submission, using Google Apps Script to store the response id in a separate Spreadsheet in order to store further meta data in the future (Id gained from the method in the onSubmit event response e.response.getId()). Upon the first submission of a Google Form, I logged the response ID in a new sheet.
I can load the response through form.getResponse(responseIdStoredInSheet), however, when I loop through the responses returned by form.getResponses() and call .getId() on those FormResponses returned, the Id is slightly altered at the end. I've searched for an afternoon around the docs and online as to why this happens, but to no avail.
function testResponseIds()
{
var responseIdStoredInSheet = 'ChMxNzM4MDQzNzQ5MjQyNDc0Njg4EAA';
//only response in the form
var formResponse = form.getResponse(responseIdStoredInSheet);
//outputs as expected above - ChMxNzM4MDQzNzQ5MjQyNDc0Njg4EAA
Logger.log(formResponse.getId());
//loop through all responses (only above response is present)
var formResponses = form.getResponses();
for (var i = 0; i < formResponses.length; i++)
{
//Outputs slightly different Id - ChMxNzM4MDQzNzQ5MjQyNDc0Njg4EJ2kvMHLzsOvdg
Logger.log(formResponses[i].getId());
}
}
Logged output from above:
[14-03-03 17:12:51:259 GMT] ChMxNzM4MDQzNzQ5MjQyNDc0Njg4EAA
[14-03-03 17:12:51:279 GMT] ChMxNzM4MDQzNzQ5MjQyNDc0Njg4EJ2kvMHLzsOvdg
I tested your code on one of my form and it look to be working as intented. My supposition is that you deleted the answer you are trying to retrieve but you can still get it through the script(I don't know the reason, the cache I suppose).
What I can propose you is to retrieve the edit URL so you will see that it's not the same answer (modifying it and checking the form answers).
Logger.log(formResponses[i].getEditResponseUrl());
By the way in your posted script you forgot:
var form = FormApp.getActiveForm();
or the equivalent (couldn't run your script without adding that line)

How to generate a pre-filled form URL for Google Form

I'm looking for a programmatic way to automate the generation of pre-filled URLs for google forms.
In a recent update, Google introduced a new Forms product to Google Docs. If you open the tools menu in a spreadsheet, you'll see some new options.
In the new Form Responses menu, one option is "Get pre-filled URL". This opens up a dialog containing a version of your form that you can fill out, and when you submit it, you receive a URL that can be used to open a Live Form with the data you pre-filled ready and waiting for you. The URL looks something like this...
https://docs.google.com/forms/d/--Form-ID--/viewform?entry.1094330118=Something&entry.1471717973=stack#example.com&entry.540962741&entry.787941281&entry.1873343651
The questions from the form have a fixed identity, e.g. entry.1094330118. They may be pre-filled with a value (entry.1094330118=Something) or blank (entry.7879412).
In apps-script, I'd like to generate these pre-filled URLs for users of my form, so I can provide them for updates. My users are not members of an Apps Domain, so I don't have the option of embedding an Edit your response link.
If I can get the information about the form, I will be able to piece together the URL. While I can go through the UI to create one URL, and dissect it to get the info for that form, I want a solution that will work with arbitrary forms.
How can I programmatically determine the question IDs?
With the new
Forms product, is the form available to me through any apps-script
APIs? (I know about getFormURL() - that's not what I mean.)
Armed with a question ID, can I get more information about the question? (Question text, type, etc.)
I required something similar for users to go and edit their response, take a look here: http://productforums.google.com/forum/#!topic/docs/LSKKCR3VHC8
Copy / paste code below:
function assignEditUrls() {
var form = FormApp.openById('1MonO-uooYhARHsr0xxxxxxxxxxxxxxxxxxxxx');
//enter form ID here
var sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName('Form Responses');
//Change the sheet name as appropriate
var data = sheet.getDataRange().getValues();
var urlCol = 4; // column number where URL's should be populated; A = 1, B = 2 etc
var responses = form.getResponses();
var timestamps = [], urls = [], resultUrls = [];
for (var i = 0; i < responses.length; i++) {
timestamps.push(responses[i].getTimestamp().setMilliseconds(0));
urls.push(responses[i].getEditResponseUrl());
}
for (var j = 1; j < data.length; j++) {
resultUrls.push([data[j][0]?urls[timestamps.indexOf(data[j][0].setMilliseconds(0))]:'']);
}
sheet.getRange(2, urlCol, resultUrls.length).setValues(resultUrls);
}
This is not possible right now but this request is being tracked on the Issue Tracker here. Please add your use cases there and watch it for updates.
I found no way to create a pre-filled URL from the form id itself. It is possible if the form has already an answer:
var form = FormApp.openById('1nGvvEzQHN1n-----_your_for_id_----zemoiYQA');
var responses = form.getResponses();
Logger.log(responses[0].toPrefilledUrl());
referring to this answer, it can be used to create prefilled urls, by replacing the last line like this:
instead of
FormResponse.submit();
it will be
FormResponse.toPrefilledUrl();