Dynamic form notification email recipient based on form field
Hi,
I have an enquiry form on my website (v12) which uses Umbraco forms.
The enquiry form features a branch selector dropdown, which allows uses to select the branch of the company they want to send their enquiry to. The dropdown is populated by a prevalue source (a list of branch nodes). The form submission field contains the node id for the branch.
I would like to use the 'Send email with template (Razor)' workflow, and set the notification to be the address set on the Branch node (The Branch doc type has a 'notificationEmailAddress' field).
If I try to use {branch} in the recipient email field of the workflow, it returns the following error:
With this scenario you can created your own Custom WorkflowType...
I think I've done nearly the exact same thing before, where the Umbraco Form has a PreValue source for a list of stores, populated from Umbraco Nodes, the 'Value' field is the Umbraco Node Id, and the Caption is the name of the store...
Then, in the Custom Workflow step you can read the value of the selected branch/(store in my case) from the submitted form details and then get that node from Umbraco and read the store/branch email address and then send the email there...
this is the kind of thing I had:
public class SendEmailToSelectedStoreWorkflow : WorkflowType
{
private readonly ILogger<SendEmailToSelectedStoreWorkflow> _logger;
private readonly IEmailService _emailService;
private readonly IWebpackService _webpackService;
private readonly IOptions<SiteSettingsOptions> _siteSettings;
private readonly IUmbracoContextAccessor _umbracoContextAccessor;
public SendEmailToSelectedStoreWorkflow(ILogger<SendEmailToSelectedStoreWorkflow> logger, IWebpackService webpackService,IEmailService emailService, IOptions<SiteSettingsOptions> siteSettings, IUmbracoContextAccessor umbracoContextAccessor)
{
_logger = logger;
_webpackService = webpackService;
_emailService = emailService;
_siteSettings= siteSettings;
_umbracoContextAccessor = umbracoContextAccessor;
this.Id = new Guid("4d3ac0b3-bd01-4e7a-854b-5fdaabe21a8c");
this.Name = "Send Email To Selected Store";
this.Description = "This workflow forwards the email containing the forms submission onto the store selected in the store dropdown on the form";
this.Icon = "icon-store";
this.Group = "Services";
}
public override WorkflowExecutionStatus Execute(WorkflowExecutionContext context)
{
_logger.LogInformation("SendEmailToSelectedStoreWorkflow STARTED: " + context.Form.Name);
try
{
var toEmail = string.Empty;
var storeName = string.Empty;
var logoUrl = _siteSettings.Value.SiteDomain + "/" + _webpackService.GetImageFile("logo-png");
var htmlBody = $"<p style='margin-top: 5px;'><br/></p><img width='260' height='46' src='{logoUrl}'/><p style='margin-top: 10px;' ><br/></p>";
var subject = context.Form.Name;
var storeDropdownFieldAlias = "storesDropdown";
foreach (var recordField in context.Record.RecordFields)
{
// check if values exist for the record
if (recordField.Value.Values != null && recordField.Value.Values.Any())
{
// read the value and alias of the record field
var formFieldValue = recordField.Value.Values[0].ToString();
var formFieldAlias = recordField.Value.Alias;
storeName = formFieldValue;
//if it's the dropdown field
if (formFieldAlias.Equals(storeDropdownFieldAlias,StringComparison.InvariantCultureIgnoreCase))
{
_logger.LogInformation($"Found {storeDropdownFieldAlias} with FormFieldValue: {formFieldValue}");
if (!String.IsNullOrWhiteSpace(formFieldValue))
{
if (_umbracoContextAccessor.TryGetUmbracoContext(out IUmbracoContext? context) == false)
{
var store = context.Content.GetById(formFieldValue);
if (store!=null){
toEmail = store.Value<string>("storeEmail");
storeName = store.Name;
subject += " for " + storeName;
}
else
{
_logger.LogInformation($"No Store Found");
}
}
else {
_logger.LogInformation($"No Umbraco Context Found!");
}
}
else
{
_logger.LogInformation("No Form Field Value For Store Dropdown!");
}
}
htmlBody += "<h4 style='font-weight: 700; color: #000000; font-size: 16px;'>" +
recordField.Value.Field.Caption + "</h4>"
+ "<p style='margin-top: 0;'>" + storeName + "</p>";
}
else
{
_logger.LogInformation($"SendEmailToSelectedStoreWorkflow NULL FIELD: {context.Form.Name} - {recordField.Value.Alias} of type {recordField.Value.DataTypeAlias}");
}
}
AsyncHelper.RunSync(() => _emailService.SendMessageAsync("[email protected]", "YourWebsite Website", toEmail, storeName, subject, htmlBody));
}
catch (Exception ex)
{
_logger.LogInformation("SendEmailToSelectedStoreWorkflow ERROR: " + context.Form.Name + " " + ex.Message);
}
_logger.LogInformation("SendEmailToSelectedStoreWorkflow ENDED: " + context.Form.Name);
return WorkflowExecutionStatus.Completed;
}
public override List<Exception> ValidateSettings()
{
return new List<Exception>();
}
}
Thanks for your response, that does do what I've asked for - however, I need to be able to use a selected template (like the default 'Send email with template (Razor)' workflow does rather than a hardcoded string for the email body like in your example. (Apologies, I should have been more specific!)
If you add this to the custom Workflow Type as a public property
[Umbraco.Forms.Core.Attributes.Setting("Store Dropdown Field Alias", Alias = "storeDropdownFieldAlias",
Description = "Enter the alias of the field that contains the Store dropdown, if left blank, will default to try to use 'storesDropdown'",
View = "TextField")]
public string StoreDropdownFieldAlias { get; set; }
you'll get a field that you can set when you add the workflow to a form, that you can then read inside your implementation to avoid hardcoding...
We have multiple forms with dropdowns on which to choose the store, and they all have different alias!
So I added the textfield above, so that when we add the custom workflow step, we can apply it to the specific form field...
Similarly this could be the path to an XSLT file, and you could inside the custom implementation above, apply the provided XSLT file to the data passed into the Workflow, just like the custom one does! (in fact your custom workflowtype might be able to inherit from the XSLT one that is shipped, and you just override the implementation to get the email, and call the base method to do the template fangling... but that is a guess!
Dynamic form notification email recipient based on form field
Hi,
I have an enquiry form on my website (v12) which uses Umbraco forms.
The enquiry form features a branch selector dropdown, which allows uses to select the branch of the company they want to send their enquiry to. The dropdown is populated by a prevalue source (a list of branch nodes). The form submission field contains the node id for the branch.
I would like to use the 'Send email with template (Razor)' workflow, and set the notification to be the address set on the Branch node (The Branch doc type has a 'notificationEmailAddress' field).
If I try to use {branch} in the recipient email field of the workflow, it returns the following error:
Hi Jake
With this scenario you can created your own Custom WorkflowType...
I think I've done nearly the exact same thing before, where the Umbraco Form has a PreValue source for a list of stores, populated from Umbraco Nodes, the 'Value' field is the Umbraco Node Id, and the Caption is the name of the store...
Then, in the Custom Workflow step you can read the value of the selected branch/(store in my case) from the submitted form details and then get that node from Umbraco and read the store/branch email address and then send the email there...
this is the kind of thing I had:
Hopefully that gives you a steer?
regards
Marc
Hi Marc,
Thanks for your response, that does do what I've asked for - however, I need to be able to use a selected template (like the default 'Send email with template (Razor)' workflow does rather than a hardcoded string for the email body like in your example. (Apologies, I should have been more specific!)
Hi Jake
If you add this to the custom Workflow Type as a public property
you'll get a field that you can set when you add the workflow to a form, that you can then read inside your implementation to avoid hardcoding...
We have multiple forms with dropdowns on which to choose the store, and they all have different alias!
So I added the textfield above, so that when we add the custom workflow step, we can apply it to the specific form field...
Similarly this could be the path to an XSLT file, and you could inside the custom implementation above, apply the provided XSLT file to the data passed into the Workflow, just like the custom one does! (in fact your custom workflowtype might be able to inherit from the XSLT one that is shipped, and you just override the implementation to get the email, and call the base method to do the template fangling... but that is a guess!
regards
marc
Overriding the implementation of the default 'Send email with template (Razor)' works perfectly - thanks for the suggestion!
Below is the workflow class that I created to get it working:
Great!
is working on a reply...