Button or template to e-mail a list of people related to a custom object

We are a music school and have a custom objects for group classes.

We have an custom object, called “Student” that is related to salesforce contacts through a lookup filter.

“Students” get enrolled in the class via an “enrollment” object which is a child object of the “Group Class” custom object.

We need to e-mail the students in the group classes on a weekly basis and would like to have a process that would allow us to select one thing, like a button or a template, that would generate a blank e-mail. When we activate this button or template, we would like it to open the gmail account associated with the Salesforce users account and populate the “to” field will all of the e-mail addresses connected to this student and the “from” field with the Salesforce user’s e-mail.  We want this e-mail to get logged in Salesforce Activity Tasks. 

Any ideas?


Hi Anna, here’s a tutorial about how to set up Gmail to Salesforce in Skuid, which will take care of logging the Salesforce Activity Tasks for the emails.

 For your Group Class custom object, I think you could set up an “Email Class” button as a page title action, or a global action on the table of enrolled students, but me check on the specifics of accomplishing that, and then I’ll get back to you.

Thanks! The directions above are out of date and generating an error on the field Email Service (NameFunctionName). I am not sure how to solve that.

{{MMA_Camper__r.Contact__r.Email}}{{#MMA_Camper__r.Contact__r.Email}} [https://mail.google.com/mail/?view=cm&fs=1&tf=1&to={{{MMA_Camper__r.Contact__r.Email}}}&...; target="ComposeGmail"> Gmail]{{/MMA_Camper__r.Contact__r.Email}}

Can you post the details of that error message?  Maybe a screenshot? 
We use that method every day in our production Crm org,  so I’d be really surprized if the tutorial was out of date… (Anna is pretty good)

Rob, It seems to work if I take out this condition:

Step 5: Set the third condition to the FunctionId > FunctionName field.

  1. Click on the icon to select a field.
  2. Click on the green arrow to dive into the Service related fields.
  3. Search and select Email Service Name (i.e. FunctionName).


Yeah, that tutorial is a little out of date (at least visually, I think some of the organization in the page composer has been changed).  But it’s weird that the condition is throwing that error, because we do have the same condition running on the page in our CRM org and it isn’t causing errors. 

Is it totally working without that condition? (i.e. clicking on the email link opens gmail in a new tab, with the student email in the to field and a complete email to salesforce address in the bcc?).

I’m tempted to say “If  you found a way that it works for you, then just go with that” :wink: unless there are any objections from the Rob Hatch department…

We figured out how to write code to send an e-mail to a group of people through g-mail. The only problem is that gmail does not accept and formatted text. 

Now I either:

  1. need a solution to open a new gmail and paste in the “body” of the email to show up as formatted text, (this seems like it would be complicated due to gmail security issues).
  2. Forget about gmail and get this process to work via the Salesforce Activity “send and e-mail” button. 
Ideas: It occurred to me that we could automate it to send out individual e-mails to each enrolled person rather than trying to send it as a bulk list as these lists are usually 30 e-mails or less.

I created a new object where my team could draft an e-mail that they want to send. There is a row action on this new object that actually sends the e-mail. This is not using the Gmail icon.

var params = arguments[0], $ = skuid.$;
var row = params.item.row;

var emailaddress=“”;
var emaillist=“”;
var campermodel=skuid.model.getModel(‘MMA_Camp_Enrollment’).data;
for(i=0;i<campermodel.length;i++){
    emailaddress=campermodel[i].MMA_Camper__r.Contact__r.Email;
    if(emailaddress!==undefined){
        if (emaillist.length!==0){
            emaillist=emaillist + “,” + emailaddress;

        }
        else {
            emaillist=emaillist + emailaddress;

            }
        
        }
    }
var domain=skuid.model.getModel(“EmailToSF”).data[0].EmailDomainName;

//Get the row data that contains the fields for the e-mail body and subject.
var email_body=row.Body__c;
console.log(’ email_body ’ + email_body);
var email_subject=row.E_mail_Subject__c;
console.log(‘email_body’ + email_body + ‘email_subject’ + email_subject);
console.log(“https://mail.google.com/mail/?view=cm&fs=1&tf=1&to=”; + emaillist + “&bcc=” + emaillist + “&shva=1&su='” + email_subject + “'&body=” + email_body + “&target=_blank”);
document.location.href=“https://mail.google.com/mail/?view=cm&fs=1&tf=1&to=”; + emaillist + “&bcc=” + emaillist + “&shva=1&su='” + email_subject + “'&body=” + email_body + “&target=_blank”;


Also, “&target=_blank” opens the gmail in the current window. What do I need to open it in a new window?

The word _blank needs to be wrapped in single quotes. 

Rob, we tried that and it did not work. We are not sure why, but we did solve this issue this way by replacing “document.location.href” with a “var href” followed by “var new_window = window.open(href,“newwindow”);”


var params = arguments[0], $ = skuid.$;
var row = params.item.row;

var emailaddress=“”;
var emaillist=“”;
var classmodel=skuid.model.getModel(‘MMA_Group_Class_Enrollment_ENROLLED’).data;
for(i=0;i<classmodel.length;i++){
    emailaddress=classmodel[i].MMA_Student_Record__r.Contact__r.Email;
    otheremailaddress=classmodel[i].MMA_Student_Record__r.Contact__r.Other_Email__c;
    console.log(’ emailaddress ’ + emailaddress + ’ otheremailaddress ’ + otheremailaddress);
    console.log(classmodel[i].MMA_Student_Record__r);
    if(emailaddress!==undefined){
        if (emaillist.length!==0){
            emaillist=emaillist + “,” + emailaddress;

        }
        else {
            emaillist=emaillist + emailaddress;

            }
        
        }
    if(otheremailaddress!==undefined){
        if (emaillist.length!==0){
            emaillist=emaillist + “,” + otheremailaddress;

        }
        else {
            emaillist=emaillist + otheremailaddress;

            }
        
        }
    }
//Get the row data that contains the fields for the e-mail body and subject.
var email_body=row.Body__c;
console.log(’ email_body ’ + email_body);
var email_subject=row.E_mail_Subject__c;
var useremail=skuid.utils.userInfo.email;
//console.log(‘email_body’ + email_body + ‘email_subject’ + email_subject);
//console.log(“https://mail.google.com/mail/?view=cm&fs=1&tf=1&to=”; + emaillist + “&bcc=” + emaillist + “&shva=1&su=” + email_subject + “&body=” + email_body + “&target=_blank”);
var href=“https://mail.google.com/mail/?view=cm&fs=1&tf=1&to=”; + useremail + “&bcc=” + emaillist + “&shva=1&su=” + email_subject + “&target=_newtab”;
//+ “&body=” + email_body;

//console.log(JSON.stringify(emaillist), href)
var new_window = window.open(href,“newwindow”);


Thanks Anna for starting this thread! I’m pretty much after the same initial task you were after, to send a group of contacts (through a junction objects) that relate to another object. I’m not sure if I understood your comment 4 posts ago, did you say you figured a way to send the group in a single email as opposed to sending each contact a separate email? If so, I would be super grateful if you could share that code here as well.

Here is the code. I left the e-mail body out as gmail does not retain formatting. A simple copy/paste from your Salesforce formatted e-mail body will retain the formatting though. One extra manual step, but still a lot less time than other solutions!

var params = arguments[0], $ = skuid.$;
var row = params.item.row;

var emailaddress=“”;
var emaillist=“”;
var classmodel=skuid.model.getModel(‘MMA_Group_Class_Enrollment_ENROLLED’).data;
for(i=0;i<classmodel.length;i++){
    emailaddress=classmodel[i].MMA_Student_Record__r.Contact__r.Email;
    otheremailaddress=classmodel[i].MMA_Student_Record__r.Contact__r.Other_Email__c;
    console.log(’ emailaddress ’ + emailaddress + ’ otheremailaddress ’ + otheremailaddress);
    console.log(classmodel[i].MMA_Student_Record__r);
    if(emailaddress!==undefined){
        if (emaillist.length!==0){
            emaillist=emaillist + “,” + emailaddress;

        }
        else {
            emaillist=emaillist + emailaddress;

            }
        
        }
    if(otheremailaddress!==undefined){
        if (emaillist.length!==0){
            emaillist=emaillist + “,” + otheremailaddress;

        }
        else {
            emaillist=emaillist + otheremailaddress;

            }
        
        }
    }
//Get the row data that contains the fields for the e-mail body and subject.
var email_body=row.Body__c;
console.log(’ email_body ’ + email_body);
var email_subject=row.E_mail_Subject__c;
var useremail=skuid.utils.userInfo.email;
//console.log(‘email_body’ + email_body + ‘email_subject’ + email_subject);
//console.log(“https://mail.google.com/mail/?view=cm&fs=1&tf=1&to=”; + emaillist + “&bcc=” + emaillist + “&shva=1&su=” + email_subject + “&body=” + email_body + “&target=_blank”);
var href=“https://mail.google.com/mail/?view=cm&fs=1&tf=1&to=”; + useremail + “&bcc=” + emaillist + “&shva=1&su=” + email_subject + “&target=_newtab”;
//+ “&body=” + email_body;

//console.log(JSON.stringify(emaillist), href)
var new_window = window.open(href,“newwindow”);