Load data from google sheet on start up - google-apps-script

I tried to retrieve a list of agents who are stored in a google sheet. The problem that I am facing right now is that I can get the list of agents in the script file. However, when I try to pass it to an html file, I keep getting null for the list. I absolutely has no idea how that can be.
Can someone give me an idea where I should look for?
My script:
var DB_URL = "";
var AGENT_DB = "";
var CREATED_ON_IDX = 0;
var NAME_IDX = 1;
var EMAIL_IDX = 2;
function agentService_getAgents() {
var ss = SpreadsheetApp.openByUrl(DB_URL);
var sheet = ss.getSheetByName(AGENT_DB);
var dataRange = sheet.getDataRange();
var agents = [];
var values = dataRange.getValues();
for (var i = 1; i < values.length; ++i) {
var row = values[i];
var name = row[NAME_IDX];
var email = row[EMAIL_IDX];
var createdOn = row[CREATED_ON_IDX];
var agent = new Agent(name, email, createdOn);
agents[i-1] = agent;
}
Logger.log(agents);
return agents;
}
Ajax call in Html
<script type="text/javascript">
function onSuccess(agents) {
var $table = $("table");
console.log(agents);
}
google.script.run.withSuccessHandler(onSuccess)
.agentService_getAgents();
</script>
So Logger.log(agents) gives me a list of agent; but console.log(agents) gives me null.

Related

We're sorry, a server error occurred. Please wait a bit and try again. (line 63, file "Code")

