I try to make a script for Google Sheets, to see what do the editors modify.
This is my script:
function onEdit() {
var sheet = SpreadsheetApp.getActiveSheet();
var email = Session.getActiveUser().getEmail();
Logger.log(email);
var User1 = email.indexOf("user1#email.com");
var User2 = email.indexOf("user2#email.com");
Logger.log(User1);
Logger.log(User2);
if (User1 = -1.0){
sheet.getActiveCell().setBackground('#f4cccc')}
if (User2 = -1.0){
sheet.getActiveCell().setBackground('#c9daf8')}
}
Log looks correct:
11:42:08 AM Notice Execution started
11:42:10 AM Info user1#email.com
11:42:10 AM Info 0.0
11:42:10 AM Info -1.0
11:42:09 AM Notice Execution completed
But User1 & 2 got the same color(c9daf8). So I missed something.
Try the below code:
You need to use getEffectiveUser() instead of getActiveUser()
function onEdit() {
var sheet = SpreadsheetApp.getActiveSpreadsheet().getActiveSheet();
var email = Session.getEffectiveUser().getEmail();
Logger.log(email);
var User1 = "user1#email.com";
var User2 ="user2#email.com";
if (email == User1){
sheet.getActiveCell().setBackground('#f4cccc');
}
if (email == User2) {
sheet.getActiveCell().setBackground('#c9daf8');}
}
Reference: getEffectiveUser()
In case if applicable for the particular data range:
function onEdit() {
var sheet = SpreadsheetApp.getActiveSpreadsheet().getActiveSheet();
var dataRng = sheet.getActiveCell().getColumn();
var email = Session.getEffectiveUser().getEmail();
Logger.log(email);
var User1 = "user1#gmail.com";
var User2 = "user2#gmail.com";
if (email == User1 && (dataRng == 2 || dataRng == 3) ){
sheet.getActiveCell().setBackground('#f4cccc');
}
if (email == User2 && (dataRng == 2 || dataRng == 3)){
sheet.getActiveCell().setBackground('#c9daf8');
}
}
Related
looking for some help with the function below. I'm trying to have it check if a file has been updated in Google Drive before running a import script. I have it down to checking if two dates/times match in a sheet, but I can't seem to get it to correctly register whether they match. It should either be when S3 <> T3 or when U3 = FALSE. Any help would be greatly appreciated!!
function syncCSVtransactions() {
var ss = SpreadsheetApp.getActiveSpreadsheet()
var sh = ss.getSheetByName("LOOKUP")
var cell_trnsnew = sh.getRange("S3");
var cell_trnsold = sh.getRange("T3");
var cell_trnscheck = sh.getRange("U3");
if( cell_trnsnew != cell_trnsold ){ //this is the line giving trouble
var source_file = DriveApp.getFilesByName("data_export.csv").next();
var csvData = Utilities.parseCsv(source_file.getBlob().getDataAsString());
var sheet2 = ss.getSheetByName('trs');
sheet2.getRange(1, 1, csvData.length, csvData[0].length).setValues(csvData);
cell_trnsnew.copyTo(cell_trnsold, {contentsOnly:true});
chartupdate();
} else {
}
}
I think that in your script, var cell_trnsnew = sh.getRange("S3");, var cell_trnsold = sh.getRange("T3"); and var cell_trnscheck = sh.getRange("U3"); can be written by one call. And, although I'm not sure about the values of your "LOOKUP" sheet, how about the following 2 patterns?
Pattern 1:
In this pattern, it supposes that the values of "S3", "T3" and "U3" are the date object, the date object and boolean, respectively.
From:
var cell_trnsnew = sh.getRange("S3");
var cell_trnsold = sh.getRange("T3");
var cell_trnscheck = sh.getRange("U3");
if( cell_trnsnew != cell_trnsold ){
To:
var [cell_trnsnew, cell_trnsold, cell_trnscheck] = sh.getRange("S3:U3").getValues()[0];
if (cell_trnsnew.getTime() != cell_trnsold.getTime() || cell_trnscheck === false) {
Pattern 2:
In this pattern, the values of "S3", "T3" and "U3" are used as the string values.
From:
var cell_trnsnew = sh.getRange("S3");
var cell_trnsold = sh.getRange("T3");
var cell_trnscheck = sh.getRange("U3");
if( cell_trnsnew != cell_trnsold ){
To:
var [cell_trnsnew, cell_trnsold, cell_trnscheck] = sh.getRange("S3:U3").getDisplayValues()[0];
if (cell_trnsnew != cell_trnsold || cell_trnscheck == "FALSE") {
References:
getValues()
getDisplayValues()
I used for Getting SMS of OTP and for list of SMS Cordova SMS plugin.
I got List of Smses but I want a Latest sms in my textbox and auto verify the OTP.
getSMS(sms)
{
if(window.SMS)window.SMS.listSMS({},data=>
{
setTimeout(()=>{console.log(data);
this.otp =data;
if(Array.isArray(this.otp)) {
for(let i in this.otp)
{
var msg = this.otp[i];
let msgaddress = msg.address;
let msgbody = msg.body;
var newValue = msgbody.slice(0,34);
if(msgaddress == "VK-POCKET" || msgaddress == "VM-POCKET" && newValue == "your pepocket registration otp is:")
{
var newVal = msgbody.substring(34,msgbody.length);
this.otpname=newVal;
}
}
}
},0 )
},error=>
{
console.log(error);
});
}
The query could not be run because the criteria for field '' contained an invalid arithmetic expression
Hi,
I faced some issue when i try to pass a value in Server Script and it keep come out with this error " doesnt support operator sbl-dat-00479". When i try to remove one of my value which is PRS Account No and it successfully come out. My value for PRS Account No = P-35971. Below is my server script.
function Print()
{
try
{
TheApplication().TraceOn("C:\\spool\\PRS SOA.txt", "Allocation", "All");
var Account = "";
var Year = "";
var Period = "";
var LPeriod = "";
var ContactID = "";
var Bookmark = "";
var ReportId = "";
var ReportName = "Customer Portal PRS Statement of Account";
//Active Field
this.BusComp().ActivateField("PRSAccountNo");
this.BusComp().ActivateField("Year2");
this.BusComp().ActivateField("Period2");
this.BusComp().ActivateField("LPeriod");
this.BusComp().ActivateField("CONTACT_ID");
//Get Account Row Id
Account = this.BusComp().GetFieldValue("PRSAccountNo");
Year = this.BusComp().GetFieldValue("Year2");
Period = this.BusComp().GetFieldValue("Period2");
LPeriod = this.BusComp().GetFieldValue("LPeriod");
ContactID = this.BusComp().GetFieldValue("CONTACT_ID");
//Construct Bookmark Query
Bookmark = "'cwa CustPortal PRS SOA Account'.Search = \"([PRS Account No] = '"+ Account +"') AND ([Year] = '"+ Year +"') AND ([Period] = '"+ LPeriod +"') AND ([CONTACT_ID] = '"+ ContactID +"')\"";
TheApplication().Trace("Bookmark: " + Bookmark);
//Retrieve Report Row Id
var boReport = TheApplication().GetBusObject("cwa CustPortal Report Administration");
var bcReport = boReport.GetBusComp("Report Standard Templates");
with(bcReport)
{
ActivateField("Report Name");
SetViewMode(AllView);
ClearToQuery();
SetSearchSpec("Report Name", ReportName);
ExecuteQuery(ForwardOnly);
if(FirstRecord())
{
ReportId = GetFieldValue("Id");
}
}
//Generate BIP Report
var GenReport = TheApplication().GetService("Workflow Process Manager");
var GenInput = TheApplication().NewPropertySet();
var GenOutput = TheApplication().NewPropertySet();
GenInput.SetProperty("ProcessName", "cwa CustPortal Generate BIP Report Workflow");
GenInput.SetProperty("Report Id", ReportId);
GenInput.SetProperty("Bookmark", Bookmark);
GenReport.InvokeMethod("RunProcess", GenInput, GenOutput);
var ErrMsg = GenOutput.GetProperty("Error Message");
if(ErrMsg == "")
{
//BIP Report successful generated, redirect to view report page
TheApplication().GotoView("cwa CustPortal PRS SOA Report View");
}
else
{
Popup(ErrMsg);
return(CancelOperation);
}
TheApplication().TraceOff();
}
catch(e)
{
Popup(e);
}
finally
{
}
}
Code looks ok, would be data issue or calc field logic error.
I think "Year2", "Period2" are Calculated fields & could be returning the special character ("/") leading to render the searchspec incorrectly.
I've been working to automatically pull data from an automated Gmail message. There are multiple daily emails that come through with the same label, so ideally I would like to loop through each email, and extract some of the data. I've set it up to use a few regex to grab the data, and it works for the first email. However, it won't loop correctly to find the next email with the label. Here is the code I have so far:
function parseEmailMessages (start) {
var label = GmailApp.getUserLabelByName("Bounce");
var threads = label.getThreads();
var sheet = SpreadsheetApp.getActiveSheet();
var tmp = [];
var messages = GmailApp.getMessagesForThreads(threads);
var bodies = [];
for (var i =0; i < threads.length; i++) {
var bodies = [];
for(k in threads[i].getMessages()) {
bodies.push(threads[i].getMessages()[i].getPlainBody());
var content = bodies.toString();
if (content) {
tmp = content.match(/[\n\r].*First Name\s*:\s*([^\n\r]*)/);
var firstname = (tmp && tmp[1]) ? tmp[1].trim() : 'No username';
tmp = content.match(/[\n\r].*Last Name\s*:\s*([^\n\r]*)/);
var lastname = (tmp && tmp[1]) ? tmp[1].trim() : 'No Lastname';
tmp = content.match(/[\n\r].*Customer ID\s*:\s*([^\n\r]*)/);
var customerID = (tmp) ? tmp[1].trim() : 'No CustomerID';
tmp = content.match(/[\n\r].*Invoice\s*:\s*([^\n\r]*)/);
var invoice = (tmp) ? tmp[1].trim() : 'No Invoice';
sheet.appendRow([firstname, lastname, customerID, invoice]);
Logger.log([firstname,lastname, customerID, invoice]);
}
}
}
};
It loops through correctly the first time, and then gives me an error: TypeError: Cannot call method "getPlainBody" of undefined.
Any help would be greatly appreciated!
You are seeing that error because you should use k variable in the for loop to get each message of that label. Check this line below:
threads[i].getMessages()[k].getPlainBody()
Tried changing this line in the for loop and its working for me.
Hope that helps!
After simplifying my code, I was able to get the script to loop correctly through my emails. This is the code that worked for me:
function processInboxToSheet() {
// Have to get data separate to avoid google app script limit!
//var start = 0;
var label = GmailApp.getUserLabelByName("Bounce");
var threads = label.getThreads();
var sheet = SpreadsheetApp.getActiveSheet();
var result = [];
var newLabel = GmailApp.getUserLabelByName("Done");
var oldLabel = GmailApp.getUserLabelByName("Bounce");
for (var i = 0; i < threads.length; i++) {
var messages = threads[i].getMessages();
var content = messages[0].getPlainBody();
// implement your own parsing rule inside
if (content) {
var tmp;
tmp = content.match(/[\n\r].*First Name\s*:\s*([^\n\r]*)/);
var firstname = (tmp && tmp[1]) ? tmp[1].trim() : 'No username';
tmp = content.match(/[\n\r].*Last Name\s*:\s*([^\n\r]*)/);
var lastname = (tmp && tmp[1]) ? tmp[1].trim() : 'No Lastname';
tmp = content.match(/[\n\r].*Customer ID\s*:\s*([^\n\r]*)/);
var customerID = (tmp) ? tmp[1].trim() : 'No CustomerID';
tmp = content.match(/[\n\r].*Invoice\s*:\s*([^\n\r]*)/);
var invoice = (tmp) ? tmp[1].trim() : 'No Invoice';
sheet.appendRow([firstname, lastname, customerID, invoice]);
}
Utilities.sleep(500);
threads[i].addLabel(newLabel).removeLabel(oldLabel).refresh();
}
};
I am trying to extract specific info from email in one of my labels in Gmail. I've hacked (my scripting knowledge is very limited) the following together based on a script from https://gist.github.com/Ferrari/9678772. I am getting an error though: "Cannot convert Array to Gmail Thread - Line 5"
Any help will be greatly appreciated.
/* Based on https://gist.github.com/Ferrari/9678772 */
function parseEmailMessages(start) {
/* var threads = GmailApp.getInboxThreads(start, 100); */
var threads = GmailApp.getMessagesForThread(GmailApp.search("label:labelname"));
var sheet = SpreadsheetApp.getActiveSheet();
var tmp, result = [];
for (var i = 0; i < threads.length; i++) {
// Get the first email message of a threads
var message = threads[i].getMessages()[0];
// Get the plain text body of the email message
// You may also use getRawContent() for parsing HTML
var content = messages[0].getPlainBody();
// Implement Parsing rules using regular expressions
if (content) {
tmp = content.match(/Name and Surname:\n([A-Za-z0-9\s]+)(\r?\n)/);
var username = (tmp && tmp[1]) ? tmp[1].trim() : 'No username';
tmp = content.match(/Phone Number:\n([\s\S]+)/);
var phone = (tmp && tmp[1]) ? tmp[1] : 'No phone';
tmp = content.match(/Email Address:\n([A-Za-z0-9#.]+)/);
var email = (tmp && tmp[1]) ? tmp[1].trim() : 'No email';
tmp = content.match(/Prefered contact office:\n([\s\S]+)/);
var comment = (tmp && tmp[1]) ? tmp[1] : 'No office';
sheet.appendRow([username, phone, email, comment]);
}
}
};
Thanks folks.. This did the trick:
// Adapted from https://gist.github.com/Ferrari/9678772
function processInboxToSheet() {
// Have to get data separate to avoid google app script limit!
var start = 0;
var label = GmailApp.getUserLabelByName("yourLabelName");
var threads = label.getThreads();
var sheet = SpreadsheetApp.getActiveSheet();
var result = [];
for (var i = 0; i < threads.length; i++) {
var messages = threads[i].getMessages();
var content = messages[0].getPlainBody();
// implement your own parsing rule inside
if (content) {
var tmp;
tmp = content.match(/Name and Surname:\n([A-Za-z0-9\s]+)(\r?\n)/);
var username = (tmp && tmp[1]) ? tmp[1].trim() : 'No username';
tmp = content.match(/Phone Number:\n([\s\S]+)/);
var phone = (tmp && tmp[1]) ? tmp[1] : 'No phone';
tmp = content.match(/Email Address:\n([A-Za-z0-9#.]+)/);
var email = (tmp && tmp[1]) ? tmp[1].trim() : 'No email';
tmp = content.match(/Prefered contact office:\n([\s\S]+)/);
var comment = (tmp && tmp[1]) ? tmp[1] : 'No office';
sheet.appendRow([username, phone, email, comment]);
Utilities.sleep(500);
}
}
};
var threads = GmailApp.getMessagesForThread(GmailApp.search("label:labelname"));
should include an array index since GmailApp.search returns an array, even if only one item is found.
var threads = GmailApp.getMessagesForThread(GmailApp.search("label:labelname")[0]);
would work but is wordy.
var thread_list = GmailApp.search("label:labelname");
var threads = GmailApp.getMessagesForThread(thread_list[0]);
IMO, the above is clearer in meaning.