Automatically push data from a Kentico form to SalesForce using a Web to Lead form

Fri Apr 04 2014

This post shows how to have data from a Kentico form builder pushed to SalesForce automatically using the Web-To-Lead functionality.

The two pieces of information you need from SalesForce is your OID and the Web-To-Lead post URL.

Below is the class to post to SalesForce from a BizFormItem. This class can be created in your App_Code folder. You want to make sure you set SalesForceOID and SalesForceWebToLeadURL to the correct values. Next set SalesForceWebToLeadForms to list each Kentico Form you want to push over.

You will also want to update the mapField(LeadModel, string) function to correctly map your Kentico Form field names to the corresponding SalesForce field. If you have any custom fields, you will need to generate the Web-To-Lead form html and find the custom field name used.

// add these includes
using CMS.CMSHelper;
using CMS.FormEngine;

namespace roma
    public class SalesForceService : IDisposable
        // define sales force settings - should be in web.config
        public static string SalesForceOID  = "00Di0000000AAAA";
        public static string SalesForceWebToLeadURL = "";

        // define forms we should integrate
        public static string[] SalesForceWebToLeadForms = { "BizForm.ContactForm", "BizForm.SignUpForm" }

        // function that posts from the given form record
        public void PostLeadFromForm(BizFormItem formObject)
            // get the form name that represents the list
            var form = 
                    formObject.BizFormClassName.ToLower().Replace("bizform.", ""),
            string formName = form.FormDisplayName;

            // check if a web to lead
            if (SalesForceWebToLeadForms.Contains(formObject.BizFormClassName))
                // create the model
                var model = new LeadModel();

                // map the fields
                foreach (var col in formObject.ColumnNames)
                    mapField(model, formObject, col);

                // post to sales force

        // function that maps the col to the correct model field
        private void mapField(LeadModel model, BizFormItem formObject, string col)
            // check the name
            switch (col.ToLower())
                // email
                case "email":
                    model.Email = formObject.GetStringValue(col, "");

                // company
                case "company":
                    model.Company = formObject.GetStringValue(col, "");

                // first name
                case "fname":
                    model.FirstName = formObject.GetStringValue(col, "");

                // last name
                case "lname":
                    model.LastName = formObject.GetStringValue(col, "");

                // title
                case "title":
                    model.Title = formObject.GetStringValue(col, "");

                // phone
                case "phone":
                    model.Phone = formObject.GetStringValue(col, "");

                // last name
                case "city":
                    model.City = formObject.GetStringValue(col, "");

                // last name
                case "state":
                    model.State = formObject.GetStringValue(col, "");

                // message
                case "comments":
                    model.Message = formObject.GetStringValue(col, "");

        // function that sends the given data to sales fource
        public void PostWebToLead(LeadModel model)
            // build the request
            var request = WebRequest.Create(Config.SalesForceWebToLeadURL);
            request.Method = "POST";

            // build the post data
            var sb = new StringBuilder()                .AppendFormat("oid={0}", Config.SalesForceOID)
                .AppendFormat("&{0}={1}", "company", model.Company)
                .AppendFormat("&{0}={1}", "first_name", model.FirstName)
                .AppendFormat("&{0}={1}", "last_name", model.LastName)
                .AppendFormat("&{0}={1}", "email", model.Email)
                .AppendFormat("&{0}={1}", "title", model.Title)
                .AppendFormat("&{0}={1}", "city", model.City)
                .AppendFormat("&{0}={1}", "state", model.State)
                .AppendFormat("&{0}={1}", "phone", model.Phone)
                .AppendFormat("&{0}={1}", "description", model.Description)
                .AppendFormat("&{0}={1}", "lead_source", model.LeadSource)

            // convert post data to byte[]
            byte[] byteArray = Encoding.UTF8.GetBytes(sb.ToString());
            request.ContentType = "application/x-www-form-urlencoded";
            request.ContentLength = byteArray.Length;

            // write to request
            Stream dataStream = request.GetRequestStream();
            dataStream.Write(byteArray, 0, byteArray.Length);

            // get a response, read into string
            WebResponse response = request.GetResponse();
            dataStream = response.GetResponseStream();
            StreamReader reader = new StreamReader(dataStream);
            string responseFromServer = reader.ReadToEnd();
            // clean up

        // dispose
        public void Dispose() { }

        // define model
        public class LeadModel
            // define fields
            public string Company { get; set; }
            public string FirstName { get; set; }
            public string LastName { get; set; }
            public string Email { get; set; }
            public string Title { get; set; }
            public string City { get; set; }
            public string State { get; set; }
            public string Phone { get; set; }
            public string Message { get; set; }
            public string Description { get; set; }

            public string LeadSource
                get { return "Web"; }

Last, you need to add an event handler so we can pick up when a form has been submitted and push that data to SalesForce. Create a new class in your App_Code folder for the following class:

// add these includes
using CMS.FormEngine;
using CMS.SettingsProvider;

public partial class CMSModuleLoader
    // define class for events
    private class CustomDocumentEventsAttribute : CMSLoaderAttribute
        // init - add events
        public override void Init()
            // set event handlers
            ObjectEvents.Insert.After += Insert_After;

        // event handler for after insert for an object
        void Insert_After(object sender, ObjectEventArgs e)
            // check if a form record added
            if (e.Object is BizFormItem)
                // push to sales force
                using( var s = new roma.SalesForceService())