none
Send Email to multiple users

    Question

  • Hi everyone

    I have a problem with a workflow.

    I use MOSS 2007 RTM
    I have a custom sharepoint list with several columns where one (lets call it MailRecipients) are of the type 'Person or Group' with the property 'Allow multiple selections' set to 'yes' - this works fine, and I can create items, select multiple users from AD and so on.

    Then i create a workflow using Sharepoint Designer 2007 and uses the action 'Send mail'.
    I then want to send a mail to all the people selected in the column 'MailRecipients', but this column isn't present when I try to selected the column for the 'To' field in my workflow.
    When I disable the proptery 'Allow multiple selections', there are no problem using the column in the To field in the Workflow

    How will I be able to use the People or Group column (with 'Allow multiple selections' enabled) as a 'To' value in a workflow 'Send Email' action.?
    I've tried making my own Custom Workflow action but have serious problems with this. Keep trying though!

    Hope anyone have more experience with this part of MOSS 2007

    Thanks

    Søren Bjerre, DK

     

    Wednesday, March 21, 2007 10:35 AM

All replies

  • Søren,

    Have you had any luck with this issue?  I am having the same problem except with assigning tasks to multiple users.  It seems like such a basic requirement for workflow, I feel like I must be doing something wrong.  Any help would be greatly appreciated.

    Thanks,
    - Lee
    Monday, March 26, 2007 3:38 PM
  • Hi Soren,

     

    I'm experiencing the same problem as you mentioned. Did you already find a solution to this?

     

    Thanks,

    Erik van Buuren, NL

    Wednesday, March 28, 2007 12:54 PM
  • This useful feature may be limited to Visual Studio users.  There is a replicator available to repeat a workflow item, that I assume would make it able to work on multiple items in a list, although I haven't had time to look into exactly what it does yet.  I'll need this feature soon, so I'll be checking back to see if anyone else has ideas before I go and implement something new.  Maybe using Todd Baginski's example it could be added as a custom email option inside of SharePoint.

    Thursday, March 29, 2007 3:39 PM
  • Hi

     

    Haven't quite solved it yet, but after having spoking to a collegue at Microsoft i've been confirmed that the option to mail multiple users isn't possible using the Sharepoint Designer Workflow.

    Instead I've tried creating a custom workflow action in Visual Studio, which have been given me all sorts of troubles, but I think im getting close to the solution.

     

    My goal was to create a custom workflow action that has one input parameter (the selected users) og one output parameter (the users mail-adresses as a string) and than make the programming logic that does this. By know, however, i'm near a solution where i provide an input parameter (the ID of the listitem holding the information of the selected users) and then through the action code, accessing the SPList object, and retrieving the users mails in that way.

    Not the most elegant solution, but my time is running up, and I have to get moving with other projects. When, or maybe more accurate, if, i get it to work, I'll try to leave some info on how the solution have been made on my site. I'll post a link when i have some working solution.

     

    Best regards

     

    Søren Bjerre, DK 

    Thursday, March 29, 2007 3:58 PM
  • Have you checked out the BasicCollectFeedback example? It seems to be doing exactly what you want.

     

    Friday, April 06, 2007 7:14 PM
  • Hi Søren and others with this problem,

    I've had the opportunity to work with this problem for a while now and have a couple of solutions. 

    The first is pretty hacky.  Basically you can temporarily turn off "
    Allow multiple selections" for your column and then SharePoint designer will pick the column up.  Save your workflow, turn "Allow multiple selections" back on, run the workflow, and it works.  Basically the limitation is in the SharePoint Designer UI, not in the engine itself.

    I've posted step by step instructions on my blog here:

    Multi-Value Columns in SharePoint Designer - Solution #1

    Solution #2 is to develop a custom action which I have working.  I'm writing it up as a post and should be finished this week.  Solution #3 is of course to use a custom Visual Studio workflow, and I'll be writing that up too.  I'll re-post here when I'm finished writing about Solution #2.
    • Proposed as answer by Dexter Wong Thursday, April 29, 2010 8:09 AM
    Monday, April 09, 2007 5:17 PM
  • As promised I posted an article with code that describes how to develop a custom activity for SharePoint designer that allows you to send e-mail to users in a multi-value column.  The post includes detailed deployment instructions and screenshots, but if you're just interested in the code I'll post it here.  Here's the post:

    Multi Value Columns Solution #2 - Custom Activities in SPD

    And here's the code:

    // Note: this code was adopted from Todd Baginski at http://www.sharepointblogs.com/tbaginski/archive/2007/03/08/HOW-TO_3A00_-Create-a-custom-Windows-Workflow-Activity-and-make-it-available-in-SharePoint-Designer.aspx

     

    using System;

    using System.ComponentModel;

    using System.ComponentModel.Design;

    using System.Collections;

    using System.Drawing;

    using System.Workflow.ComponentModel;

    using System.Workflow.ComponentModel.Design;

    using System.Workflow.ComponentModel.Compiler;

    using System.Workflow.ComponentModel.Serialization;

    using System.Workflow.Runtime;

    using System.Workflow.Activities;

    using System.Workflow.Activities.Rules;

    using System.Net.Mail;

    using Microsoft.SharePoint;

    using System.IO;

     

    namespace MultiRecipientMail {

        public partial class MultiRecipientMailActivity : SequenceActivity {

     

            // Windows Workflow Foundation (WWF) will store the workflow state using these "instance property"

            //      dependency properties for more info check out: http://msdn2.microsoft.com/en-us/library/ms733604.aspx

     

            // the ToProperty must be bound to a multi-value column of users otherwise the activity will fail

            public static DependencyProperty ToProperty = DependencyProperty.Register("To", typeof(string), typeof(MultiRecipientMailActivity));

            // the FromEmailAddress does not support multi-value columns, it must be static or bound to a single-value column

            public static DependencyProperty FromEmailAddressProperty = DependencyProperty.Register("FromEmailAddress", typeof(string), typeof(MultiRecipientMailActivity));

            public static DependencyProperty SubjectProperty = DependencyProperty.Register("Subject", typeof(string), typeof(MultiRecipientMailActivity));

            public static DependencyProperty BodyProperty = DependencyProperty.Register("Body", typeof(string), typeof(MultiRecipientMailActivity));

            public static DependencyProperty SMTPServerNameProperty = DependencyProperty.Register("SMTPServerName", typeof(string), typeof(MultiRecipientMailActivity));

     

            // the ValidationOptionAttribute is new to .Net 3.0 and is used exclusively by WWF

            [ValidationOption(ValidationOption.Required)]

            public string To {

                get {

                    return (string)base.GetValue(ToProperty);

                }

                set {

                    base.SetValue(ToProperty, value);

                }

            }

     

            [ValidationOption(ValidationOption.Required)]

            public string FromEmailAddress {

                get {

                    return (string)base.GetValue(FromEmailAddressProperty);

                }

                set {

                    base.SetValue(FromEmailAddressProperty, value);

                }

            }

     

            [ValidationOption(ValidationOption.Required)]

            public string Subject {

                get {

                    return (string)base.GetValue(SubjectProperty);

                }

                set {

                    base.SetValue(SubjectProperty, value);

                }

            }

     

            [ValidationOption(ValidationOption.Optional)]

            public string Body {

                get {

                    return (string)base.GetValue(BodyProperty);

                }

                set {

                    base.SetValue(BodyProperty, value);

                }

            }

     

            [ValidationOption(ValidationOption.Required)]

            public string SMTPServerName {

                get {

                    return (string)base.GetValue(SMTPServerNameProperty);

                }

                set {

                    base.SetValue(SMTPServerNameProperty, value);

                }

            }

     

            public MultiRecipientMailActivity() {

                InitializeComponent();

            }

     

            protected override ActivityExecutionStatus Execute(ActivityExecutionContext executionContext) {

                try {

                    // log workflow started

                    LogThis("MultiRecipientMail started");

     

                    // create a MailMessage object to send the email

                    MailMessage msg = new MailMessage();

     

                    // set the from address

                    MailAddress fromAddress = new MailAddress(this.FromEmailAddress);

                    msg.From = fromAddress;

     

                    // the To property is bound to a multi-value column of usernames (e.g. "Domain\username1; Domain\username2",

                    //      so parse its contents out into an array of e-mail addresses

                    string[] astrEmails = GetEmailAddressesFromUsernames(To);

     

                    // loop through and add the To addresses to the MailMessage

                    foreach (string strEmail in astrEmails) {

                        MailAddress toAddress = new MailAddress(strEmail);

                        msg.To.Add(toAddress);

                    }

     

                    // set the subject and body

                    msg.IsBodyHtml = true;

                    msg.Subject = Subject;

                    msg.Body = Body;

     

                    // create an SmtpClient object to represent the mail server that will send the message

                    SmtpClient client = new SmtpClient(SMTPServerName);

                    // how to authenticate to the email server

                    client.UseDefaultCredentials = true;

                    // send the message

                    client.Send(msg);

     

                    // log workflow started

                    LogThis("MultiRecipientMail completed successfully");

                } catch (Exception ex) {

                    LogThis("MultiRecipientMail error: " + ex.ToString());

                }

     

                // indicate the activity has closed

                return ActivityExecutionStatus.Closed;

            }

     

            private string[] GetEmailAddressesFromUsernames(string strUsernames) {

                // SharePoint stores multi-value columns to the format: "domain\user1; domain\user2" so split on ';'

                string[] astrUsernames = strUsernames.Split(';');

     

                // This beautiful piece of code I adapted from Finnatic at http://rfinn.spaces.live.com/Blog/cns!4E19D0E183DFC38B!204.entry

                //      I looked for a while to find an easier way to get e-mail addresses from user names, but no luck.  Perhaps web services.

                //      Anyway RunWithElevatedPrivileges is necessary to avoid permissions problems with UserProfileManager. It's argument is a

                //      delegate, so the anonymous delegate works.  This will probably fail if the user has no WorkEmail, but it's a starting point.

                //     

                SPSecurity.RunWithElevatedPrivileges(

                    delegate() {

                        // connect to the root Sharepoint site

                        using (SPSite site = new SPSite("http://nic-lrichard-03:34089/")) {

                            Microsoft.Office.Server.ServerContext context = Microsoft.Office.Server.ServerContext.GetContext(site);

                            Microsoft.Office.Server.UserProfiles.UserProfileManager profilemanager = new Microsoft.Office.Server.UserProfiles.UserProfileManager(context);

     

                            // for each of the usernames in astrUsernames

                            for (int i = 0; i < astrUsernames.Length; i++) {

                                string strUsername = astrUsernamesIdea.Trim();

     

                                // convert the username to the WorkEmail address

                                Microsoft.Office.Server.UserProfiles.UserProfile profile = profilemanager.GetUserProfile(strUsername);

                                astrUsernamesIdea = profile[Microsoft.Office.Server.UserProfiles.PropertyConstants.WorkEmail].Value.ToString();

                            }

                        }

                    }

                );

     

                return astrUsernames;

            }

     

            /// <summary>

            /// This logging method is NOT production ready.  Obviously you need to create a C:\MultiRecipientMailLog.log

            /// with appropriate for debugging.  In production it should log to the event log or be removed.

            /// </summary>

            /// <param name="str"></param>

            private void LogThis(string str) {

                FileInfo fi = new FileInfo("C:\\MultiRecipientMailLog.log");

                if (fi.Exists) {

                    StreamWriter sw = fi.AppendText();

                    sw.WriteLine(String.Format("{0:g} {1}", DateTime.Now, str));

                    sw.Flush();

                    sw.Close();

                }

            }

       

        }

    }



    Sunday, April 15, 2007 4:15 PM
  • There is a simeple answer using SPD; build a dynamic string made up of 'MailRecipients'.  Map this variable to "TO:".

     

    The only issue is if 'MailRecipients' is blank the email is ent to "???"

     

    Hope this helps

    Daniel

    Thursday, July 26, 2007 9:11 AM
  • Solution #1 Works like a champ for me...

     

    Thank you!!

    Wednesday, November 21, 2007 5:12 PM
  • Solution #1 worked like a champ for me, thank you!!

    Wednesday, November 21, 2007 5:14 PM
  • This was an ENORMOUS help Lee. Thanks!!!!!!!!!!!!!!!!!!!!!

    Friday, June 06, 2008 12:59 PM
  • Thank you so much Lee. Solution #1 worked for me!.
    Tuesday, August 05, 2008 9:07 PM
  • This thread was very helpful in getting me to be able to create a list and send emails to users in that list.

    What if I do not want to maintain the list of approvers? The solution I am attempting to create is pretty much to keep tabs on the process, not be too strict on who is in the process as it happens.

    I want the user to dynamically select the approvers as in the default approval workflow that comes with SharePoint. Is there a way to prompt for multiple email address inputs using SharePoint designer?

    I've figured out how to handle the addresses once I store them in variables or colums or whereever, I just don't know how to prompt the user with the address book or active directory lookup without going to visual studio - I want this maintainable by someone without them having to learn visual studio.

    any tips appreciated. thank you

    Monday, September 29, 2008 9:01 PM
  • Ok, do you know how to make the user name (Joe Smoe) show up the custom workflow e-mail instead of the domain\username?  I've seen a million people with this question and I don't think our IT department is going to install the codeplex utility.  WHY can the system generated e-mails show the user name instead of the domain\user name, but custom workflows in SharePoint cannot?  Any ideas anyone????? PLEASE :).

    Thanks,

    dah
    Monday, February 16, 2009 11:42 PM
  • first you have to correct your outgoing email settings. then

    you can use this method to send emails.

    SPUtility.SendEmail (SPWeb, Boolean, Boolean, String, String, String)


    if you need to send multiple emails you have to use a loop and within that you

    have to set email addresses to the method and send mails in a loop.

    examples are available in
    http://www.sharepoint-amila.blogspot.com/
    Wednesday, March 04, 2009 7:44 PM
  • You can simply accomplish by following this approach:

    1. In your workflow designer create a new Activity called Build Dynamic String. Assign your MailRecipients column to this variable. Call this variable "Recepients"

    2. Next create a Send Email action and in To field , lookup for Workflow Data > Recepients.

    Click OK and you are done!

     

    Thursday, October 28, 2010 12:06 PM
  • A really simple solution is to in your workflow, create a variable and then build a dynamic string that is set equal to the column with multiple values. Then in the send email action, put the variable in the "to" section of the email. It should send the message to everybody.
    • Proposed as answer by aaronk84 Monday, October 31, 2011 8:09 PM
    • Unproposed as answer by aaronk84 Monday, October 31, 2011 8:09 PM
    Monday, October 31, 2011 8:09 PM