Thank you in advance for helping.
I am trying to convert the most recent submitted data from Google Form/Google sheets to a "template" Google doc. Basically, when a user submit a form, it will convert the data from Google Sheet and create a new Google Doc.
Side note: Im not really a coder.. I found the base script online and tried to modified it accordingly. I would greatly appreciate a step by step if possible?
AGAIN, THANK YOU SO MUCH
function createDocument() {
var headers = Sheets.Spreadsheets.Values.get('SHEET-ID', 'A1:AU1');
var tactics = Sheets.Spreadsheets.Values.get('SHEET-ID', 'A2:AU2');
var templateId = 'DOCTEMPLATE-ID';
for(var i = 0; i < tactics.values.length; i++){
var Fclient = tactics.values[i][0];
var Lclient = tactics.values[i][1];
var birthday = tactics.values[i][2];
var profession = tactics.values[i][3];
var email = tactics.values[i][4];
var phone = tactics.values[i][5];
var whatsapp = tactics.values[i][6];
var preferredcontact = tactics.values[i][7];
var UScitizen = tactics.values[i][8];
var Ocitizen = tactics.values[i][9];
var Tsapre = tactics.values[i][10];
var Pairplane = tactics.values[i][11];
var Photelamen = tactics.values[i][12];
var FFlyer = tactics.values[i][13];
var hotelloy = tactics.values[i][14];
var vistedcountries = tactics.values[i][15];
var smoke = tactics.values[i][16];
var allergies = tactics.values[i][17];
var Othermed = tactics.values[i][18];
var addANOTHER = tactics.values[i][19];
var emergencyname = tactics.values[i][20];
var emergencyphone = tactics.values[i][21];
var emergencyrelation = tactics.values[i][22];
var emergencyname2 = tactics.values[i][23];
var emergencyphone2 = tactics.values[i][24];
var emergencyrelation2 = tactics.values[i][25];
var comptravelmag = tactics.values[i][26];
var secondaryFname = tactics.values[i][27];
var secondaryLname = tactics.values[i][28];
var secondarybirthday = tactics.values[i][29];
var secondaryprofession = tactics.values[i][30];
var secondaryemail = tactics.values[i][31];
var secondaryphone = tactics.values[i][32];
var secondarywhatsapp = tactics.values[i][33];
var secondarypreferredcontact = tactics.values[i][34];
var secondaryUScitizen = tactics.values[i][35];
var secondaryOcitizen = tactics.values[i][36];
var secondaryTsapre = tactics.values[i][37];
var secondaryPairplane = tactics.values[i][38];
var secondaryPhotelamen = tactics.values[i][39];
var secondaryFFlyer = tactics.values[i][40];
var secondaryhotelloy = tactics.values[i][41];
var secondaryvistedcountries = tactics.values[i][42];
var secondarysmoke = tactics.values[i][43];
var secondaryallergies = tactics.values[i][44];
var secondaryOthermed = tactics.values[i][45];
var timestamp = tactics.values[i][46];
//Make a copy of the template file
var documentId = DriveApp.getFileById(templateId).makeCopy().getId();
//Rename the copied file
DriveApp.getFileById(documentId).setName('Basic Information: ' + Lclient + 'test');
//Get the document body as a variable.
var body = DocumentApp.openById(documentId).getBody(); **ERROR HERE**
//Insert the supplier name
body.replaceText('{{Fcilent}}', Fclient);
body.replaceText('{{Lcilent}}', Lclient);
body.replaceText('{{birthday}}', birthday);
body.replaceText('{{profession}}', profession);
body.replaceText('{{email}}', email);
body.replaceText('{{phone}}', phone);
body.replaceText('{{whatsapp}}', whatsapp);
body.replaceText('{{preferredcontact}}', preferredcontact);
body.replaceText('{{UScitizen}}', UScitizen);
body.replaceText('{{Ocitizen}}', Ocitizen);
body.replaceText('{{Tsapre}}', Tsapre);
body.replaceText('{{Pairplane}}', Pairplane);
body.replaceText('{{Photelamen}}', Photelamen);
body.replaceText('{{FFlyer}}', FFlyer);
body.replaceText('{{hotelloy}}', hotelloy);
body.replaceText('{{vistedcountries}}', vistedcountries);
body.replaceText('{{smoke}}', smoke);
body.replaceText('{{allergies}}', allergies);
body.replaceText('{{Othermed}}', Othermed);
body.replaceText('{{addANOTHER}}', addANOTHER);
body.replaceText('{{emergencyname}}', emergencyname);
body.replaceText('{{emergencyphone}}', emergencyphone);
body.replaceText('{{emergencyrelation}}', emergencyrelation);
body.replaceText('{{emergencyname2}}', emergencyname2);
body.replaceText('{{emergencyphone2}}', emergencyphone2);
body.replaceText('{{emergencyrelation2}}', emergencyrelation2);
body.replaceText('{{comptravelmag}}', comptravelmag);
body.replaceText('{{secondaryFname}}', secondaryFname);
body.replaceText('{{secondaryLname}}', secondaryLname);
body.replaceText('{{secondarybirthday}}', secondarybirthday);
body.replaceText('{{secondaryprofession}}', secondaryprofession);
body.replaceText('{{secondaryemail}}', secondaryemail);
body.replaceText('{{secondaryphone}}', secondaryphone);
body.replaceText('{{secondarywhatsapp}}', secondarywhatsapp);
body.replaceText('{{secondarypreferredcontact}}', secondarypreferredcontact);
body.replaceText('{{secondaryUScitizen}}', secondaryUScitizen);
body.replaceText('{{secondaryOcitizen}}', secondaryOcitizen);
body.replaceText('{{secondaryTsapre}}', secondaryTsapre);
body.replaceText('{{secondaryPairplane}}', secondaryPairplane);
body.replaceText('{{secondaryPhotelamen}}', secondaryPhotelamen);
body.replaceText('{{secondaryFFlyer}}', secondaryFFlyer);
body.replaceText('{{secondaryhotelloy}}', secondaryhotelloy);
body.replaceText('{{secondaryvistedcountries}}', secondaryvistedcountries);
body.replaceText('{{secondarysmoke}}', secondarysmoke);
body.replaceText('{{secondaryallergies}}', secondaryallergies);
body.replaceText('{{secondaryOthermed}}', secondaryOthermed);
body.replaceText('{{timestamp}}', timestamp);
//Append tactics
parseTactics(headers.values[0], tactics.values[i], body);
}
}
function parseTactics(headers, tactics, body){
for(var i = 1; i < tactics.length; i++){
{tactics[i] != '' &&
body.appendListItem(headers[i] + ' | ' + tactics[i] + ' OTHER').setGlyphType(DocumentApp.GlyphType.BULLET);
}
}
}
Error: "We're sorry, a server error occurred. Please wait a bit and try again. (line 63, file "Code")"
I expected the script to generate a new google doc from the data sheet as it is being submitted on google form.
I think your pretty close. Here's an example I did.
First, I created a function to generate some data for myself.
function testData() {
var ss=SpreadsheetApp.getActive();
var sh=ss.getActiveSheet();
sh.clearContents();
var rg=sh.getRange(1,1,10,10);
var vA=rg.getValues();
for(var i=0;i<vA.length;i++) {
for(var j=0;j<vA[i].length;j++) {
vA[i][j]=Utilities.formatString('row: %s - col: %s',i+1,j+1);
}
}
rg.setValues(vA);
}
The above function creates a sheet that looks like this:
The Template File Looks like this:
And after running this code:
function createDoc(){
var spreadsheetId='spreadsheet Id';
var templateId='template Id';
var data=Sheets.Spreadsheets.Values.get(spreadsheetId,'Sheet177!A1:J2');//range include sheet name
var docId=DriveApp.getFileById(templateId).makeCopy('Test').getId();
var body=DocumentApp.openById(docId).getBody();
for(var i=0;i<data.values.length;i++) {
for(var j=0;j<data.values[i].length;j++) {
var s=Utilities.formatString('{{col%s-%s}}',i+1,j+1);
body.replaceText(s,data.values[i][j]);
}
}
}
There appears in the same folder another file named test that looks like this:
I must say that sure is a simple way to get data.
I'm kind of wondering if perhaps you simply didn't authenticate the program in the script editor.

