googlescript spreadsheet not updating on exec - javascript

When I published the app, in dev mode the spreadsheet is getting updated, but in exec mode it is not, even though the spreadsheet has all the permission for any anonymous to edit it.
//Code.js:
function doGet(e) {
return HtmlService.createTemplateFromFile('Form.html')
.evaluate() // evaluate MUST come before setting the NATIVE mode
.setTitle('Name To Appear in Browser Tab')
.setSandboxMode(HtmlService.SandboxMode.NATIVE);
}
function processForm(theForm) {
var fileBlob = theForm.picToLoad;
var fldrSssn = DocsList.getFolder('For Web Hosting');
var createdFile = fldrSssn.createFile(fileBlob);
var fileUrl = createdFile.getUrl();
var name = theForm.user_name;
var files = DocsList.find('prat');// this is an array of file objects that include the term 'thisisthesheetIwant'
var file = files[0];// I take the first one
var ss = SpreadsheetApp.open(file);// using that file object I can open a spreadsheet
var sheet = ss.getSheets()[0];
var lastRow = sheet.getLastRow();
sheet.getRange(lastRow+1, 1, 1, 2).setValues([[name,fileUrl]]);
return true;
}

If you haven't re-published a new version, it will keep running the old version in exec mode. Dev mode runs the current version. Exec mode runs the last published version

Related

How to create file directory from reading spreadsheet in apps script

