Why is Google Group exporting members not giving me an accurate number? - google-groups

I used this script to export the email addresses from my group, and that gets me 8815 results. But on my group's page, the total number of members is 13,000+ (according to the counter in the top right corner, in member view). Why is there a difference?
function listGroupMembers() {
var GROUP_EMAIL = "mygroupsname#googlegroups.com";
var group = GroupsApp.getGroupByEmail(GROUP_EMAIL);
var users = group.getUsers();
var s = "Group " + GROUP_EMAIL + " has " + users.length +
" members: ";
for (var i = 0; i < users.length; i++) {
var user = users[i];
s = s + user.getEmail() + ", ";
}
var doc = DocumentApp.create('group emails');
doc.getBody().appendParagraph(s);
}

Related

google sheets script regarding sending emails

I'd presume this would be an easy solve but I've been unable to find a solution anywhere online.
I'm trying to send automated emails when I run a script. The problem is it will send one email for every row (multiple emails to the same person) instead of sending one email with every row/column included in that one email.
The second issue is I want to send to more than one recipient. In my sheet, I want to send the data in B2:F3 to the first email address and then I want to send B4:F5 to the second email provided.
Thank you for your help. - Jared
Here's my script:
function sendEmails() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
ss.setActiveSheet(ss.getSheetByName("sheet1"));
var sheet = SpreadsheetApp.getActiveSheet();
var dataRange = sheet.getRange("A2:m8");
var data = dataRange.getValues();
for (i in data) {
var rowData = data[i];
var emailAddress = rowData[0];
var city = rowData[11];
var dimension = rowData[1];
var product = rowData[2];
var tally = rowData[3];
var price = rowData[5];
var ship = rowData[5];
var message = city + '\n\n' + dimension + ' ' + product + ' ' + tally + ' ' + price + ' ' + ship;
var subject = 'PFP Lumber';
MailApp.sendEmail("emailaddress1#blank.com",
"PFP Lumber",
message);
}
}
From your shared sample sheet and script, there are some questions.
It seems that price and ship are rowData[5].
price and ship are rowData[4] and rowData[5], respectively?
It seems that rowData[11] is Phone.
Is this rowData[6]?
If price, ship and Phone are rowData[4], rowData[5] and rowData[6], respectively, you want to send the following emails.
Mail 1 :
mailaddress: emailaddress1#blank.com
message: Gulfport desc1 1 1 1 1, Gulfport desc2 2 2 2 2
Mail 2 :
mailaddress: emailaddress2#blank.com
message: Gulfport desc3 3 3 3 3, Gulfport desc4 4 4 4 4
If my understanding is correct, how about this modification? I think that there are several answers for your situation, so please think of this as one of them.
Modification points :
Retrieve email address and messages.
When new email address was NOT found at column A, the message is added.
When new email address was found at column A, the email is separated.
Modified script :
function sendEmails() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
ss.setActiveSheet(ss.getSheetByName("sheet1"));
var sheet = SpreadsheetApp.getActiveSheet();
var dataRange = sheet.getRange("A2:m8");
var data = dataRange.getValues();
// Modified
var temp = [];
var emailAddress, dimension, product, tally, price, ship, city;
for (var i in data) {
[emailAddress, dimension, product, tally, price, ship, city] = data[i];
var message = city + '\n\n' + dimension + ' ' + product + ' ' + tally + ' ' + price + ' ' + ship;
if (emailAddress || !dimension) {
if (temp.length > 0) {
MailApp.sendEmail(temp[0], "PFP Lumber", temp.slice(1,temp.length).join("\n"));
var temp = [];
}
temp.push(emailAddress, message);
if (!dimension) break;
} else {
temp.push(message);
}
}
}
Note :
Several messages for one mail address is separated by \n.
Because I'm not sure the variables for each columns that you want to use, please modify them if the variables of my modified script is difference from you want.
In this modified script, after the rows that Dimension of column B is empty, I recognized that there are no emails you want to send.
If I misunderstand your question, I'm sorry.
Edit :
When you want to add a signature, how about this script?
function sendEmails() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
ss.setActiveSheet(ss.getSheetByName("sheet1"));
var sheet = SpreadsheetApp.getActiveSheet();
var dataRange = sheet.getRange("A2:m8");
var data = dataRange.getValues();
var temp = [];
var emailAddress, dimension, product, tally, price, ship, city;
var signature = "\n---\nsample signature";
for (var i in data) {
[emailAddress, dimension, product, tally, price, ship, city] = data[i];
var message = city + '\n\n' + dimension + ' ' + product + ' ' + tally + ' ' + price + ' ' + ship;
if (emailAddress || !dimension) {
if (temp.length > 0) {
MailApp.sendEmail(temp[0], "PFP Lumber", temp.slice(1,temp.length).join("\n") + signature);
var temp = [];
}
temp.push(emailAddress, message);
if (!dimension) break;
} else {
temp.push(message);
}
}
}