Script: Transpose, Find and Save

I have some data containing, Dates, Usernames and an average percent that i want to save in a certain way. My problem is that the order of the usernames can change depending on if new ones are added. I therefore need to "find" a specific username and then save the percentage data in the correct column.
I have found some code that partially helps me save the data that i need. But i could use some help in the "find" the corresponding username and save it in a certain Column part.
function save() {
var sss = SpreadsheetApp.getActive();
var ss = sss.getSheetByName('Result');
var range = ss.getRange('B1:B10');
var data = range.getValues();
var tss = SpreadsheetApp.getActive();
var ts = tss.getSheetByName('Archive');
ts.getRange(ts.getLastRow()+1, 1,data[0].length,data.length)
.setValues(Object.keys(data[0]).map ( function (columnNumber) {
return data.map( function (row) {
return row[columnNumber];
});
}));
}
Basically from this:
To a result that looks like this:
Thank you for your assistance.
Alright for anyone out there that may have a similar problem, this is what i ended up with.
function extractAttendance() {
var currentSheet = SpreadsheetApp.getActive();
var attendanceTab = currentSheet.getSheetByName('Data_Filtered');
var userData = attendanceTab.getRange('B1:B').getValues();
var percentageData = attendanceTab.getRange('I1:I').getValues();
var archiveTab = currentSheet.getSheetByName('Archive');
var existingUsersRow = archiveTab.getRange('1:1');
var newRowNumber = archiveTab.getLastRow() + 1;
archiveTab.getRange(newRowNumber, 1).setValue(new Date());
for (var i = 1; i < userData.length; i++) {
var user = userData[i][0];
if (user === '') {
continue;
}
var existingUsers = existingUsersRow.getValues()[0];
var exists = false;
var existingColumnNumber = -1;
for (var j = 0; j < existingUsers.length; j++) {
if (existingUsers[j] === user) {
exists = true;
existingColumnNumber = j + 1;
break;
}
}
if (exists) {
archiveTab.getRange(newRowNumber, existingColumnNumber).setValue(percentageData[i]);
} else {
var newColumnNumber = archiveTab.getLastColumn() + 1;
archiveTab.getRange(1, newColumnNumber).setValue(user);
archiveTab.getRange(newRowNumber, newColumnNumber).setValue(percentageData[i]);
}
}
}
It might be easier to implement your desired functionality through looping rather than through mapping.
The following code retrieves all users ad their percentage data in ‘Result’ and transfers the data (in the format you desire) to "Archive" with the percentages data pasted with the corresponding timestamp into the first empty row.
function save() {
var sss = SpreadsheetApp.getActive();
var ss = sss.getSheetByName('Result');
var range = ss.getRange('B1:B');
var percentageRange = ss.getRange('G1:G');
var userData = range.getValues();
var percentageData = percentageRange.getValues();
var tss = SpreadsheetApp.getActive();
var ts = tss.getSheetByName('Archive');
var userRow=1;
var percentageRow=(ts.getLastRow()+1)
for(var i=0; i<=userData.length; i++)
{
{
var j=(i+2);
ts.getRange(userRow, j).setValue(userData[i])
ts.getRange(percentageRow, 1).setValue(new Date())
ts.getRange(percentageRow, j).setValue(percentageData[i])
}
}
}

