I have pieced together a few different scripts to get this to work but I cant seem to get the code to put the data in correctly.
Email Input:
*Status:*
*Date:* 03/31/2020
*WorkOrder:* 123456-1
*DMSShipDate:* 03/31/2020
*PONumber:* 8675309
*Company:* Test
Script
var ui = SpreadsheetApp.getUi();
function onOpen(e){
ui.createMenu("Import Email").addItem("Import Email", "getGmailEmails").addToUi();
}
function getGmailEmails(){
if (Session.getActiveUser().getEmail() != "email#gmail.com"){
Browser.msgBox("Please log in as email#gmail.com");
return;
}
var label = GmailApp.getUserLabelByName("ImportMe");
var threads = label.getThreads();
for(var i = threads.length - 1; i >=0; i--){
var messages = threads[i].getMessages();
for (var j = 0; j <messages.length; j++){
var message = messages[j];
extractDetails(message);
GmailApp.markMessageRead(message);
}
threads[i].removeLabel(label);
}
}
function extractDetails(message){
var bodyContents = message.getPlainBody();
var status = bodyContents.match(/\*Status:\*(.*) /);
var dateEntered = bodyContents.match(/\*Date:\*(.*) /);
var workOrder = bodyContents.match(/\*WorkOrder:\*(.*) /);
var dmsShipDate = bodyContents.match(/\*DMSShipDate:\*(.*) /);
var poNum = bodyContents.match(/\*PONumber:\*(.*) /);
var company = bodyContents.match(/\*Company:\*(.*) /);
var activeSheet = SpreadsheetApp.getActiveSheet();
activeSheet.appendRow([status, dateEntered, workOrder, dmsShipDate, poNum, company]);
}
Result:
I get the following in each column:
[Ljava.lang.Object;#488e1851, [Ljava.lang.Object;#5c588720, etc, etc
I have tried JSON.Stringify and toString() but nothing seems to be able to get the data into the column correctly.
String.match returns a array. To get the captured group, index into that array:
bodyContents.match(/\*Status:\*(.*) /)[1];
Related
So i'm writing a script to automatically collect emails to a Google spreadsheet. I would like from this email to extract some details like the email address, the name, the address, the phone number. So far i managed to extract the date, the subject, the sender details and the body contents. Below i'll attach the email body and also the code i've written so far! If you have contact me directly at this emails.
This a code i've tried so far:
function onOpen(e) {
var ui = SpreadsheetApp.getUi();
ui.createMenu("KingBoss Menu").addItem("Get Emails", "getGmailEmails").addToUi();
}
function getGmailEmails() {
var label = GmailApp.getUserLabelByName("warranty");
var threads = label.getThreads();
for(var i = threads.length - 1; i >=0; i--) {
var messages = threads[i].getMessages();
for (var j = 0; j <messages.length; j++) {
var message = messages[j];
extractDetails(message);
GmailApp.markMessageRead(message);
}
}
}
function extractDetails(message) {
var dateTime = message.getDate();
var subjectText = message.getSubject();
var senderDetails = message.getFrom();
var bodyContents = message.getPlainBody();
var activeSheet = SpreadsheetApp.getActiveSpreadsheet().getActiveSheet();
activeSheet.appendRow([dateTime, senderDetails, subjectText, bodyContents]);
}
Hi sorry this is probably a very newbie question, I am teaching myself and can't figure out how to google the answer to this one.
I have a loop in google sheets that goes through each field and updates some cells which pull info from a website that I then need to copy across into each row of the loop. It seems to be working through the loop okay however when trying to copy i cant get it into the correct row.
Im sure its something very simple hoping someone out there can point me in the right direction. I'm pretty sure its to do with the code at line 34 but can't figure out how to correct it.
function myLoop() {
var ui = SpreadsheetApp.getUi();
var ss = SpreadsheetApp.getActiveSpreadsheet();
var Lsheet = ss.setActiveSheet(ss.getSheetByName('Loop'), true);
var rangeData = Lsheet.getDataRange();
var lastColumn = rangeData.getLastColumn();
var lastRow = rangeData.getLastRow();
var dataRange = Lsheet.getRange(2,1, lastRow-1, lastColumn-1);
var data = dataRange.getValues();
var len = data.length;
var i = 0
for (i; i < len; i++) {
var row = data[i];
var player = row[4]
var prop = row[6]
var number = row[7]
var overodds = row[8]
var underodds = row[9]
var overreq = row[10]
var underreq = row[11];
if(prop = "Points"){
ss.setActiveSheet(ss.getSheetByName('Stats'), true);
ss.getRange('B1').activate();
ss.getRange("B1").setValue(player);
ss.getRange('AB5').activate();
ss.setActiveSheet(ss.getSheetByName('Loop'), true);
ss.getRange(overreq).activate();
ss.getRange('Stats!AB5').copyTo(ss.getActiveRange(), SpreadsheetApp.CopyPasteType.PASTE_VALUES, false);
ss.setActiveSheet(ss.getSheetByName('Stats'), true);
ss.getRange('AB6').activate();
ss.setActiveSheet(ss.getSheetByName('Loop'), true);
ss.getRange(underreq).activate();
ss.getRange('Stats!AB6').copyTo(ss.getActiveRange(), SpreadsheetApp.CopyPasteType.PASTE_VALUES, false);
}
}
}
Modifications of the original code:
Corrected an error in line 24. In your original post, you are using = (assignment operator) to compare your variables. However, you want to use == (equality operator).
Added missing semicolons. Although not necessary, makes for good, consistent style and may prevent some errors.
Moved i declaration inside the for-loop. Makes for cleaner, safer code.
Modified for-loop body so that it uses ranges and setValue(), getValue() methods to copy data.
function myLoop() {
var ui = SpreadsheetApp.getUi();
var ss = SpreadsheetApp.getActiveSpreadsheet();
var Lsheet = ss.setActiveSheet(ss.getSheetByName('Loop'), true);
var rangeData = Lsheet.getDataRange();
var lastColumn = rangeData.getLastColumn();
var lastRow = rangeData.getLastRow();
var dataRange = Lsheet.getRange(2,1, lastRow-1, lastColumn-1);
var data = dataRange.getValues();
var len = data.length;
var statsSheet = ss.getSheetByName('Stats');
var loopSheet = ss.getSheetByName('Loop');
for (var i = 0; i < len; i++) {
var row = data[i];
var player = row[4];
var prop = row[6];
var number = row[7];
var overodds = row[8];
var underodds = row[9];
var overreq = row[10];
var underreq = row[11];
if (prop == "Points") {
statsSheet.getRange('B1').setValue(player);
loopSheet.getRange(overreq).setValues(
statsSheet.getRange('AB5').getValues()
);
loopSheet.getRange(underreq).setValues(
statsSheet.getRange('AB6').getValues()
);
}
}
}
Could you try this:
var currentRow = ss.getActiveRange().getRow();
var currentCol = ss.getActiveRange().getColumn();
.
.
.
ss.getRange('State!AB5').copyTo(ss.getRange(currentRow+1, currentCol),
SpreadsheetApp.CopyPasteType.PASTE_VALUES, false);
I'm using google app scripts to extract e-mail data into a google spreadsheet. I've got the below working code that I am trying to modify. I'm sure there's a smarter way ... but for now this works
function emf() {
var ss = SpreadsheetApp.getActiveSheet();
var label = GmailApp.getUserLabelByName("tkh_emf");
var threads = label.getThreads();
for (var i=0; i<threads.length; i++)
{
var messages = threads[i].getMessages();
for (var j=0; j<messages.length; j++)
{
var name = messages[j].getPlainBody().split("Name*:")[1].split("\n")[0];
var email = messages[j].getPlainBody().split("E-mail*:")[1].split("\n")[0];
var phone = messages[j].getPlainBody().split("Phone:")[1].split("\n")[0];
var addr = messages[j].getPlainBody().split("Street Address:")[1].split("\n")[0];
var city = messages[j].getPlainBody().split("City*:")[1].split("\n")[0];
var find = messages[j].getPlainBody().split("hear about us?*:")[1].split("\n")[0];
var sub = messages[j].getSubject().split("Feedback via the ")[1].split("[")[0];
var num = messages[j].getSubject().split("Feedback via the ")[1].split("[")[1].split("]")[0];
var dat = messages[j].getDate();
var referrer = messages[j].getPlainBody().split("Referer URL:")[1].split("\n")[0];
ss.appendRow([name, email, phone, addr, city, find, sub, num, dat, referrer])
}
threads[i].removeLabel(label);
}
}
My e-mail looks like this:
Name*: name
E-mail*: email#gmail.com
Phone:
Street Address: 3704 17th St.
City*: city
How did you hear about us?*: Search engine results
Brief description of work requested*: work here
So my code extracts the appropriate strings for each field except the 'Phone' and 'Address' fields which are not required. If these fields are not filled, then the e-mail does not have the words 'Phone' or 'Street Address' so the lines for var phone and var addr fail because you can't split a null. Is there a way to insert an if string 'Phone' and 'Street Address' exists then execute the above? Thanks.
You were right that you'll need regex to accomplish the job (or it'll certainly make it easier). I've written a simple script in Codepen that'll show you how to use the regex.
In my script, I split the body data at the newline character, and then loop through the resulting array of lines. I pipe each line into a function that captures and returns the text you need. You needn't pipe in anything other the line--it detects what the name of the field is, and uses it appropriately, based on your current format.
In your own code, you would have to do the following to msg before placing it into your spreadsheet:
var msg = messages[j].getPlainBody();
var sub = messages[j].getSubject();
var dat = messages[j].getDate();
var bodyLines = msg.split("\n");
var fields = [];
for (var k = 0; k < bodyLines.length; k++) {
fields.push(getText(bodyLines[k]));
}
// do something with the resulting array of fields here
Here's the getText(str) function (can also be found in Codepen):
function getText(str) {
var fieldRe = new RegExp("(.+)\:", "g");
var fieldGroups = fieldRe.exec(str);
var fieldName = fieldGroups[1].split("*")[0];
fieldName = (fieldName == null) ? fieldGroups[1] : fieldName;
fieldName = fieldName.replace(/[\!\#\#\$\%\^\&\*\(\)\-\_\+\=\`\~\[\]\{\}\\\/\|\:\;\'\"\<\>\,\.\?]/g, function transformIllegal(x) {
return "\\" + x;
});
var re = new RegExp(`${fieldName}\\*?\\:\\s+(.*)`, "g");
var groups = re.exec(str);
var out = (groups == null) ? "" : groups[1];
return out;
}
Here's what I'm ending with. Not sophisticated but works.
function emf() {
var ss = SpreadsheetApp.getActiveSheet();
var label = GmailApp.getUserLabelByName("tkh_emf");
var threads = label.getThreads();
for (var i=0; i<threads.length; i++)
{
var messages = threads[i].getMessages();
for (var j=0; j<messages.length; j++)
{
var name = messages[j].getPlainBody().split("Name*:")[1].split("\n")[0];
var email = messages[j].getPlainBody().split("E-mail*:")[1].split("\n")[0];
try {var phone = messages[j].getPlainBody().split("Phone:")[1].split("\n")[0];}
catch(e){var phone = "-";}
try {var addr = messages[j].getPlainBody().split("Street Address:")[1].split("\n")[0];}
catch(e){var addr = "-";}
var city = messages[j].getPlainBody().split("City*:")[1].split("\n")[0];
var find = messages[j].getPlainBody().split("hear about us?*:")[1].split("\n")[0];
try {var referrer = messages[j].getPlainBody().split("Referrer Name:")[1].split("\n")[0];}
catch(e){var referrer = "-";}
var sub = messages[j].getSubject().split("Feedback via the ")[1].split("[")[0];
var num = messages[j].getSubject().split("Feedback via the ")[1].split("[")[1].split("]")[0];
var dat = messages[j].getDate();
ss.appendRow([name, email, phone, addr, city, find, referrer, sub, num, dat])
}
threads[i].removeLabel(label);
}
}
I have the column "D" in my spreadsheet. I would like to get all objects in the column and send an email to them. My script gets the firts user in the column and then loops it, it dosen't continue.
This i what i have:
function email(){
var ss = SpreadsheetApp.getActiveSpreadsheet();
var dataSheet = ss.getSheets()[0];
var email = dataSheet.getRange(2, 5);
var email2 = email.getValue();
for (var i = 0; i < email2.length; ++i) {
// Get a row object
var rowData = email2[i];
MailApp.sendEmail(rowData emailSubject, emailText);
Logger.log(email2);
}
}
you selected only one cell, so you are making a loop in a single element...
try this way :
function email(){
var ss = SpreadsheetApp.getActiveSpreadsheet();
var dataSheet = ss.getSheets()[0];
var emails = dataSheet.getRange('D2:D').getValues();
for (var i = 0; i < emails.length; ++i) {
// Get a row object
var rowData = emails[i][0];
if(rowData!=''){
MailApp.sendEmail(rowData emailSubject, emailText);// I assume emailSubject and emailText are defined in your real code...
}
Logger.log(emails[i]);
}
}
I am using jGFeed to parse an RSS Feed, my code for which is below:
$.jGFeed('http://feeds.bbci.co.uk/news/rss.xml',
function(feeds){
// Check for errors
if(!feeds){
// there was an error
return false;
}
// do whatever you want with feeds here
$('#newsTimeline').empty();
for(var i=0; i<feeds.entries.length; i++){
var entry = feeds.entries[i];
var title = entry.title;
var description = entry.description;
var linkUrl = entry.link_url;
var date = getDate(entry.pubDate);
var time = getTime(entry.pubDate);
$('#newsTimeline').append('<li><time class="cbp_tmtime" datetime="'+date+' '+time+'"><span>'+date+'</span> <span>'+time+'</span></time><div class="cbp_tmicon cbp_tmicon-phone"></div><div class="cbp_tmlabel"><h2>'+title+'</h2><p>'+description+'</p></div></li>');
}
}, 10);
The problem is that it is working for entry.title, but nothing after that works:
NOTE: No errors are logged in the Javascript Console.
Try this
for(var i=0;i<feeds.entries.length;i++){
var entry = feeds.entries[i];
var title = entry.title;
var linkUrl= entry.link;
var description = entry.contentSnippet;
var date = entry.publishedDate;
$('#newsTimeline').append('<li><time class="cbp_tmtime" datetime="'+date+' '+time+'"><span>'+date+'</span> <span>'+time+'</span></time><div class="cbp_tmicon cbp_tmicon-phone"></div><div class="cbp_tmlabel"><h2>'+title+'</h2><p>'+description+'</p></div></li>');
}