var userProperties = PropertiesService.getUserProperties(); is not working properly for me? - google-apps-script

I am creating userproperties with PropertiesService, as
var userProperties = PropertiesService.getUserProperties();
for storing users single token for my add-on , When i set usertoken in userproperties with a key pair value as, userProperties.setProperty('USERTOKEN','token'); in an document.
Once i do this as per the userproperties scope i can retrieve the user properties value from any of the document by using userProperties.getProperty('USERTOKEN'); but,
When i do that the value is null (i.e), i cant retrieve the 'userProperties' value from other documents,
So that, the scope of the userproperties fails. The userproperties value is associated only with the particular document where it's created.
once my add-on is installed i used to check every time userproperties value for all documents ,
if(value)
{
retrieve data;
}
else
{
authorize;
}
Thus value is null and the user is made to authorize everytime for every new document. Since my add-on cant retrieve the value from userProperties.getProperty('USERTOKEN');

According to the documentation at Properties Service - Saving Data:
"Script properties can also be saved via the script editor user interface by going to File > Project properties and selecting the Project properties tab. User properties and document properties cannot be set or viewed in the user interface."
I'm not sure what it means but I think it means that even if you are able to set the property using script, the value will not update if you view it in File > Project Properties > User Properties.
But it doesn't mean that the property was not updated though. However, if it's a Script Property you set via script, the value will update in your view.
This I say because I tried it by setting it inside the doGet(). See the example below:
//Set properties as global variables
var userProperty = PropertiesService.getUserProperties();
var scriptProperty = PropertiesService.getScriptProperties();
function doGet() {
userProperty.setProperty('uservar', 'Hello');
scriptProperty.setProperty('scriptvar', 'World');
Logger.log(userProperty.getProperty('uservar'));
Logger.log(scriptProperty.getProperty('scriptvar'));
return HtmlService.createTemplateFromFile('index').evaluate();
}
I did it inside doGet() so that I can check it simply by refreshing my WebApp page.
Interestingly, the log shows the correct values (Hello, and World).
But if I visit the File > Project Properties, only the Script Propery value was updated, the User Property remains the same as the original value I set it for.
Hope this helps.

For some reason it seems that the PropertiesService does not work. Even when I use Google example in https://developers.google.com/apps-script/guides/properties#reading_data I am getting nulls. I have reverted back to the old UserProperties and it works, however it is supposed to be depreciated...
PropertiesService seem to be working for script properties though.

Related

Passign parameters form google sheet to google script

I am new to google scripts and I am having trouble with passing parameters from my google spreadsheet to my google script.
I have created a function in my script:
function functionname(ref) {
Logger.log(ref);
var value = SpreadsheetApp.getActiveSpreadsheet().getActiveSheet().getRange(ref).getValue();
//do stuff with the value read from the sheet
return modified_value;
}
and I am calling it in my google spreadsheet like:
=functionname(A4)
(the function is called from an empty A5 cell, with cell A4 filled with text).
I have initially tried with a static reference in the function, like:
SpreadsheetApp.getActiveSpreadsheet().getActiveSheet().getRange("H9").getValue()
In this situation, it worked perfectly, but I do not want to replicate the function for each cell I need to operate, given I need to deliver this to non-programmers and the list of cells will increase.
Initially, I read that passing the parameters from the cell will be sufficient to receive the value and I had tried also this solution. Still, no matter what I try, the value of ref is always "undefined".
Can anyone please help me understand what I am missing?
Thanks
No need for the SpreadSheetApps methods for custom function to pull the value from the SpreadSheet because it already gets the cell value that you are referencing. Just remove the var value = SpreadsheetApp.getActiveSpreadsheet().getActiveSheet().getRange(ref).getValue();
function functionname(ref) {
Logger.log(ref);
//do stuff with the value read from the sheet
return modified_value;
}
You can call this function directly on your spreadsheet. Don't forget to store the new value on a variable and return it, or return the computed value directly.

