Welcome to Part 5 of this series! I wasn't expecting to add more to this series, but as I continue to improve my Salesforce skills on the job I continue to find additional topics I'd like to share.
This week I'm going to show you how to automatically add new records to a Salesforce object in a C# application. The ability to programmatically add new records comes in handy when your application runs into, for example, a contact that does not already exist in the system but does have existing information elsewhere (such as in your database). Instead of expecting the person who created the incoming RMA to create a new Contact or potentially many new Contacts, you can simply ask them to input an email address and run a query to use or create a Contact matching it.
At this point I assume you have some form of working C# application. This doesn't need to be identical to my previous examples or even have a web service/outbound message relationship at all, but it does need to be set up to log in, query, and make changes with Salesforce using binding. If you don't already have this functionality in place, you can reference my previous posts in the series to work through most of it and I highly recommend this documentation for setting up Salesforce Logins.
Determining Whether A Contact Already Exists In Salesforce
The first thing to do is ensure we don't already have a Contact in Salesforce - nobody likes duplicated data! If you're unfamiliar with querying for an object, take a look at Part 4 of this series either using the circles above or here: Retrieving and Updating Salesforce Object Fields. Once you've got your unique information from the database (in this case an email address) you can query Salesforce using this.
As an aside: in the case of potential multiple contacts being processed at one time, I prefer to add them to a string as a comma separated list so I only hit Salesforce with a single query using "IN ()" instead of "=" in my query like so:
string contactQuery = $"SELECT Id, Name, Email, Account.Name, Account.Id, Account.identify_industry__c " +
$"FROM Contact WHERE Contact.Email IN ({CommaSeparatedShippingContactEmails(shippedContactsFromDB)})";
private string CommaSeparatedShippingContactEmails(List<string> shippedContactsFromDB)
{
foreach (string email in shippedContactsFromDB)
{
if (_emailCsv == "")
_emailCsv = $"'{email}'";
else
_emailCsv += $", '{email}'";
}
return _emailCsv;
}
In case what I did there was unclear, I take each email address from the list I gathered from the database and add it to a string while inserting a comma between every email after the first and before last and finally return the list in my Salesforce query. The end result will look something like this when it's received by Salesforce:
string contactQuery = $"SELECT Id, Name, Email, Account.Name, Account.Id, Account.identify_industry__c " +
$"FROM Contact WHERE Contact.Email IN ('bob@bobthebuilder.com', 'fred@awesomecomputers.com', 'sue@gmail.com')";
This will provide a result set of all Contacts in your current Salesforce Org that match the email addresses in the query. You can compare the emails in this result set against the emails in your original list to determine which Contacts do not exist and should be added. There may be better ways to perform this task, but this is how I go about getting a list of Contacts to add to Salesforce:
private void GetListOfContactsNotInSalesforce(List<string> shippedContactsFromDB)
{
foreach (var shipped in shippedContactsFromDB)
{
bool match = false;
foreach (var sfItem in contactsRetrievedFromSalesforce)
{
if (sfItem == shipped)
match = true;
}
if (!match)
contactsToAddToSalesforce.Add(shipped);
}
}
I pass in my original list of Contact email addresses from the database and for each email address I set "match" to false to indicate that it has not already been found as I loop through the list of Contacts found in Salesforce. If an email makes it through without matching a single item in the Salesforce Contacts list, this indicates it is not in Salesforce and it gets added to a new list.
Adding New Contacts To Salesforce
Now that we have a list of Contacts that aren't already in Salesforce we can use our binding similarly to how we update fields, but instead of using binding.update() we're going to use binding.create(). If you'd like to learn more about binding, click their links for the documentation provided by Salesforce.
The process is just as simple as updating Salesforce fields and looks very similar:
foreach (var contact in contactsToAddToSalesforce)
{
ObjectResult<sp_BSYNC_GetShipmentsForServiceCloud_Result> incomingShipments = context.sp_BSYNC_GetShipmentsForServiceCloud();
foreach (var ship in incomingShipments)
{
if (ship.conEmail == contact && !alreadyCreated.Contains(ship.conEmail))
{
try
{
Contact newContact = new Contact
{
FirstName = ship.FirstName,
LastName = ship.LastName,
Email = ship.conEmail,
Phone = ship.conPhone,
MailingStreet = ship.SH_ShipToAddress,
MailingCity = ship.SH_ShipToCity,
MailingState = ship.State,
MailingPostalCode = ship.SH_ShipToPostalCode,
MailingCountry = ship.SH_ShipToCountry,
AccountId = GetAccountIdFromSalesforce(ship.SH_ShipToName)
};
SaveResult[] results = Form1.ProcessMonitor.binding.create(new sObject[] { newContact });
alreadyCreated.Add(ship.conEmail);
}
catch (Exception e)
{
UpdateProcessingMonitorText(
$"{DateTime.Now}: Error in Contact creation process for {ship.conEmail}{Environment.NewLine}{e}");
}
}
}
}
A lot happened here, so let me explain: I start by looping through each email address in the list I created of Contacts to add to Salesforce. Because I only stored the email address from the database at the start, I have to retrieve my full list of database Contacts again using a stored procedure (you could also use a table instead). Looping through the list of Contacts provided by the stored procedure, I can compare each email address to those in my Salesforce list and use only the records that match the email address I'm currently working with.
Once I've confirmed a match between my Salesforce list and the stored procedure result, I create the new Contact in Salesforce using all of the information I gathered and call the binding.create() method on the new Contact to add it to Salesforce. Similarly to updating a field with an Id to create a relationship, I check for any Accounts that match the company name of my Contact and return the Salesforce Id to give my Contact a relationship to its corresponding Account (if it exists).
Note: To avoid accidentally creating any duplicate entries in Salesforce, I keep a secondary list of Contacts that is populated as I create new references and compare against it before creating each new Contact.
A few moments after creation you should see your new Contact(s) in Salesforce. It's a good idea to verify any relationships as well, if you've opted to add those.
I hope you're enjoying my Salesforce series and I also hope you're learning a little bit along with me as I share what I've been doing on the job. If you have any Salesforce topics you'd like me to cover next in this series, please don't hesitate to ask! I love a challenge and have found that I thoroughly enjoy working with Salesforce using C# applications. Thanks for reading!