I’ve created a simple SalesForce Workflow for Umbraco Forms 15:
using DotLiquid;
using Microsoft.Extensions.Logging;
using RestSharp;
using Umbraco.Forms.Core;
using Umbraco.Forms.Core.Attributes;
using Umbraco.Forms.Core.Enums;
namespace Umbraco.Forms.Workflows.SalesForce.Workflows
{
public class SalesForceWebToLeadWorkflow : WorkflowType
{
[Setting("SalesForce Id", Alias = "oid",
Description = "SalesForce Customer Id (Oid)",
View = "Umb.PropertyEditorUi.TextBox",
IsMandatory = true,
SupportsHtml = false,
DisplayOrder = 0)]
public string Oid { get; set; }
[Setting("Return URL",
Alias = "returnURL",
Description = "[Optional] URL to redirect back after submitting the form",
View = "Umb.PropertyEditorUi.TextBox",
IsMandatory = false,
SupportsHtml = false,
DisplayOrder = 1)]
public string ReturnUrl { get; set; }
[Setting("Custom Field Prefix",
Alias = "customFieldPrefix",
Description = "[Optional] Custom Field Prefix for SalesForce Filtering",
View = "Umb.PropertyEditorUi.TextBox",
IsMandatory = false,
SupportsHtml = false,
DisplayOrder = 2)]
public string CustomFieldPrefix { get; set; }
[Setting("Lead Source",
Alias = "leadSource",
Description = "[Optional] SalesForce Lead Source",
View = "Umb.PropertyEditorUi.TextBox",
IsMandatory = false,
SupportsHtml = false,
DisplayOrder = 3)]
public string LeadSource { get; set; }
[Setting("Debug",
Alias = "debugToggle",
Description = "[DEBUG] Set Debug Mode ON | OFF",
View = "Umb.PropertyEditorUi.Toggle",
IsMandatory = false,
SupportsHtml = false,
DisplayOrder = 4)]
public bool Debug { get; set; }
[Setting("Debug Email",
Alias = "debugEmail",
Description = "[DEBUG] Email address to send debug information",
View = "Umb.PropertyEditorUi.TextBox",
IsMandatory = false,
SupportsHtml = false,
DisplayOrder = 5)]
public string DebugEmail { get; set; }
private readonly ILogger<SalesForceWebToLeadWorkflow> _logger;
private const string SALESFORCE_WEBTOLEAD_URL = "https://webto.salesforce.com";
private const string SALESFORCE_RESOURCE = "/servlet/servlet.WebToLead?encoding=UTF-8";
public SalesForceWebToLeadWorkflow(ILogger<SalesForceWebToLeadWorkflow> logger)
{
Id = new Guid("8c9127b6-fd8c-4528-989d-6f3a9787f77e");
Name = "Salesforce Web-to-Lead";
Description = "Submit sales lead to Salesforce via Web-to-Lead";
Icon = "icon-mailbox";
Group = "CRM Integrations";
_logger = logger;
}
public override List<Exception> ValidateSettings()
{
var exceptions = new List<Exception>();
if (string.IsNullOrEmpty(Oid) && string.IsNullOrEmpty(Oid))
exceptions.Add(new Exception("Oid cannot be null"));
return exceptions;
}
public override Task<WorkflowExecutionStatus> ExecuteAsync(WorkflowExecutionContext context)
{
_logger.LogDebug("the IP " + context.Record.IP + " has submitted a record");
var status = WorkflowExecutionStatus.Failed;
var fieldHash = Hash.FromDictionary(context.Record.RecordFields.ToDictionary(k => k.Value.Field!.Alias.ToString(), v => (object)v.Value.ValuesAsString()));
try
{
var request = new RestRequest(SALESFORCE_RESOURCE + $"&orgId={Oid}", Method.Post);
// Add headers
request.AddHeader("Content-Type", "application/x-www-form-urlencoded");
request.AddHeader("Cookie", $"BrowserId={GenerateBrowserId()}");
// Add parameters for URL-encoded form data
request.AddParameter("oid", Oid);
if (!string.IsNullOrEmpty(ReturnUrl))
request.AddParameter("retURL", ReturnUrl);
if (!string.IsNullOrEmpty(LeadSource))
request.AddParameter("lead_source", LeadSource);
if (Debug)
{
request.AddParameter("debug", "1");
request.AddParameter("debugEmail", DebugEmail);
}
if (fieldHash != null)
{
foreach (var field in fieldHash)
{
var values = field.Value?.ToString()?.Split(',');
if (values is null) continue;
if (values.Length > 1)
{
foreach (var value in values)
request.AddParameter(field.Key.Replace(CustomFieldPrefix, ""), value.Trim());
}
else
{
request.AddParameter(field.Key.Replace(CustomFieldPrefix, ""), field.Value?.ToString()?.Trim(), true);
}
}
}
Task.Factory.StartNew(() => SubmitToSalesforceAsync(request));
status = WorkflowExecutionStatus.Completed;
}
catch (Exception ex)
{
_logger.LogError(ex, "Could not send lead to Salesforce");
status = WorkflowExecutionStatus.Failed;
return Task.FromResult(status);
}
return Task.FromResult(status);
}
private async Task<bool> SubmitToSalesforceAsync(RestRequest request)
{
// Execute the request
var client = new RestClient(SALESFORCE_WEBTOLEAD_URL);
var response = await client.ExecuteAsync(request);
if (!response.IsSuccessful)
{
_logger.LogDebug("Could not submit to SalesForce: {status} - {message}", response.StatusCode, response.ErrorMessage);
}
// Check if the response was successful
return response.IsSuccessful;
}
private static string GenerateBrowserId()
{
return Guid.NewGuid().ToString();
}
}
}
public class UmbracoFormsSalesForceProviderComposer : IComposer
{
public void Compose(IUmbracoBuilder builder)
{
builder.WithCollectionBuilder<WorkflowCollectionBuilder>()
.Add<SalesForceWebToLeadWorkflow>();
}
}
I can create the new Workflow.
But when I submit I get the following error:
request.ts:195
POST https://localhost:44311/umbraco/forms/management/api/v1/form-workflow/8c9127b6-fd8c-4528-989d-6f3a9787f77e/validate-settings 500 (Internal Server Error)
fy @ request.ts:195
(anonymous) @ request.ts:314
await in (anonymous)
(anonymous) @ CancelablePromise.ts:79
ly @ CancelablePromise.ts:40
c @ request.ts:306
postFormWorkflowByIdValidateSettings @ services.ts:711
M @ form-edit-workflow-modal.element.ts:164
await in M
handleEvent @ index.js:15
provider-type-settings-helper.class.ts:186 Uncaught (in promise) TypeError: Cannot read properties of undefined (reading 'detail')
at U_.createValidationErrorNotification (provider-type-settings-helper.class.ts:186:39)
at c.M (form-edit-workflow-modal.element.ts:168:43)
createValidationErrorNotification @ provider-type-settings-helper.class.ts:186
M @ form-edit-workflow-modal.element.ts:168
await in M
handleEvent @ index.js:15
Is the workflow missing something?