function readOnly(count){ }
Starting November 20, the site will be set to read-only. On December 4, 2023,
forum discussions will move to the Trailblazer Community.
+ Start a Discussion
kamalkamal 

How to send email to a public group in apex

I Have requirement in which i need to send a email to a public group from an apex class.

 

Any pointers will be helpful

 

Thanks in advance  

Best Answer chosen by Admin (Salesforce Developers) 
prageethprageeth

Once before I had a requirement to send emails to all of the users in a public group and I accomplished my task as below. I don't know whether you are looking for this kind of a solution.

 

 Controller:

public class EmailSender {

public void sendMail() {

Messaging.SingleEmailMessage mail = new Messaging.SingleEmailMessage();

mail.setToAddresses(getEmailAddresses());

mail.setSubject('This is the subject');

mail.setPlainTextBody('This is the body.');

Messaging.sendEmail(new Messaging.SingleEmailMessage[] { mail });

}

 

private List<String> getEmailAddresses() {

List<String> idList = new List<String>();

List<String> mailToAddresses = new List<String>();

Group g = [SELECT (select userOrGroupId from groupMembers) FROM group WHERE name = 'MyPubGroup'];

for (GroupMember gm : g.groupMembers) {

idList.add(gm.userOrGroupId);

}

User[] usr = [SELECT email FROM user WHERE id IN :idList];

for(User u : usr) {

mailToAddresses.add(u.email);

}

return mailToAddresses;

}

}

 

 In page:

<apex:commandbutton value="Send Mail" action="{!sendMail}"/>

 

 

 

 

 

 

 

All Answers

kminevkminev
I would like to know this as well?
kminevkminev
Anybody? :)
XactiumBenXactiumBen

Basically what you need to do is to query the group members from within a group and loop around to get out their user ids.  There is an added problem where there could be a group inside a group which I have attempted but it could easily hit governor limits if you have a hierarchy of groups.

 

public static List<Messaging.SingleEmailMessage> createEmailsFromGroup(Id groupId) { List<Messaging.SingleEmailMessage> emailsToSend = new List<Messaging.SingleEmailMessage>(); // Get user and group key prefixes so we can test to see what the UserOrGroupId field contains String userType = Schema.SObjectType.User.getKeyPrefix(); String groupType = Schema.SObjectType.Group.getKeyPrefix(); // Loop through all group members in a group for (GroupMember m : [Select Id, UserOrGroupId From GroupMember Where GroupId = :groupId]) { // If the user or group id is a user if (((String)m.UserOrGroupId).startsWith(userType)) { Messaging.SingleEmailMessage e = new Messaging.SingleEmailMessage(); // todo: populate email fields here emailsToSend.add(e); } // If the user or group id is a group // Note: there may be a problem with governor limits if this is called too many times else if (((String)m.UserOrGroupId).startsWith(groupType)) { // Call this function again but pass in the group found within this group emailsToSend.addAll(createEmailsFromGroup(m.UserOrGroupId)); } } // Return my emails - You can then call Messaging.sendEmail when this function returns return emailsToSend; }

 

 

 

prageethprageeth

Once before I had a requirement to send emails to all of the users in a public group and I accomplished my task as below. I don't know whether you are looking for this kind of a solution.

 

 Controller:

public class EmailSender {

public void sendMail() {

Messaging.SingleEmailMessage mail = new Messaging.SingleEmailMessage();

mail.setToAddresses(getEmailAddresses());

mail.setSubject('This is the subject');

mail.setPlainTextBody('This is the body.');

Messaging.sendEmail(new Messaging.SingleEmailMessage[] { mail });

}

 

private List<String> getEmailAddresses() {

List<String> idList = new List<String>();

List<String> mailToAddresses = new List<String>();

Group g = [SELECT (select userOrGroupId from groupMembers) FROM group WHERE name = 'MyPubGroup'];

for (GroupMember gm : g.groupMembers) {

idList.add(gm.userOrGroupId);

}

User[] usr = [SELECT email FROM user WHERE id IN :idList];

for(User u : usr) {

mailToAddresses.add(u.email);

}

return mailToAddresses;

}

}

 

 In page:

<apex:commandbutton value="Send Mail" action="{!sendMail}"/>

 

 

 

 

 

 

 

This was selected as the best answer
kamalkamal
Thanks a lot Ben......You rock ....
kamalkamal
Thanks a lot Pragneeth....It worked
ShikibuShikibu

What if the group also has role members? I don't see a way to query them.

Jeffrey CheungJeffrey Cheung
Clearly people here don't know how to post code. I reformatted Ben's code here:
public static List<Messaging.SingleEmailMessage> createEmailsFromGroup(Id groupId) {
        List<Messaging.SingleEmailMessage> emailsToSend = new List<Messaging.SingleEmailMessage>();
        // Get user and group key prefixes so we can test to see what the UserOrGroupId field contains
        String userType = Schema.SObjectType.User.getKeyPrefix();
        String groupType = Schema.SObjectType.Group.getKeyPrefix();
        // Loop through all group members in a group
        for (GroupMember m : [SELECT Id, UserOrGroupId FROM GroupMember WHERE GroupId = :groupId]) {
            // If the user or group id is a user
            if (((String) m.UserOrGroupId).startsWith(userType)) {
                Messaging.SingleEmailMessage e = new Messaging.SingleEmailMessage();
                // todo: populate email fields here
                emailsToSend.add(e);
            }
            // If the user or group id is a group 
            // Note: there may be a problem with governor limits if this is called too many times 
            else if (((String) m.UserOrGroupId).startsWith(groupType)) {
                // Call this function again but pass in the group found within this group
                emailsToSend.addAll(createEmailsFromGroup(m.UserOrGroupId));
            }
        }
        // Return my emails - You can then call Messaging.sendEmail when this function returns
        return emailsToSend;
    }

 
Timothy Gentet O'BrienTimothy Gentet O'Brien
There is a more efficient way of doing this! The below runs less queries, uses less resources and is a little neater, if all you need are users email Addresses:
public List<String> getEmailAddresses() {
    List<String> mailToAddresses = new List<String>();
	List<User> users = [SELECT Email FROM User WHERE Id IN (
					  	  SELECT UserOrGroupId
					  	  FROM GroupMember
					  	  WHERE Group.Name = :'Group Name'
					    )];

	for(User u : users)
		mailToAddresses.add(u.email);

	return mailToAddresses;
}

The above will query all of the relevant users in 1 query and will populate the list of Email Addresses then return it.

Alternatively you could also scrap this and go with an even neater way and utilise Organisation Wide Email Address.