Get data from array in nested json using Google Script

I need to fix a Google Script I've been working on. Basically, I have a json https://www.instagram.com/nike/?__a=1 that returns basic info about Nike's account on instagram. I have no problem retrieving data from objects such as "biography". But, when I try to retrieve nested objects (arrays) I'm doing something wrong because the results arrive duplicated (see attachment). Can anyone help me figure out what I'm doing wrong?
// the name of the sheet within your document
var sheetName = "Sheet1";
// the name of the Instagram account you want the follower count for
var instagramAccountName = "nike";
function insert() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = ss.getSheetByName(this.sheetName);
var followers = [];
var followers = captionArray(this.instagramAccountName);
for(var i = 0 ; i < 3; i++) {
sheet.appendRow([Utilities.formatDate(new Date(), "GMT", "yyyy-MM-dd"), followers]);
};
}
function captionArray(username) {
var i = 0;
for(var i = 0; i < 3; i++) {
var url = "https://www.instagram.com/" + username + "/?__a=1";
var response = UrlFetchApp.fetch(url).getContentText();
var caption = [];
var caption = JSON.parse(response).graphql.user.edge_owner_to_timeline_media.edges[i].node.edge_media_to_caption.edges[i].node.text;
return caption;
};
}
I think this is causing problems:
You're using the same index (i) for both arrays, but the second have only one element.
You just need to do one request.
This code works for me:
function captionArray(username) {
var captions = [];
var url = "https://www.instagram.com/nike/?__a=1";
var response = UrlFetchApp.fetch(url).getContentText();
var edges = JSON.parse(response).graphql.user.edge_owner_to_timeline_media.edges;
for(var i = 0, limit = edges.length; i < limit; i++) {
captions.push(edges[i].node.edge_media_to_caption.edges[0].node.text);
}
return captions;
}

How to get e.parameter.array() in doGet(e) funtion in Google app script while submitting an array via HTML Form

