nodejs turn string into array to upload to google sheets - javascript

Main Goals
Retrieve string from google sheets tab.
Edit string to remove "s and ,s.
re-format the string for upload into google sheets.
I have accomplished the first 2 tasks of my goal. Although I will explain in full the situation.
I am querying google sheets to return a row which contains a specified string so it can be added to a new sheet. currently I have been able to retrieve the row fine. the data comes back looking like this.
"12/24/2020, 3:40:33 PM","SanguineDepths+5","The Key Is
Timed","1000","Aegwynn","#name #name #name #[Manager]
name-name","name#0000 name#0000 name#0000
name#0000","Advertiser-Realm","testing-testing","Ticket","33p2bdlfto9g45","Customer-Realm","Horde",""
I have then used the following code to remove all of the "s and ,s.
const result = `"12/24/2020, 3:40:33 PM","SanguineDepths+5","The Key Is Timed","1000","Aegwynn","#name #name #name #[Manager] name-name ","name#0000 name#0000 name#0000 name#0000","Advertiser-Realm","testing-testing","Ticket","33p2bdlfto9g45","Customer-Realm","Horde",""`
var result1 = result.replace (/,/g, " ");
var result2 = result1.replace (/"/g, "");
Now my string is looking like this.
12/24/2020 3:40:33 PM SanguineDepths+5 Timed 1000 Aegwynn #name #name
#name #[Manager] name-name name#0000 name#0000 name#0000
name#0000 Advertiser-Realm testing-testing Ticket 33p2bdlfto9g45
Customer-Realm Horde
When uploading the above string which removes the characters I do not require, google sheets actually inputs all of the data in one cell instead of multiple, is there a way I can fix this? I did try to use arguments although I would like the 4 discord name#0000 in one cell and the 4 discord #name also in their own cell, like this.
Desired format for data to be entered in
So my main goal is to format the result in such a way I can write them to google sheets in their own cells.
Edit #1
I have used the .split(',') function but google API returns the following error:
"The API returned an error: Error: Invalid values[1][0]: list_value"

You could try to target the comma's in between to split the data at that point to an array and then take care of removing charcters.
Try:
result.split(',')
That should give you an Array.
And you could resuse your code to take out the characters you don't need with an array helper: something like:
result.split(',').map((part) => {
return part.replace (/"/g, "")
})

I was hoping for an easier solution, but I ended up using this method with multiple arguments for the string I got back from the sheet.
var result1 = result.replace (/,/g, " ");
var result2 = result1.replace (/"/g, "");
const argsRUN = result2.split(' ');
const command = argsRUN.shift().toLowerCase();
var date1 = (argsRUN[0]);
var time1 = (argsRUN[1]);
var ampm = (argsRUN[2]);
var dungeonkey = (argsRUN[3]);
var timedornot = (argsRUN[4]);
var costofboost = (argsRUN[5]);
var paymentrealm1 = (argsRUN[6]);
var boost1ID = (argsRUN[7]);
var boost2ID = (argsRUN[8]);
var boost3ID = (argsRUN[9]);
var boost4ID = (argsRUN[10]);
var boost1tag = (argsRUN[11]);
var boost2tag = (argsRUN[12]);
var boost3tag = (argsRUN[13]);
var boost4tag = (argsRUN[14]);
var advertiserrealm = (argsRUN[15]);
var commentup = (argsRUN[16]);
var ticketornot = (argsRUN[17]);
var uniquerunid = (argsRUN[18]);
var customerrealm = (argsRUN[19]);
var customerfaction = (argsRUN[20]);

Related

Apps Script Function to Erase Cell Containing Certain Text

I’m working on a Google Sheet for work (not allowed to share), and I want to create an Apps Script Function that parses through all the data and erases cell content if they contain “?”, “PPS”, “LES”, “MPES”,or “PSPEC”. I can’t find any way to do it without deleting the whole row, which i don’t want. Any help will be greatly appreciated, thank you.
function delIfContains() {
const contains = ["?","PPSF","LES","MPES","PSPEC"];//needles
const ss = SpreadsheetApp.getActive();
const sh = ss.getActiveSheet();//haystack
contain.forEach(s => {
sh.createTextFinder(s).matchEntireCell(false).findAll().forEach(rg => rg.clearContent());//reaper
});
}
textFinder
Cooper already showed how to do this with a loop that creates a TextFinder for value separately. To match all values in one go, use a regular expression, like this:
function test() {
const range = SpreadsheetApp.getActiveSheet().getDataRange();
const regexString = '\\?|PPS|LES|MPES|PSPEC';
const numCleared = clearMatchingCells_(range, regexString);
SpreadsheetApp.getActive().toast(`Cleared ${numCleared} cell(s).`);
}
/**
* Clears cells in a range that match a regular expression.
*
* #param {SpreadsheetApp.Range} range The range to search.
* #param {String} regexString The pattern to match with cells in range.
*/
function clearMatchingCells_(range, regexString) {
const matches = range
.createTextFinder(regexString)
.useRegularExpression(true)
.findAll();
matches.forEach(cell => cell.clearContent());
return matches.length;
}
Note that any regex special characters such as ? and * need to be double escaped in regexString.
As another approach, how about using replaceAllWith with TextFinder as follows?
Sample script:
function myFunction() {
const search = ["\\?", "PPS", "LES", "MPES", "PSPEC"];
const r = search.map(e => `.*${e}.*`).join("|");
SpreadsheetApp.getActiveSheet().getDataRange().createTextFinder(r).useRegularExpression(true).replaceAllWith("");
}
When this script is run, the cell values including search are replaced with "".
Reference:
replaceAllWith(replaceText)

Is there way start a loop in a certain date range

I have a sheet that is dynamically updating with leads from my marketing campaign. Currently, it has over 9K rows and will continue to grow.
I need to check values for Col F for leads that came in today; however, when I run a loop, it takes too long since it has 9k+ rows.
I want to run a loop for rows that have today's date only. Is there a way to have my script efficiently look for today's date first (without having to loop through 9k rows), and then start my loop?
Below is what I had originally. The code would start from the top of the sheet and look at Col F values and then email me if a cell had only "az-" instead of a full location value. Content below has been modified for privacy
function Google_Check_Lead_Values() {
var title = "Google | Leads"
var app = SpreadsheetApp;
var Def_url = ("website")
///EDIT ^ URL
var ss = app.openByUrl(Def_url).getSheetByName("Google | Leads");
var last_row = ss.getLastRow();
for (i = 1;i <=last_row; i++) {
var location = ss.getRange(i,6).getValue();
var location_len = location.length;
if (location_len <= 3){
MailApp.sendEmail({
to: "email1",
//cc: "email2",
subject: "Discrepancy found on " + title,
htmlBody:"Hi Team, <br>This is an automated notifcation to let you know that an issue was found on " + title + ". Please take a look at the sheet linked below: <br><br> email"
});//end of email
}//end of if
}//end of for
}//end of function
Try it like this:
function Google_Check_Lead_Values() {
const title = "Google | Leads"
const ss = SpreadsheetApp.openByUrl("url")
const sh = SpreadsheetApp.openByUrl(Def_url).getSheetByName(title);
const dt = new Date();
const dtv = new Date(dt.getFullYear(), dt.getMonth(), dt.getDate()).valueOf();
const vs = sh.getDataRange().getValues();
vs.forEach(r => {
let loc = r[5].toString();
let d = new Date(r[0]);
let dv = new Date(d.getFullYear(),d.getMonth(),d.getDate()).valueOf();
if( dv == dtv && loc.length < 4) {
MailApp.sendEmail({ to: "email1", subject: "Discrepancy found on " + title, htmlBody: "Hi Team, <br>This is an automated notifcation to let you know that an issue was found on " + title + ". Please take a look at the sheet linked below: <br><br> email", })
}
});
}
I believe your goal is as follows.
You want to reduce the process cost of the search of value from a large sheet.
You want to achieve this using Google Apps Script.
In your situation, by searching the values from the columns "A" and "F", you want to send emails.
In order to search the values from a sheet, there are several methods. Using for loop, TextFinder and query language. In my test, when the query language is used, the process cost was the lowest of these 3 patterns. So, in this answer, I would like to propose to search the values using use the query language. Ref
Sample script:
function Google_Check_Lead_Values() {
var title = "Google | Leads"
var Def_url = "###"; // Please use your Spreadsheet URL.
var ss = SpreadsheetApp.openByUrl(Def_url);
const spreadsheetId = ss.getId();
const today = new Date();
const tommorow = new Date();
tommorow.setDate(tommorow.getDate() + 1);
const vToday = Utilities.formatDate(today, Session.getScriptTimeZone(), "yyyy-MM-dd");
const vTommorow = Utilities.formatDate(tommorow, Session.getScriptTimeZone(), "yyyy-MM-dd");
const sheetName = "Google | Leads";
const query = `SELECT * WHERE A >= DATE '${vToday}' AND A < date '${vTommorow}' AND E = 'az-'`;
const url = `https://docs.google.com/spreadsheets/d/${spreadsheetId}/gviz/tq?sheet=${sheetName}&tqx=out:csv&tq=${query}`;
const res = UrlFetchApp.fetch(encodeURI(url), { headers: { authorization: "Bearer " + ScriptApp.getOAuthToken() } });
const [, ...values] = Utilities.parseCsv(res.getContentText());
if (values.length == 0) return;
values.forEach(_ => {
MailApp.sendEmail({
to: "email1",
//cc: "email2",
subject: "Discrepancy found on " + title,
htmlBody: "Hi Team, <br>This is an automated notifcation to let you know that an issue was found on " + title + ". Please take a look at the sheet linked below: <br><br> email"
});
});
}
When this script is run, the today date values are searched from the column "A", and also it searches whether the cell value of column "F" is the value of az-. When the values are found, the emaiil is sent. In this case, from your showing script, for example, when 2 rows are found, 2 emails are sent.
If you know the Spreadsheet ID, you can also directly use it to const spreadsheetId = ss.getId(); like const spreadsheetId = "###SpreadsheetID###";.
In this sample script, about the search of the column "F", it seaches whether the value is az-. But, if you want to search the length of cell value, please modify as follows.
From
const query = `SELECT * WHERE A >= DATE '${vToday}' AND A < date '${vTommorow}' AND E = 'az-'`;
To
const query = `SELECT * WHERE A >= DATE '${vToday}' AND A < date '${vTommorow}' AND E MATCHES '^.{0,3}$'`;
References:
Query Language Reference (Version 0.7)
Related thread.
https://stackoverflow.com/a/56663884

Cannot Read Property 'getSheetId' of null; Not sure why this happens

I have a the following snippet of code
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = ss.getSheets()[0];
var driverArray = sheet.getRange("H2:H33").getValues().flat().filter(r=>r!="");
var ssname = ss.getName();
var length = ssname.length;
var shName = sheet.getName();
var date = ssname.substring(0,length-15);
var scheduleDate = ss.getSheets()[7].getRange("G27").getValue(); //this contains a formula, but it evaluates to a date coinciding with the title of a sheet
const body = "Hello, <br><br>Attached is the pay stub for the week ending "+ date+"."+"<br><br> Thank you, <br> Elizabeth";
var arrayLength = driverArray.length;
var scheduleSheet = SpreadsheetApp.openById("SpreadsheetURL");
var scheduleSS = scheduleSheet.getId();
var nextSchedule = scheduleSheet.getSheetByName(scheduleDate);
var scheduleID = nextSchedule.getSheetId(); // I believe the error is coming here
I am trying to get the ID of a sheet on a different spreadsheet. I believe that I am navigating to that sheet correctly, but I get the error "cannot read property of 'getSheetId' of null". Does this mean that it did not find a sheet with the name?
G27 contains the formula
=(Leftb(Summary!$A$2,2)&"-"&Midb(Summary!$A$2,3,2)&"-"&rightb(Summary!$A$2,2))+7
but it evaluates to a date. And the format of the date matches correctly with the title of the sheet.
Instead of
var scheduleDate = ss.getSheets()[7].getRange("G27").getValue()
use
var scheduleDate = ss.getSheets()[7].getRange("G27").getDisplayValue()
The above because getValue() returns a Date object for cells holding a date value and usually the Date object is parsed as string in a long format rather than the usual date formats.

Extract subject and body text from Gmail messages and export to CSV

My current project is to take a set of emails from my gmail account and create a book from them, where each letter is a chapter.
I wrote up a Google Script snippet that successfully extracts the subject, date, and body text from all emails under a certain
label and writes them to a Google Document. This is not quite ideal, as I would prefer to ultimately have all this text in
markdown or LaTeX for formatting more carefully, but I was only familiar with how to to write to a Google Doc, based on the
Gmail API.
The fastest way for A to B for me would be to figure out how to alter this code so that it writes the text to a CSV file, containing
subject, date, and body columns. From there, I can process and parse it out into LaTeX and assign the necessary header styles and
formats there instead; however, I don't see much guidance on that file format in the API. Any guidance on how to adapt this script for
that purpose would be very welcome. Thanks.
function collectLetters() {
var fileName = 'OUTPUT_GOOGLE_DOC_FILENAME';
var labelName = 'MY_LABEL';
var timeZoneName = 'GMT'
var dateFormat = "dd | MM | yyyy"
var docBody;
var subject;
var date;
var body;
var message;
var num;
var datePar;
var bodyPar;
var subjectPar;
var numPar;
// get the handle for label
var label = GmailApp.getUserLabelByName(labelName);
var threads = label.getThreads();
// Create a new Google Doc
var doc = DocumentApp.create(fileName);
// get all the threads from label
for (var i = threads.length-1; i >= 0; i--) {
// EXTRACT FROM EMAIL: date, subject and body
message = threads[i].getMessages()[0];
subject = message.getSubject();
date = Utilities.formatDate(message.getDate(), timeZoneName, dateFormat)
body = message.getPlainBody().replace(/\r\n\r\n/gm,'aaaLINEBREAKERaaa').replace(/\r\n/gm,' ').replace(/ /gm,' ')
var splitBody = body.split('aaaLINEBREAKERaaa');
// APPEND TO GOOGLE DOC: Date (as Header)
datePar = doc.getBody().appendParagraph(date);
datePar.setHeading(DocumentApp.ParagraphHeading.HEADING1);
// APPEND TO GOOGLE DOC: Subject (as Subtitle)
if (subject.length > 0) {
subjectPar = doc.getBody().appendParagraph(subject);
}
else{
subjectPar = doc.getBody().appendParagraph("no subject");
}
subjectPar.setHeading(DocumentApp.ParagraphHeading.SUBTITLE);
// APPEND TO GOOGLE DOC: Body (as Normal)
docBody = doc.getBody()
splitBody.forEach(function (paragraphText) {
this.appendParagraph(paragraphText).setHeading(DocumentApp.ParagraphHeading.NORMAL);
}, docBody);
// Start a new page
doc.getBody().appendPageBreak();
//Logger.log(subject);
}
}

Google Apps Script - Dynamically Add Remove UiApp Form Elements

I am looking to create a Ui form section in my application that will Dynamically Add Remove UiApp Form Elements. I was trying to use the example from App Script Tutorials here
This example works great as far as performing the add remove elements, but when I use the submit button to capture the values, it submits as a JSON.stringify format. When I just want to capture the values only in a text or string format that will be added to a html email.
If there is way to convert JSON.stringify to text, string or get the values only in format, I will continue to use this example.
If not I was wonder if the following Javascript HTML code can be convert into GAS code and able to capture the values for each entry in a HTML email template to using in MailApp.
http://jsfiddle.net/g59K7/
Any suggestions, examples or adjustments to the codes would be greatly appreciated.
Thank you in advance
If you don't want the result to be in a JSON object, then you can adjust the _processSubmittedData(e) function. Right now he has it writing everything to an Object, which is fine. All you have to do is have a way to parse it:
function _processSubmittedData(e){
var result = {};
result.groupName = e.parameter.groupName;
var numMembers = parseInt(e.parameter.table_tag);
result.members = [];
//Member info array
for(var i=1; i<=numMembers; i++){
var member = {};
member.firstName = e.parameter['fName'+i];
member.lastName = e.parameter['lName'+i];
member.dateOfBirth = e.parameter['dob'+i];
member.note = e.parameter['note'+i];
result.members.push(member);
}
var htmlBody = 'Group Name: ' + result.groupName;
for(var a in result.members) {
var member = result.members[a];
var date = member.dateOfBirth;
var last = member.lastName;
var first = member.firstName;
var note = member.note;
htmlBody += first + ' ' + last + ' was born on ' + date + ' and has this note: ' + note;
}
MailApp.sendEmail('fakeEmail#fake.com',"Test Subject Line", "", {htmlBody: htmlBody});
}

Categories

Resources