Need Script for Google Docs to Send Auto Email

I'm looking for a script that I can add to a Google sheet that will auto generate an email and include some of the fields in the spread sheet.
I had created a Google Form and I have that data going to the Google spreadsheet, the idea is when the user submits the form it sends that data to the spreadsheet and the spreadsheet sends an automated email.
I found this script and edited it some but it fails on the 4th line (var theEvent = e.values[1]):
function AutoConfirmation(e){
var theirFirst = "Bill";
var theirEmail = johndoe#example.com;
var theEvent = e.values[1];
var subject = "Form Submitted";
var message = "Thank you, " + theirFirst + " for the expressed interest in our " + theEvent;
MailApp.sendEmail (theirEmail, subject, message);
}
Shouldn't line 4 pull the data from column 1 in my google sheet? Is this old an script and it doesn't work now?
In my google sheet I have Site instead of event as a column and another that has Complete as a header.
Let me know what I have missed here as it seems that this should be simple.
I tried to run this and this is the result: screenshot of the error I get
I get the same type of error when running the code above so I thought I would run a logger to see if I get anything with that and the result is in the screen shot. Click the link to see it.
It looks that the script that you found is function to be put in a Apps Script project bounded to a Google spreadsheet and called by an installable trigger.
Shouldn't line 4 pull the data from column 1 in my google sheet?
No. e.values returns an Array which use a zero based index. This means that index for Column A, the first column, is 0.
Issue:
The error you are getting:
TypeError: Cannot read property 'values' of undefined
Means that the event object (e) is undefined, which means that you are trying to run this function manually. Functions that are attached to a trigger are supposed run when the corresponding trigger event happens: in this case, when a user submits the Form. You don't have to run it manually.
Solution:
Step 1: Install the trigger: If you haven't done so yet, install the trigger, either manually, following these steps, or programmatically, by copy the following function to your bound script and running it once:
function createOnFormSubmitTrigger() {
var ss = SpreadsheetApp.getActive();
ScriptApp.newTrigger("AutoConfirmation")
.forSpreadsheet(ss)
.onFormSubmit()
.create();
}
Step 2: Submit the form!: Once the trigger is installed, when a user submits the Form that is attached to your Spreadsheet (that is, assuming that you have attached the Form to the Spreadsheet), AutoConfirmation runs automatically, and the event object, containing these properties, is passed as an argument. If you run it manually, e is undefined (no event object is passed as parameter), and you get the error.
Note:
e.values[1] will retrieve the same value that is written to column B when the form is submitted, since JavaScript arrays are zero-indexed. You might want to use e.namedValues['yourProperty'] instead, to make sure your are retrieving the desired information.
Reference:
SpreadsheetTriggerBuilder.onFormSubmit()
Event Objects: Form submit

Keep getting 'Null' when pulling data from google sheets

Whenever I try to pull data from 2 of 3 sheets from using the 'google.script.run' function call from Javascript, I keep getting an error saying the array I am returning is Null, but when I just change the exact same function call to work on another sheet, it returns the data perfectly
I have tried deleting the sheets and giving it the same names, I have tried using 'openWithURL' instead of 'getActive' to access the spreadsheet, I have tried rewriting the code, I have tried the same code in a different project, and checking the documentation to make sure I am not missing any detail. I have tried changing the references to the sheets, some work and some dont.
var SS = SpreadsheetApp.getActive();
var DB_BOOKINGS = SS.getSheetByName("BookingDatabase");
var DB_VEHICLES = SS.getSheetByName("VehicleDatabase");
var DB_REQUESTS = SS.getSheetByName("RequestDatabase");
function getRequestData(){
return DB_REQUESTS.getDataRange().getValues();
}
<script>
function getRequestData(callingFunction) {
google.script.run
.withSuccessHandler(callingFunction)
.withFailureHandler(CustomAlert)
.getRequestData();
}
</script>
I want to retrieve the sheet data but keep getting a null value
Since this is an issue with formatting as you said, try using getDisplayValues() rather than getValues(), this will pull the data as you see it in the sheet (as a string), rather than the unformatted data itself.
Reference:
getDisplayValues
I was having a similar problem. This was exactly the solution I needed. For my situation, I was able to use getValues() successfully on the initial page load, but when I tried to run it again as a sort of 'refresh' to update the values without reloading the entire page, it would return null.
My data did indeed contain dates, so after changing it to getDisplayValues(), it worked perfectly.