I am trying to submit Html form with an array to google app script webapp but unable to retrieve array into the app.
here the html form code
function onOpen(){
SpreadsheetApp.getUi().createMenu("Send Mail").addItem("Insurance Mail", "insuranceMail").addToUi();
}
function insuranceMail(){
var webApp = "https://script.google.com/macros/s/AKfycbwsAlL2GWySwmkGooucVmDXTJK60TLAcAgQWYAdxGumgdI2Kjs/exec";
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sh = ss.getActiveSheet();
var row = sh.getActiveRange().getRow();
var clientName = sh.getRange("A"+row).getDisplayValue();
var senderID = Session.getActiveUser().getEmail();
var clientID = sh.getRange("B"+row).getDisplayValue();
var senderName = sh.getRange("C"+row).getDisplayValue();
var namesOfIns = sh.getRange("D"+row).getDisplayValue().replace(/,/g,"<br>"); //Next Line Formatting
var sub= "Additional Credentialing Options";
var message = "";
var date = new Date();
var iSheet = ss.getSheetByName("Insurances");
var iLastRow = iSheet.getLastRow();
var insurances = [];
var plan = [];
var values = [];
var tableRows = [];
var j,count = 1,tableRow;
for(var i = 0;i<=iLastRow;i++){
j=i+2;
insurances[i] = iSheet.getRange("A"+j).getDisplayValue(); //Get Insurance Names
}
for(var i = 0;i<=iLastRow;i++){
j=i+2;
plan[i] = iSheet.getRange("B"+j).getDisplayValue(); //Get Plan Names
}
for(var i = 0;i<=iLastRow;i++){
j=i+2;
values[i] = iSheet.getRange("C"+j).getDisplayValue(); // Get Yes/No values
}
var messageHtmlTop = "<!DOCTYPE html><html><head>"
+"<style> table{font-size:11px;font-family:sans-serif;} tr,td {padding: 0px 0px 0px 0px;text-align:center;}</style></head>"
+"<body>"
+"Hello "+clientName+",<br><br>"
+"<br><br>"
+"Some Html"
+"<b>"+namesOfIns+"</b><br><br>";
var messageHtmlTop2 = "<form action ='"+webApp+"'method='GET'><input type='email' name='clientID' value='"+clientID+"' style='display: none'><input type='text' name='clientName' value='"+clientName+"' style='display: none'>"
+"<table><tr><th>Sr. No.</th><th>Select</th><th>Insurance</th><th>Plane</th></tr>";
var messageHtmlMid = "";
for(n in insurances){
if(values[n] == "Yes" || values[n] == "yes"){
tableRow ="<tr>"
+"<td>"+count+"</td>"
+"<td><input type='checkbox' name='insurances[]' value='"+insurances[n]+"'></td>"
+"<td>"+insurances[n]+"</td>"
+"<td>"+plan[n]+"</td>"
+"</tr>";
tableRows[n] = tableRow;
count++;
} // Creat table rows array
} //Add Form top to the HTML on if atleast 1 Yes is present
for(n in tableRows){
messageHtmlMid = messageHtmlMid.concat(tableRows[n]); //Compose HTML Form Mid Part
};
var messageHtmlBottom1 ="<tr></tr><tr><td></td><td></td><td><input type='submit' value='Send' width=100% hieght=40px></td></tr></table>"
+"</form><br><br>"
+"some sentence<br><br>"
var messageHtmlBottom ="some HTML"
+"</body>"
+"</html>";
for(n in values){
if (values[n] == 'Yes'){
messageHtmlTop = messageHtmlTop.concat(messageHtmlTop2);
messageHtmlBottom = messageHtmlBottom1.concat(messageHtmlBottom);
break;
}
} ////Add Form bottom to the HTML on if atleast 1 Yes is present
var messageHtml = messageHtmlTop.concat(messageHtmlMid).concat(messageHtmlBottom); //Compose Full HTML with Form
Logger.log(messageHtml);
try{
MailApp.sendEmail(clientID,sub,message,{'htmlBody':messageHtml});
sh.getRange("E"+row).setValue("Sent");
} catch(e){
sh.getRange("E"+row).setValue("Error");
}
sh.getRange("F"+row).setValue(date);
}
Here my webapp code i am trying to work which is giving me empty result.
function doGet(e) {
var name = e.parameter.clientName;
var id = e.parameter.clientID;
var date = new Date();
var iSheet = SpreadsheetApp.openById("ID").getSheetByName("Responses");
var lastRow = iSheet.getLastRow();
var getIns =[];
var insurances = "";
for(n in e.parameter.insurances){
getIns[n] = e.parameter.insurances[n];
}
for(n in getIns){
insurances = insurances.concat(getIns[n]+"\n");
}
lastRow++;
iSheet.getRange("A"+lastRow).setValue(name);
iSheet.getRange("B"+lastRow).setValue(id);
iSheet.getRange("C"+lastRow).setValue(insurances);
iSheet.getRange("D"+lastRow).setValue(date);
return ContentService.createTextOutput('Some Sentence').setMimeType(ContentService.MimeType.TEXT)
}
I am getting client name,client ID,date printed into the sheet but the Column C is coming empty
There are two reasons you get an empty entry into the spreadsheet.
In the form, checkboxes are named as insurances[]. However, in the web app you refer to them as just insurances. So, please modify your Html so that the checkboxes are named 'insurances'
+"<td><input type='checkbox' name='insurances' value='"+insurances[n]+"'></td>"
As mentioned in the documentation here . The e.parameter only retrieves the first key:value pair
An object of key/value pairs that correspond to the request parameters. Only the first value is returned for parameters that have multiple values.
Instead, use e.parameters. Note the 's' at the end, it will return an array of checkbox values that were checked. As mentioned in the documentation above.
So instead of the following:
for(n in e.parameter.insurances){
getIns[n] = e.parameter.insurances[n];
}
for(n in getIns){
insurances = insurances.concat(getIns[n]+"\n");
}
you can just do this
var insurances = e.parameters.insurances.join("\n")
Your final web app would be the following:
function doGet(e) {
var name = e.parameter.clientName;
var id = e.parameter.clientID;
var date = new Date();
var iSheet = SpreadsheetApp.openById("ID").getSheetByName("Responses");
var lastRow = iSheet.getLastRow();
var getIns =[];
var insurances = e.parameters.insurances.join("\n")
lastRow++;
iSheet.getRange("A"+lastRow).setValue(name);
iSheet.getRange("B"+lastRow).setValue(id);
iSheet.getRange("C"+lastRow).setValue(insurances);
iSheet.getRange("D"+lastRow).setValue(date);
return ContentService.createTextOutput('We have received your request').setMimeType(ContentService.MimeType.TEXT)
}
Final note: Make sure to update your web app and redeploy.
References:
join()