Email Google Sheet cells and format

Background: I am a teacher. I gave a test through Forms. I graded the test by using various background colors on each cell (which represented an answer to a question by a student). Each row of the sheet has their email address in Column B.
Problem: I would like to email the entire row, including formatting, to that address in Column B so that each student has a record of their answers and how I graded them.
Question: How can I email a row of data, including formatting?
I am working with the following script, which works well for emailing a single cell without formatting:
`function sendEmails() {
var sheet = SpreadsheetApp.getActiveSheet();
var startRow = 2; // First row of data to process
var numRows = 1; // Number of rows to process
// Fetch the range of cells A2:B3
var dataRange = sheet.getRange(startRow, 1, numRows, 2)
// Fetch values for each row in the Range.
var data = dataRange.getValues();
for (i in data) {
var row = data[i];
var emailAddress = row[1]; // Second column
var message = row[0]; // I want the whole row, including formatting.
var subject = "Sending emails from a Spreadsheet";
MailApp.sendEmail(emailAddress, subject, message);
ContentService.createTextOutput("hello world!");
}
}`
Here it is.
I decided to add another function as it makes it a little cleaner. You'll be able to adjust the styles of the output by playing with the css styles. If you keep the commented lines your can use them for debugging. I tested the code with them and it looks good. So let me know how it works on the emails.
function sendEmails()
{
var br='<br />';
var sheet=SpreadsheetApp.getActiveSheet();
var dataRange=sheet.getDataRange();
var dataA=dataRange.getValues();
var backA=dataRange.getBackgrounds();
//var s='';//Please leave the commented lines. If needed for the future they are handy to have
for (var i=1;i<dataA.length;i++)
{
var emailAddress=dataA[i][1];
var message=formatRow(sheet.getName(),dataA[i],backA[i],dataA[0]);
var subject="Sending emails from a Spreadsheet";
//s+=br + '<strong>EmailAddress:</strong>' + emailAddress + br + '<strong>Subject:</strong>' + subject + br + message + '**************************************' + br;
MailApp.sendEmail({to:emailAddress,subject:subject,htmlBody:message});
}
//var userInterface=HtmlService.createHtmlOutput(s);
//SpreadsheetApp.getUi().showModelessDialog(userInterface, 'Email Message')
}
I just noticed the yellow background so I quickly added another section for it.
//assume Timestamp,EmailAddres,Score,FirstName,LastName,Section...
function formatRow(sheetName,rowA,rowbackA,titleA)
{
var br='<br />';
var ss=SpreadsheetApp.getActive();
var sh=ss.getSheetByName(sheetName);
var html='';
if(rowA && rowbackA)
{
html='';
for(var j=0;j<rowA.length;j++)
{
switch(rowbackA[j])
{
case '#ff0000':
html+=br + '<span style="font-weight:600;font-size:20px;">' + titleA[j] + ':</span>' + br + '<span style="background-color:#ff0000;">' + rowA[j] + '</span>' + br;
break;
case '#ffff00':
html+=br + '<span style="font-weight:600;font-size:20px;">' + titleA[j] + ':</span>' + br + '<span style="background-color:#ffff00;">' + rowA[j] + '</span>' + br;
break;
case '#ffffff':
html+=br + '<span style="font-weight:600;font-size:20px;">' + titleA[j] + ':</span>' + br + '<span style="background-color:#ffffff;">' + rowA[j] + '</span>' + br;
break
}
}
}
return html;
}
Just a reminder I'm using #ff0000 for red so don't change to a different shade without making a change to the code.
In the event that one student's email gets eaten by the dog, you might like to send just one email.
function sendOneEmail(firstName,lastName)
{
if(firstName && lastName)
{
var br='<br />';
var sheet=SpreadsheetApp.getActiveSheet();
var dataRange=sheet.getDataRange();
var dataA=dataRange.getValues();
var backA=dataRange.getBackgrounds();
//var s='';//Please leave the commented lines. If needed for the future they are handy to have
for (var i=1;i<dataA.length;i++)
{
if(firstName==dataA[i][3] && lastName==dataA[i][4])
{
var emailAddress=dataA[i][1];
var message=formatRow(sheet.getName(),dataA[i],backA[i],dataA[0]);
var subject="Sending emails from a Spreadsheet";
//s+=br + '<strong>EmailAddress:</strong>' + emailAddress + br + '<strong>Subject:</strong>' + subject + br + message + '**************************************' + br;
MailApp.sendEmail({to:emailAddress,subject:subject,htmlBody:message});
}
}
//var userInterface=HtmlService.createHtmlOutput(s);
//SpreadsheetApp.getUi().showModelessDialog(userInterface, 'Email Message')
}
}
Here's a birds eye view of the Spreadsheet.

