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];
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;
}
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];
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;
}
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.
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
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; }
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}"/>
What if the group also has role members? I don't see a way to query them.
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.