I have managed to record a folder's file/folder directory into a Google Sheet. From this Google Sheet I would like to copy this folder structure by reading each row.
Google Sheet Link: https://docs.google.com/spreadsheets/d/1qgDd8PEmHSYz5IsN9banYBjbmAyoLLVe3WMnOvmHdlE/edit?usp=sharing
function copyFolderTree() {
const sourceFolderId = '1uTGq2MRHzbev23sQzzFCi3Pl-v-ntMql';
const sourceFolder = DriveApp.getFolderById(sourceFolderId).getName();
const ss = SpreadsheetApp.getActiveSpreadsheet();
const ws = ss.getSheetByName('Sheet1');
const data = ws.getDataRange().getValues();
range.shift()
const destinationRootFolder = DriveApp.createFolder(`${sourceFolder}`)
data.forEach(function(row){
Logger.log(row)
let depth = row[4]
if (row[4] === depth && row[2] === 'Folder') {
Logger.log(`Name of folder is currently ${row[4]}`)
Logger.log(`Depth is currently ${row[4]}`)
Logger.log(`Type is currently ${row[2]}`)
destinationRootFolder.createFolder(row[0])
row.push('hello')
Logger.log(row)
range.setValues(values);
}
})
}
I realise this is the incorrect thinking. Do I need to place the newly created folder into it's copied parent folder using the folder's name?
Thank you,
[1]: https://docs.google.com/spreadsheets/d/1qgDd8PEmHSYz5IsN9banYBjbmAyoLLVe3WMnOvmHdlE/edit?usp=sharing
For folder tree, you can try
function copyFolderTree() {
const ss = SpreadsheetApp.getActiveSpreadsheet();
const ws = ss.getSheetByName('Sheet1');
const range = ws.getDataRange();
const values= range.getValues();
var levels = []
values.forEach(r => {
if (r[2]=='Folder'){
if (r[4]==0){ // root
var dossier = DriveApp.createFolder(r[0]);
levels[1] = dossier.getId(); // specific correction as 1 doesn't exists in the example provided
}
else {
var parent = DriveApp.getFolderById(levels[r[4]-1]);
var dossier = parent.createFolder(r[0]);
levels[r[4]] = dossier.getId();
}
}
})
}
From From this Google Sheet I would like to copy this folder structure by reading each row. and First I would like to create the folder structure. My next step would be to work on transferring the files across., when you want to copy a folder (in your sample Spreadsheet, it's "Amy Bits".) including all subfolders and files using Google Apps Script, how about the following sample script? I have created a Google Apps Script library for achieving this situation. So in this answer, I would like to propose the script using the Google Apps Script library.
Usage:
1. Install library.
You can see the method for installing the library at here.
2. Enable Drive API.
In this library, Drive API is used. So please enable Drive API at Advanced Google services.
3. Sample script:
When your sample Spreadsheet is used, the sample script is as follows.
function myFunction() {
const sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("Sheet1");
const sourceFolderId = sheet.getRange("B2").getValue().split("/")[5]; // Please set the source folder ID.
const destinationFolderId = DriveApp.createFolder("sample").getId(); // Please set the destination folder ID.
const object = { sourceFolderId, destinationFolderId, overwrite: true };
const res = CopyFolder.copyAllFilesFolders(object);
console.log(res);
}
If you can directly put the source folder ID and the destination folder ID, you can also the following sample script.
function myFunction() {
const object = {
sourceFolderId: "###", // Please set the source folder ID.
destinationFolderId: "###", // Please set the destination folder ID.
overwrite: true,
};
const res = CopyFolder.copyAllFilesFolders(object);
console.log(res);
}
Note:
If the script process time is over 6 minutes, you can see one more sample script. Ref
Reference:
CopyFolder of Google Apps Script library

Is it possible to post multiple Live sensor data to a single Google Spread Sheet?

I made a weighing Machine using an M5 stack. The measured data is being saved in the sheet called, "logsheet" and another sheet (called "chartsheet")to create a gauge chart using that live data. Now, I want to create 60 more weighing machines like this and want to display their live data in a single spreadsheet. Is it possible to create a sheet like this?
This is my Arduino code: (only postvalues funtion)
void postValues(float a){
DynamicJsonDocument doc(capacity);
doc["sensor"] = a;
serializeJson(doc, Serial);
Serial.println("");
serializeJson(doc, buffer, sizeof(buffer));
HTTPClient http;
Serial.println(http.begin(host));
http.addHeader("Content-Type", "application/json");
int status_code = http.POST((uint8_t*)buffer, strlen(buffer));
Serial.printf("status_code=%d\r\n", status_code);
if( status_code == 200 ){
Stream* resp = http.getStreamPtr();
DynamicJsonDocument json_response(255);
deserializeJson(json_response, *resp);
serializeJson(json_response, Serial);
Serial.println("");
}else{
Serial.println(http.getString());
}
http.end();
}
And My appSpript code:
function doPost(e) {
var postjsonString = e.postData.getDataAsString();
var postdata = JSON.parse(postjsonString);
var spreadsheet = SpreadsheetApp.openById("####"); //sheetName
var logSheet = spreadsheet.getSheetByName("logSheet") || spreadsheet.insertSheet("logSheet"); //logsheet
var chartSheet = spreadsheet.getSheetByName("chartSheet") || spreadsheet.insertSheet("chartSheet"); //chartsheet
sensor_data = postdata.sensor;
var date_time = Utilities.formatDate(new Date(), 'JST', 'yyyy年M月d日 H時m分s秒')
var values = [date_time, sensor_data];
logSheet.appendRow(values);
//chart
chartSheet.getRange("A1:B1").setValues([values]);
var max = 25;
var min = 0;
var charts = chartSheet.getCharts();
if (charts.length == 0) {
var chart = chartSheet.newChart().setChartType(Charts.ChartType.GAUGE).addRange(chartSheet.getRange('B1')).setPosition(3, 1, 0, 0).setOption('height', 300).setOption('width', 300).setOption('title', 'Weighing Gauge').setOption('max', max).setOption('min', min).build();
chartSheet.insertChart(chart);
}
}
First things to check
Make sure your web app is deployed to be accessible to "Anyone, even anonymous"
IMPORTANT! Try deploying the web app again with the Old Editor - the New IDE has issues with deployment of web apps and sometimes redeploying it in the old editor fixes things.
Sample web app
function doPost(e) {
let file = SpreadsheetApp.getActive();
let sheet = file.getSheetByName("Sheet1");
let id = e.parameter.id;
let weight1 = e.parameter.weight1;
let weight2 = e.parameter.weight2;
sheet.appendRow([id, weight1, weight2])
}
Then accessing with a simple POST request with CURL from any machine:
curl -d "id=0001&weight1=100&weight2=200" -X POST https://script.google.com/a/egs-sbt095.eu/macros/s/[SCRIPTID]/exec
Produces this:
This example uses cURL just to show that now the spreadsheet can receive data from anywhere. Here is another variation of the same POST request:
curl -X POST "https://script.google.com/a/egs-sbt095.eu/macros/s/[SCRIPTID]/exec?id=0001&weight1=100&weight2=200"
Finally, remember to make sure you are redeploying your web app every time you make changes!

Opening an excel file using Protractor

Protractor Query: our application generate a excel file which contains aome formulas. Now until I don't open the excel, it won't readable by exceljs. Is there any way I can open the excel and close it like we do robot in selenium?
Please Note that if i Open the file and keep at specified location below code works fine, but when i download the same from application and try to read it it wont work.
function compareExcelFromScreen(VerificationSection, file, row, column, SheetName, callback) {
var wrkbook = new Excel.Workbook();
var valFromExcel = null;
var filteredExcelValue = null;
var filteredScreenvalue = null;
var temp = null;
wrkbook.xlsx.readFile(file.toString()).then(function () {
var worksheet = wrkbook.getWorksheet(SheetName);
valFromExcel = worksheet.getRow(parseInt(row)).getCell(parseInt(column)).value;
}
}

Need to create a function that saves a google apps script (or fixes the original function)

I'm just beginning my JS journey. Currently trying to update a MailChimp API call within Google Sheets Script. The issue is that the script (originally found here:https://medium.hackinrio.com/mailchimp-reports-in-google-sheets-88496a153ee2 1) only works when you SAVE the Google Scripts editor. I would like to create a JavaScript GAS function that is able to run every day that saves the Script Editor thereby updating the MailChimp count. Or some other solution that would allow this to work.
Google Scripts Function:
function getSubscribersCount(api_key, list_id) {
var API_KEY = api_key;
var LIST_ID = list_id;
var dc = '(my mailchimp API Key goes here)'.split('-')[1];
var api = 'https://'+ dc +'.api.mailchimp.com/2.0';
var membersPath = '/lists/members.json';
// MC api-specific parameters
var payload = {
"apikey": API_KEY,
"id": LIST_ID
};
// GAS specific parameters:
var params = {
"method": "POST",
"muteHttpExceptions": true,
"payload": payload
};
var apiCall = function(endpoint){
var apiResponse = UrlFetchApp.fetch(api+endpoint, params);
var json = JSON.parse(apiResponse);
return json;
};
var members = apiCall(membersPath);
return members.total;
}
Is there a function I can add that will enable me to save the function, or perhaps emulate a CMD + s keyboard event?
Instead of writing a formula into your spreadsheet to invoking your script you should write another function that modifies the spreadsheet directly.
function updateSubscriberCount() {
var ss = SpreadsheetApp.getActiveSpreadsheet(),
sheet = ss.getSheetByName("Sheet1"),
api_key = sheet.getRange("B1").getValue(),
list_id = sheet.getRange("C1").getValue();
sheet.getRange("A1").setValue(getSubscribersCount(api_key, list_id));
}
Then you click on "edit/current project's triggers" and set up a timer to run that function at regular intervals.
However you have to run that function manually at least once to grant the script the permissions it needs.

Getting special Folder path for a given user in Jscript

How to get the path of a shell folder like "Local Settings" or "Local Appdata" for a specific user other than the current user?
While there are methods for getting special folder paths in Windows Script Host — WshShell.SpecialFolders and Shell.NameSpace — they return paths for the current user only. Getting other users' special folder paths is a bit tricky.
The proper way to do this is to use the Windows API SHGetKnownFolderPath function (or SHGetFolderPath on Windows versions prior to Vista). But the problem is, Windows Script Host doesn't support calling WinAPI functions, so to make use of these functions in your script you'll have to expose them via a custom-written COM component.
Another possible but undocumented solution is to read the special folder paths from that user's registry hive, specifically, the HKEY_USERS\<user_SID>\Software\Microsoft\Windows\CurrentVersion\Explorer\User Shell Folders key.
The paths in the User Shell Folders key are typically specified using the %USERPROFILE% environment variable; so to get fully-qualified paths you'll have to substitute this variable with the ProfileImagePath value from the HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\ProfileList\<user_SID> key.
Also, the HKEY_USERS\<user_SID> key is only available when the corresponding user is currently logged on. For a general solution, you would have to load the user's hive (<UserProfile>\ntuser.dat) into a temporary registry key (say, HKEY_USERS\Temp) and read values from this key instead.
Below is sample JScript code that demonstrates how your task can be accomplished. On Windows 7 and Vista, you may need to run the script as Administrator depending on your UAC settings.
NOTE: This method is discouraged, as Raymond Chen explains in his article The long and sad story of the Shell Folders key. There's no guarantee it will keep working in future versions of Windows.
var strUser = "foo";
var strDomain = "bar";
// If the account is local, domain name = computer name:
// var strDomain = getComputerName();
var strSID = getSID(strUser, strDomain);
var strProfilePath = getProfilePath(strSID);
// Load the user's registry hive into the HKEY_USERS\Temp key
var strTempKey = "Temp";
loadHKUHive(strTempKey, strProfilePath + "\\ntuser.dat");
// Get unexpanded path, e.g. %USERPROFILE%\AppData\Roaming
//var strAppData = getAppData(strSID);
var strAppData = getAppData(strTempKey);
WScript.Echo(strAppData);
// Expand the previous value to a fully-qualified path, e.g. C:\Users\foo\AppData\Roaming
strAppData = strAppData.replace(/%USERPROFILE%/i, strProfilePath);
WScript.Echo(strAppData);
// Unload the user's registry hive
unloadHKUHive(strTempKey);
function getComputerName() {
var oShell = new ActiveXObject("WScript.Shell");
return oShell.ExpandEnvironmentStrings("%COMPUTERNAME%");
}
function getSID(strUser, strDomain) {
var oAccount = GetObject("winmgmts:root/cimv2:Win32_UserAccount.Name='" + strUser + "',Domain='" + strDomain + "'");
return oAccount.SID;
}
function getProfilePath(strSID) {
var oShell = new ActiveXObject("WScript.Shell");
var strValue = oShell.RegRead("HKLM\\Software\\Microsoft\\Windows NT\\CurrentVersion\\ProfileList\\" + strSID + "\\ProfileImagePath");
return strValue;
}
function getAppData(strSID) {
var oShell = new ActiveXObject("WScript.Shell");
var strValue = oShell.RegRead("HKEY_USERS\\" + strSID + "\\Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\User Shell Folders\\AppData");
return strValue;
}
function loadHKUHive(strKeyName, strHiveFile) {
var oShell = new ActiveXObject("WScript.Shell");
oShell.Run("reg load HKU\\" + strKeyName + " " + strHiveFile, 0, true);
}
function unloadHKUHive(strKeyName) {
var oShell = new ActiveXObject("WScript.Shell");
oShell.Run("reg unload HKU\\" + strKeyName, 0, true);
}

Categories