Google maps downloadUrl does not return 200

My code is based on the example of google code:
https://developers.google.com/maps/articles/phpsqlinfo_v3
and was working fine.
I need to change a former 'gid' (Integer) field to 'id' (String) to get saved to the database and used to display a new labeled symbol on the map.
The strange thing is, that the url, that is build in the code to call the addrow.php file is OK. When I capture this string with alert(url), and I manually use this string, the new data is added to the database.
In my script, the call seems to fail (responseCode == 200 && data.length <=1), since no data is written to the database and the alert from the 'else-clause' is displayed as short pop-up.
Here's the code I use in my project (to save data from a form):
//save new marker to Postgis-database and add new markerwithlabel on the fly
function saveData(){
var gender = escape(document.getElementById("gender").value);
var hoehe = InZahl(document.getElementById("hoehe").value);
var breite = InZahl(document.getElementById("breite").value);
var id = escape(document.getElementById("id").value);
var vital = document.getElementById("vital").value;
var typ = document.getElementById("typ").value;
var ein_mehr = document.getElementById("ein_mehr").value;
var st_durchm = document.getElementById("st_durchm").value;
var frucht = document.getElementById("frucht").value;
var anmerk = document.getElementById("anmerk").value;
var latlng = marker.getPosition();
var url = "./mapdata/addrow.php?gender=" + gender +
"&hoehe=" + hoehe + "&lat=" + latlng.lat() + "&lng=" + latlng.lng() +
"&breite=" + breite + "&id=" + id + "&typ=" + typ + "&ein_mehr=" +ein_mehr + "&st_durchm=" + st_durchm +
"&frucht=" + frucht +
"&vital=" + vital + "&anmerk=" + anmerk;
downloadUrl(url, function (data, responseCode) {
if (responseCode == 200 && data.length <=1) {
infowindow.close();
marker.setDraggable(false);
marker.setIcon('./images/mm_purple.png');
marker.labelContent = id;
marker.setMap(map);
downloadUrl("./mapdata/getxml_get_last.php", function (data1) {
var xml = parseXml(data1);
var ms = xml.documentElement.getElementsByTagName("m");
var gid = ms[0].getAttribute("gid");
var html_n = "<div id='InfoWindow'><p style='font-weight:bold;'>" + id + "</p> \n\<p>Höhe:" + hoehe + " Breite: "+ breite +
"<br />\n\Typ: "+typ+" Stämme: "+ein_mehr+" St-Durchm: "+ st_durchm + "<br />\n\Vitalität: "+vital+" Fruchtbehang: "+frucht+
"<p/>\n\<p style='text-align:right;'><a href='sm_juniperus.php?operation=ssearch&ResetFilter=0&SearchField=gid&FilterType=%3D&FilterText="+ gid +
"' target='_blank'> Daten editieren </a></p></div>";
infowindow.setContent(html_n);
bindInfoWindow(marker, map, infowindow, html_n);
(function(i, marker, gid) {
var origIcon = marker.getIcon();
new LongPress(marker, 1000);
google.maps.event.addListener(marker, 'longpress', function(e) {
marker.setDraggable(true);
marker.setIcon(mmcross);
});
google.maps.event.addListener(marker, 'dragend', function(){
updatePosition(marker, gid);
marker.setIcon(origIcon);
});
})(i,marker,gid);
//add new marker to markerCluster-Array and to markerArray
markerCluster.addMarker(marker,false);
markerArray.push(marker);
i++;
}); // End add new marker
}
else {
alert("Your data couldn't be saved!");
}
}); // End downloadUrl
}; // END saveData()
As I said, my code worked fine, but after 3 evenings passed to solve this, I thought it would be time to ask for help.
If anybody has an idea, where the mistake lies, I would apreciate any hint.
Just to confirm, you're aware that you by doing
if (responseCode == 200 && data.length <=1) {
you are saying 'if the request is successful and the data it returns is only one character or below in length'? I am unsure if this is intended or not, because this way the code inside the if statement is only ran if the response is successful but contains only 1 or 0 characters.

Google Apps Script: How to pull values from column A based on values in column E and send all values in one email?

I'm trying to create a script for a student attendance spreadsheet that will look in Column E for the string "X". For each instance of "X", the string from column A (the student name) will be added to the body of an email. I'm pretty new to JavaScript, although I have been studying the basics. I've done a lot of research and found some scripts I was able to modify to send an individual email for each instance of X in E. However, I have not been able to figure out how to combine that information into a single email.
Here's what I have so far:
function Email_ReminderNS() {
var sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("July_August"),
EMAIL_SENT = "EMAIL_SENT",
statusArray = sheet.getDataRange().getValues();
var class = statusArray[0][8],
status = "X",
email = "XXXX"
for (i=7;i < statusArray.length;i++){
var emailSent = statusArray[i][84];
if (status == statusArray[i][4] & emailSent != EMAIL_SENT) {
var student = statusArray[i][0];
var body = "This is a No-Show Report for " +student+ " from " + class;
var subject = "No-Show Report for " + student+ " from " + class;
MailApp.sendEmail(email,subject,body,{NoReply : true});
sheet.getRange(i+1, 85).setValue(EMAIL_SENT);
SpreadsheetApp.flush();
}
}
}
I realize I'll probably need to move the sendEmail function to be outside the IF statement. I tried to create an array with the names and join those into a string and add it to the body of the email, but I've had no luck. It just ended up sending the last name instead of all of them.
If anyone has any suggestions for me I would be deeply grateful.
First set up variables to keep track of which student did not show up:
var students = [];
var student_rows = [];
Then, add student to these arrays when X is found:
if (status == statusArray[i][4] & emailSent != EMAIL_SENT) {
var student = statusArray[i][0];
students.push(student);
student_rows.push(i+1);
}
Then send the email with all student names combined (outside of the for loop like you said)
var body = "This is a No-Show Report for " + students.join(', ') + " from " + class;
var subject = "No-Show Report for " + students.join(', ') + " from " + class;
MailApp.sendEmail(email,subject,body,{NoReply : true});
Finally update the spreadsheet indicating which names were in that email:
for (var i=0; i<student_rows.length; i++) {
sheet.getRange(student_rows[i], 85).setValue(EMAIL_SENT);
SpreadsheetApp.flush();
}
Here's the complete script:
function Email_ReminderNS() {
var sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("July_August"),
EMAIL_SENT = "EMAIL_SENT",
statusArray = sheet.getDataRange().getValues();
var class = statusArray[0][8],
status = "X",
email = "francis#bposolutions.com";
var students = [];
var student_rows = [];
for (i=7;i < statusArray.length;i++){
var emailSent = statusArray[i][84];
if (status == statusArray[i][4] & emailSent != EMAIL_SENT) {
var student = statusArray[i][0];
students.push(student);
student_rows.push(i+1);
}
}
var body = "This is a No-Show Report for " + students.join(', ') + " from " + class;
var subject = "No-Show Report for " + students.join(', ') + " from " + class;
MailApp.sendEmail(email,subject,body,{NoReply : true});
for (var i=0; i<student_rows.length; i++) {
sheet.getRange(student_rows[i], 85).setValue(EMAIL_SENT);
SpreadsheetApp.flush();
}
}
There are probably many ways to implement a new version of your code, the other answer probably works but I think it can be improved (a bit).
First of all, you can get rid of the flush method that does nothing else than slowing down the function (it was originally used in the Google example to check the sent status row by row, it is useless when we send only one mail with all the data in it)
Secondly, it might be a good idea to use html format to get a better looking result.
And lastly, it is good practice to write back to the sheet using one setValues instead of multiple setValue() in a loop.
Here is a possible replacement code, you'll have to "tune" it to your needs to eventually improve the message format but the main structure is there and working.
function Email_ReminderNS() {
var sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("July_August"),
statusArray = sheet.getDataRange().getValues();
var email = Session.getActiveUser().getEmail(); //replace with the email you want, this value will send mails to you I used it for test.
var class = statusArray[0][8],
status = "X",
students = [];
for (var i=7;i < statusArray.length; i++){
var emailSent = statusArray[i][84];
if (status == statusArray[i][4] & emailSent != "EMAIL_SENT") {
students.push(statusArray[i][0]);
statusArray[i][84]="EMAIL_SENT";
}
}
var subject = "No-Show Report for " + students.length + " from " + class;
var textBody = "This is a No-Show Report for " +students.length+ " from " + class+"\n";
var HTMLBody = "<b>This is a No-Show Report for " +students.length+ " from " + class+"</b><br><br>"
+'<table style="background-color:lightblue;border-collapse:collapse;" border = 1 cellpadding = 5><th>Sent Mails</th><tr>';
for(var n in students){
HTMLBody += '<tr><td>'+n+'</td><td>'+statusArray[n][0]+'</td></tr>';
textBody += '\n'+n+' - '+statusArray[n][0];
}
HTMLBody+='</table><BR> kind regards.' ;
textBody+='\n\nKind regards';
Logger.log(HTMLBody);
Logger.log(textBody);
MailApp.sendEmail(email,subject,textBody,{'NoReply' : true, 'htmlBody' : HTMLBody});
sheet.getRange(1,1,statusArray.length,statusArray[0].length).setValues(statusArray);
}

Can I send SSRS custom subscription e-mails?

I need to send some e-mails containing a SSRS report to a list of persons, representing the amount of work items they have left until a certain date.
What I would like to do is to send each person in the list, the customized report that reflects his progress, so my question is: can I send different reports to the persons in the list (like sending it's e-mail address as a parameter to the report), or can I only send the same report to all people in the list?
Thanks!
If you do not have enterprise (to utilize data driven subscription as #StephLocke mentioned), you can programmatically generate SSRS subscriptions using the SSRS web service.
Your code would look something like this (SubscriptionRequest is a custom class I use, its properties should be intuitive):
static void generateSubscription()
{
if (SubscriptionRequests.Count < 1) return;
NetworkCredential credentials = new NetworkCredential("user", "pass");
reports.ReportingService2005 rs = new reports.ReportingService2005();
rs.Credentials = credentials;
DateTime topDatetime = DateTime.Now;
topDatetime = topDatetime.AddMinutes(2);
foreach (SubscriptionRequest x in SubscriptionRequests)
{
reports.ExtensionSettings extensionSettings = new reports.ExtensionSettings();
List<reports.ParameterValue> extParameters = new List<reports.ParameterValue>();
List<reports.ParameterValue> parameters = new List<reports.ParameterValue>();
string description = "Email: ";
string eventType = "TimedSubscription";
extensionSettings.Extension = "Report Server Email";
string scheduleXml = "<ScheduleDefinition><StartDateTime>";
scheduleXml += topDatetime.ToShortDateString() + " " + topDatetime.ToShortTimeString();
scheduleXml += "</StartDateTime></ScheduleDefinition>";
parameters.Add(new reports.ParameterValue() { Name = "abc", Value = x.id });
extParameters.Add(new reports.ParameterValue() { Name = "RenderFormat", Value = x.renderFormat });
extParameters.Add(new reports.ParameterValue() { Name = "TO", Value = x.email });
extParameters.Add(new reports.ParameterValue() { Name = "ReplyTo", Value = x.replyTo });
extParameters.Add(new reports.ParameterValue() { Name = "IncludeReport", Value = "True" });
extParameters.Add(new reports.ParameterValue() { Name = "Subject", Value = "subject - " + " (" + x.id.ToString() + ")" });
extParameters.Add(new reports.ParameterValue() { Name = "Comment", Value = x.body });
extensionSettings.ParameterValues = extParameters.ToArray();
description += topDatetime.ToShortDateString() + " " + topDatetime.ToShortTimeString();
description += " (" + x.a + " - " + x.b + " - " + x.c + ")";
string _reportName = "/report";
rs.CreateSubscription(_reportName, extensionSettings, description, eventType, scheduleXml, parameters.ToArray());
topDatetime = topDatetime.AddSeconds(30);
}
}
More examples can be found here.
Yes you can use a data driven subscription to do this. Unfortunately this isn't available to every edition (2008+, enterprise only I believe) so you may not be able to use this functionality.
There are more details available: http://technet.microsoft.com/en-us/library/ms159150.aspx