Prevent manual copy of spreadsheet Google script

I have a Google sheet that is created monthly, so have writtena script that will make a copy of the current month's sheet in a specific folder and then populate cells in the new spreadsheet with data from the old. It works well.
I am trying to come up with a solution to warn users if they try to manually copy the spreadsheet using the 'make a copy' menu item to instead use the custom menu item provided.
I thought about setting a flag in a cell, but of course that only works for the first time, as a manual copy also copies the flag. If I could detect when the file is copied manually, I could reset the flag and then test for it onOpen.
Can someone please point me in the right direction. Unfortunately the users need to be able to edit the document, so I don't think I can disable the option in the file menu.
Many thanks
You can address this specific issue:
I thought about setting a flag in a cell, but of course that only
works for the first time, as a manual copy also copies the flag.
By using PropertiesService, you can use document property to add a property to a specific document. This property can be accessed by the script, run by any user, on that specific document.
However, if you copy the document, the property is not copied. You can look for this property during onOpen and determine if the document was copied the way you want.
You can do something like this:
function setProp(){ //use this to set the property to the document
var docProp = PropertiesService.getDocumentProperties();
docProp.setProperty("Copied", "false") //Properties are stored as text immaterially of the type of value you pass to it!
}
function getProp(){ //use this to check if the property of the document was set, if set will return true, else false
var docProp = PropertiesService.getDocumentProperties();
Logger.log(docProp.getProperty("Copied"))
return docProp.getProperty("Copied") == "false"
}
function onOpen(e){
var ui = SpreadsheetApp.getUi()
if(getProp()){ // Check to see if the property was set for the sheet.
ui.alert("Copied correctly")
} else { // This will trigger each time they open the sheet,
ui.alert("Copied Incorrectly, please use custom function to make a copy")
}
}
Hope that helps!

automatically create google contact from my google form

I have a google form that my clients fill out. How do I have the form create a google contact automatically each time someone new fills out the survey? I dont want to have to copy paste each time just to create a new contact in my gmail
I'm trying to use this script but getting an error when I try to run it with some test data
function onFormSubmit(e) {
var timestamp = e.values[0];
var firstName= e.values[1];
var lastName= e.values[2];
var email= e.values[3];
var phone= e.values[4];
ContactsApp.createContact( timestamp , firstName , lastName , email , phone );
}
TypeError: Cannot read property "values" from undefined. (line 2
You will get that error message when attempting to run the function manually, as there is no event being passed to the function.
Disregard the remainder of the post (see Henrique's comment).
According to the documentation:
An event is passed to every event handler as the argument (e) . You
can add attributes to the (e) argument that further define how the
trigger works or that capture information about how the script was
triggered.
If you use the attributes, you must still set the trigger from the
Resources menu, as described in the sections above.
https://developers.google.com/apps-script/guide_events#TriggerAttributes
I can't explain why this is the case, but it seems you need to use the
simple event handler (ie naming the function onFormSubmit), as well as
applying an installable event handler to that same function. Then,
for me at least, it works as expected.
HTH, Adam
There's no "phone" argument in createContact function. Before attempting to create it from a more difficult to debug trigger, have you tried writing a simple function to create a simple contact just to check that you got it right?
Also, I remember an old error with on form submit parameters, that may be back. Anyway, it doesn't hurt to add a toString in all your parameters. e.g.
var email = e.values[3].toString(); //just to be sure