google script maximum execution time - return google group emails (huge list)

Im trying to save google groups emails into a spreadsheet but Im getting the 'maximum execution time' error. Any ideas?
function listGroupMembers() {
var GROUP_EMAIL = "prgg#googlegroups.com";
var group = GroupsApp.getGroupByEmail(GROUP_EMAIL);
var users = group.getUsers();
var sheet = SpreadsheetApp.create("Group Mail");
for (var i = 0; i < users.length; i++) {
sheet.appendRow([users[i]]);
}
}
What is probably taking much of the time is the appendRow() call.
you should build an array with all the values and write this at once in your sheet.
Code could be like this :
function listGroupMembers() {
var GROUP_EMAIL = "prgg#googlegroups.com";
var group = GroupsApp.getGroupByEmail(GROUP_EMAIL);
var users = group.getUsers();
var sheet = SpreadsheetApp.create("Group Mail");
var values = [];
for (var i = 0; i < users.length; i++) {
values.push([users[i]]);
}
sheet.getRange(1,1,values.length, values[0].length).setValues(values);
}
EDIT
I didn't check the begining of your initial code, SpreadsheetApp.create("Group Mail"); returns a spreadsheet, not a sheet... that's why it fails on getRange.
Since it's not clear what you wanted to get exactly I assumed you wanted to create a new Sheet with that name if it doesn't exist.
The appropriate code would be like this :
function listGroupMembers() {
var GROUP_EMAIL = "prgg#googlegroups.com";
var group = GroupsApp.getGroupByEmail(GROUP_EMAIL);
var users = group.getUsers();
if(SpreadsheetApp.getActive().getSheetByName("Group Mail") == null){
var sheet = SpreadsheetApp.getActive().insertSheet("Group Mail");
}else{
var sheet = SpreadsheetApp.getActive().getSheetByName("Group Mail");
}
var values = [];
for (var i = 0; i < users.length; i++) {
values.push([users[i]]);
}
sheet.getRange(1,1,values.length, values[0].length).setValues(values);
}