Integrating Dux-Soup with Zoho CRM
With LinkedIn members now surpassing 750 million (756 million to be precise, according to LinkedIn) it’s clear that the platform remains the #1 B2B social selling network.
As more and more people use LinkedIn automation as an integrated and vital part of their overall lead generation process - we’re delighted to bring you a practical CRM integration blueprint designed by Martin Blonk, an automation process consultant who specialises in the Zoho CRM platform.
Zoho CRM was recently cited in a 2021 Gartner Magic Quadrant as a visionary in CRM Lead Management - due to the robust solution, exceptional customer experience, and increased market presence.
And, with more and more Dux-Soup users utilizing the Zoho CRM platform, it feels timely to bring you this step by step guide that Dux-Soup Turbo users can follow today.
The manual shows how you can integrate Dux-Soup with Zoho CRM to automatically create and update contact records in Zoho CRM with your LinkedIn activity - including messages sent and received
This enriches your Zoho CRM data - creating new contacts and enhancing your prospects CRM profile so you can better assess who is qualified and ready to buy.
Enjoy!
Introduction by Martin Blonk
In this manual I run through the steps needed to integrate Dux-Soup Turbo with Zoho CRM. The Zoho CRM integration that I built consists of three functions:
● Creating / Updating CRM Contact records from Visits or Connection requests via the Dux-Soup Webhook function.
● Sending LinkedIn messages (sent and received) from Dux-Soup to Zoho CRM and relating them to the Contacts.
● Sending messages from CRM to Dux-Soup via Remote Control (not in this manual yet)
Content
Zoho products used
Preparing Zoho CRM
Relating the Dux-Soup user id to the CRM User ID
Adding custom field(s) to the Contact record in Zoho CRM
Filling the Dux-Soup fields in the user record
Setting up Zoho Flow
Dux-Soup visits to CRM
Dux-Soup (LinkedIn) Messages to CRM
Testing
Appendix
Zoho products used
In order to make this integration work you need Zoho Flow and Zoho CRM. I used the Zoho One versions of these products, which means that Zoho CRM is the Enterprise edition and Zoho Flow the professional edition.
If you generate a lot of traffic via the integration you may need to purchase extra task credits for Zoho Flow and extra API credits for Zoho CRM.
Preparing Zoho CRM
Relating the Dux-Soup user id to the CRM User ID
In order to be able to relate the LinkedIn leads that come in from Dux-Soup to the right CRM user (as owner of the lead) you need to enter some Dux-Soup information in the CRM User record, and so you need to create custom fields. You need to have Administrator access to the CRM in order to configure this:
● In Zoho CRM go to Setting and click Users
![](https://cdn.prod.website-files.com/632194ff304e3aa238ad7ab8/632852dd2bb524abc5d0bea6_60da125f2b27b03d1cead7e8_Zoho1.png)
● In the User section, edit a User Record and click "Manage Fields":
![](https://cdn.prod.website-files.com/632194ff304e3aa238ad7ab8/632852dd2bb5245497d0bea7_60da1283ef476133d093609b_zoho2.png)
● Add 3 fields to the user record template
○ Duxsoup user ID
○ Duxsoup Remote Control URL
○ Duxsoup personal Key
For the field types see the picture below. NOTE: use the field names exactly as typed above (including exactly the upper- en lowercase characters. If you change this you will need to do a lot of troubleshooting before the integration will function properly.
![](https://cdn.prod.website-files.com/632194ff304e3aa238ad7ab8/632852dd2bb524823cd0be7d_60da12b480a2a030570541be_zoho%25203.png)
● After adding the fields click the "Save and Close" button to store the new fields
![](https://cdn.prod.website-files.com/632194ff304e3aa238ad7ab8/632852dd2bb5241651d0be74_60da12f92b27b0aadfeb6161_zoho4.png)
Adding custom field(s) to the Contact record in Zoho CRM
● Go to Settings and click Modules and Fields
![](https://cdn.prod.website-files.com/632194ff304e3aa238ad7ab8/632852dd2bb524df88d0bea0_60da132cc721654499338a4e_zoho5png.png)
● In Modules and Fields click Contacts
![](https://cdn.prod.website-files.com/632194ff304e3aa238ad7ab8/632852dd2bb5248628d0bea2_60da13543b375de3f3e0a39c_zoho7.png)
● In Contacts click the layout to which you want to add the fields (if you have more than one layout defined):
![](https://cdn.prod.website-files.com/632194ff304e3aa238ad7ab8/632852dd2bb524f852d0be83_60da138286a34fcfd737286c_zoho8.png)
● In the layout make sure you create the field:
● LinkedIn (again with the same upper- and lowercase characters)
The field has to be of type url and it has to be set to unique:
![](https://cdn.prod.website-files.com/632194ff304e3aa238ad7ab8/632852dd2bb52482a7d0bea4_60da13b3c86e044f9deac02c_zoho9.png)
● In this field the LinkedIn profile url of the contact will be stored. You might already have a field for storing the LinkedIn profile url of a contact. In this case make sure that it is of the right type (url) and is unique and the API name of the field is "LinkedIn".
● You could create more fields e.g. for storing the connection status but that is not part of this manual.
Filling the Dux-Soup fields in the user record
In order to relate the Zoho CRM user account to the Dux-Soup user account we need to fill the fields that we created earlier in the Zoho CRM record with the values from Dux-Soup:
![](https://cdn.prod.website-files.com/632194ff304e3aa238ad7ab8/632852dd2bb524b18bd0be91_60da13fdb64cdd776223f16e_Zoho10.png)
In the Duxsoup user ID, enter the Dux-Soup user ID that you find in the Dux Dash:
![](https://cdn.prod.website-files.com/632194ff304e3aa238ad7ab8/632852dd2bb524cfb8d0be9a_60da14378f332adac32e25da_zoho11.png)
In the field Duxsoup Remote Control URL, enter the "Personal remote control url" that you can find in the Options / Connect screen and in the Duxsoup Personal Key, enter the "Personal remote control authentication key"
Setting up Zoho Flow
In Zoho Flow you will need to create a Connection to Zoho CRM. Use an account with at least the "Standard" (preferably Administrator) profile in CRM to create the connection.
Dux-Soup visits to CRM
Here you set up the sync of visits you make to Zoho CRM. NOTE: Disable the Webhook in Dux-Soup when you are browsing. Only switch it on when you use the Robot to visit (& connect) LinkedIn profiles.
Start with creating a Flow in Zoho Flow of the type "Webhook":
![](https://cdn.prod.website-files.com/632194ff304e3aa238ad7ab8/632852dd2bb5240b80d0be9f_60da14788403d9196f3d58b0_Zoho12.png)
Choose payload format JSON and you may copy the Webhook url now (or later).
![](https://cdn.prod.website-files.com/632194ff304e3aa238ad7ab8/632852dd2bb524a265d0be81_60da149d7b282ba66b87ef04_zoho13.png)
This webhook url goes to the Options/ Connect screen in Dux-Soup (check the "Visit" checkmark); leave the Webhook switch off for now:
![](https://cdn.prod.website-files.com/632194ff304e3aa238ad7ab8/632852dd2bb524bea3d0be95_60da14e9b963ad15e2d5a93b_zoho14.png)
In Zoho Flow, click Next and skip the test step (just click Done):
![](https://cdn.prod.website-files.com/632194ff304e3aa238ad7ab8/632852dd2bb52468e8d0bea3_60da150fbf54ec48d00a32dd_zoho15.png)
![](https://cdn.prod.website-files.com/632194ff304e3aa238ad7ab8/632852dd2bb524e7add0be85_60da15416f91336c2cae19c5_zoho15.png)
Now you may create the following flow; this may look complicated but most steps are necessary.
![](https://cdn.prod.website-files.com/632194ff304e3aa238ad7ab8/632852dd2bb52459d4d0beaa_60da1573b9903a727a15fb81_zoho16.png)
The syntax custom functions used in this flow are listed in the Appendix.
Below the description and config of each numbered item; NOTE: the "_<number" in variables may differ when you create a flow, e.g: the fetchUserByDuxsoupID_7 from step 2 could in your case be fetchUserByDuxsoupID_5 (this goes for all variable/output names).
1: Custom function to fetch the CRM User account based on the Dux-Soup user ID
![](https://cdn.prod.website-files.com/632194ff304e3aa238ad7ab8/632852dd2bb524af1bd0be89_60da15941950067c5cc80745_zoho18.png)
2: If the CRM user account is not found, send an email to the admin (error)
![](https://cdn.prod.website-files.com/632194ff304e3aa238ad7ab8/632852dd2bb524525bd0be98_60da15baf3fba7383ad2a1cb_zoho19.png)
3: Email with error message
![](https://cdn.prod.website-files.com/632194ff304e3aa238ad7ab8/632852dd2bb524164cd0be79_60da15dde0c607d93eb74fdf_zoho19.png)
4: This variable holds the value of the event from Dux-Soup; this can be "create" or "update". We need this later in order to avoid creation of duplicate records in CRM.
![](https://cdn.prod.website-files.com/632194ff304e3aa238ad7ab8/632852dd2bb524f0a6d0be7b_60da16073483b08d2ab09908_zoho20.png)
5: Fetch the CRM user based on the output of 1
![](https://cdn.prod.website-files.com/632194ff304e3aa238ad7ab8/632852dd2bb524093ad0be92_60da1629903f7b7c3740425e_zoho21.png)
6: Optional: get the City from the LinkedIn location
![](https://cdn.prod.website-files.com/632194ff304e3aa238ad7ab8/632852dd2bb5240155d0be99_60da1654a495e654f3c23983_zoho21.png)
7: Fetch the Account based on the LinkedIn Company
![](https://cdn.prod.website-files.com/632194ff304e3aa238ad7ab8/632852dd2bb524aeabd0be82_60da1677b9903af2b816c565_zoho.png)
8: Decision - type of event is "create" or "update"; if "update" delay of 2 minutes in order to avoid duplicate records
![](https://cdn.prod.website-files.com/632194ff304e3aa238ad7ab8/632852dd2bb5244de2d0be7e_60da16b45807b377987f14df_zoho.png)
9: Delay of 2 minutes
![](https://cdn.prod.website-files.com/632194ff304e3aa238ad7ab8/632852dd2bb5246e3fd0be84_60da16dc0e971f327e386e41_zoho.png)
10: Decision - if Account does not exist - create new Account
![](https://cdn.prod.website-files.com/632194ff304e3aa238ad7ab8/632852dd2bb52433b0d0bea1_60da16fe19035185be02e9e2_zoho.png)
11: Create new account; this is a long form and I only show the filled in variables
![](https://cdn.prod.website-files.com/632194ff304e3aa238ad7ab8/632852dd2bb524b233d0be8a_60da17245807b323937f4864_zoho.png)
![](https://cdn.prod.website-files.com/632194ff304e3aa238ad7ab8/632852dd2bb52497b7d0be8d_60da17422993ce814af7121a_zoho.png)
![](https://cdn.prod.website-files.com/632194ff304e3aa238ad7ab8/632852dd2bb5249e59d0be7f_60da178be6c8bf373daec348_zoho.png)
(lead source)
![](https://cdn.prod.website-files.com/632194ff304e3aa238ad7ab8/632852dd2bb524fa96d0be97_60da17c02da8ba2e04d258af_zoho%25201.png)
![](https://cdn.prod.website-files.com/632194ff304e3aa238ad7ab8/632852dd2bb5247875d0be93_60da17e186a34f52853af195_zoho%25201.png)
![](https://cdn.prod.website-files.com/632194ff304e3aa238ad7ab8/632852dd2bb52435b3d0be96_60da1805e03eebd0a64be1b6_zoho%25201.png)
12: Custom function to search contact in CRM based on LinkedIn profile
![](https://cdn.prod.website-files.com/632194ff304e3aa238ad7ab8/632852dd2bb5247838d0be76_60da183ce840d1bd6c70a59f_zoho%25201.png)
13: Decision - if contact exists; update contact, or else create a new contact
![](https://cdn.prod.website-files.com/632194ff304e3aa238ad7ab8/632852dd2bb524fe2ad0be7a_60da185fc665726990091228_zoho%25201.png)
14: Create contact (contact does not exist in CRM); this again is a long form and only the filled in values are shown:
![](https://cdn.prod.website-files.com/632194ff304e3aa238ad7ab8/632852dd2bb5246116d0be90_60da188ee840d16c8070cd07_zoho%25201.png)
![](https://cdn.prod.website-files.com/632194ff304e3aa238ad7ab8/632852dd2bb52407aed0be86_60da18ac547b58f438c353a7_zoho%25201.png)
![](https://cdn.prod.website-files.com/632194ff304e3aa238ad7ab8/632852dd2bb5242433d0be88_60da18d2c3aa0c4a4c897097_zoho%25201.png)
![](https://cdn.prod.website-files.com/632194ff304e3aa238ad7ab8/632852dd2bb5244355d0be8c_60da19047eb517946bf4e25e_zoho%25201.png)
![](https://cdn.prod.website-files.com/632194ff304e3aa238ad7ab8/632852dd2bb524f94cd0be75_60da192dda854b1d6fdd59ab_zoho%25201.png)
![](https://cdn.prod.website-files.com/632194ff304e3aa238ad7ab8/632852dd2bb524190ad0be8b_60da195cc3aa0c66f689cc71_zoho%25201.png)
![](https://cdn.prod.website-files.com/632194ff304e3aa238ad7ab8/632852dd2bb5241f62d0be9c_60da197f5844c8815b3f9533_zoho%25201.png)
![](https://cdn.prod.website-files.com/632194ff304e3aa238ad7ab8/632852dd2bb52463aed0be9d_60da19a3547b586281c3c21e_zoho%25201.png)
![](https://cdn.prod.website-files.com/632194ff304e3aa238ad7ab8/632852dd2bb5246f87d0be94_60da19c68371ccb924f9e0bb_zoho%25201.png)
15: Update contact (contact exists in Zoho CRM); this again is a long form and only the filled in values are shown
![](https://cdn.prod.website-files.com/632194ff304e3aa238ad7ab8/632852dd2bb524bb54d0be8f_60da1a003c24c70c64cff134_zoho%25201.png)
Last name, Owner, First Name, Email, Account Name : see 14
Lead source is not filled in (because the contact already existed)
Dux-Soup (LinkedIn) Messages to CRM
The following flow logs the sent and received LinkedIn message to the CRM contacts. This flow adds a LinkedIn message as a Note to a contact. It is also possible to make a custom related module "LinkedIn messages" in the CRM and store the messages in that module. This will not be covered in this manual.
In Zoho Flow create a new flow of type "Webhook" again and copy the Webhook url in a second link in Dux-Soup:
![](https://cdn.prod.website-files.com/632194ff304e3aa238ad7ab8/632852dd2bb5241ad5d0bea8_60da1a5172e4822afcb2ad72_zoho%25201.png)
Only the "Message" checkbox should be checked and the Message Bridge should be switched on.
The flow looks like this:
![](https://cdn.prod.website-files.com/632194ff304e3aa238ad7ab8/632852dd2bb524cd46d0bea9_60da1a6efb8941a5f4180a40_zoho%25201.png)
Explanation of the flow steps:
1: Stores message type
![](https://cdn.prod.website-files.com/632194ff304e3aa238ad7ab8/632852dd2bb5249862d0be9e_60da1aa169673566fa4e5271_zoho%25201.png)
2: Stores "sent" or "received"
![](https://cdn.prod.website-files.com/632194ff304e3aa238ad7ab8/632852dd2bb5247b63d0be7c_60da1acf5550717263f22f2b_zoho%25201.png)
3: Custom function (same as used in the Visits flow) to find contact in CRM
![](https://cdn.prod.website-files.com/632194ff304e3aa238ad7ab8/632852dd2bb524209dd0be9b_60da1aee4da48ad23e7d891c_zoho%25201.png)
Note that in this flow two payload variables are concatenated; this is because in all cases only one of these two variables has a value.
4: Decision: only proceed when contact is found in CRM
![](https://cdn.prod.website-files.com/632194ff304e3aa238ad7ab8/632852dd2bb52415e7d0be80_60da1b0c91f111700872bafb_zoho%25201.png)
Note: one could extend the flow by creating a new contact when a contact is not found. In this example I have chosen to only add messages to existing contacts.
5: Determine message type (accept of message) (custom function in Appendix)
![](https://cdn.prod.website-files.com/632194ff304e3aa238ad7ab8/632852dd2bb5240753d0be77_60da1b3086c8f450d1be81d5_zoho%25201.png)
6: Fetch contact in CRM
![](https://cdn.prod.website-files.com/632194ff304e3aa238ad7ab8/632852dd2bb52475cbd0bea5_60da1b4d86c8f44b6dbea2c6_zoho%25201.png)
7: Fetch user in CRM (for owner of the Note in CRM).
![](https://cdn.prod.website-files.com/632194ff304e3aa238ad7ab8/632852dd2bb524df02d0be78_60da1b7410fe4de6cf207164_zoho%25201.png)
8: Convert time (different format in Dux-Soup and CRM); custom function
![](https://cdn.prod.website-files.com/632194ff304e3aa238ad7ab8/632852dd2bb52441f2d0be87_60da1ba2f3fba71f49d3de9d_zoho%25201.png)
9: Add message to Contact in the form of a Note; custom function.
![](https://cdn.prod.website-files.com/632194ff304e3aa238ad7ab8/632852dd2bb524299bd0be8e_60da1bc464ff4255ff86f096_zoho%25201.png)
Testing
After you have setup the flows, you can test them from the Dux-Soup options panel (with the "Send Sample" buttons:
![](https://cdn.prod.website-files.com/632194ff304e3aa238ad7ab8/632852dd2bb52481ddd0beac_60da1bfaa77d527290ce9953_zoho%25201.png)
Success!
Please do reach out to me if you have questions about this integration or any aspect of Zoho CRM.
About the Author
![](https://cdn.prod.website-files.com/632194ff304e3aa238ad7ab8/632852dd2bb524375ad0beab_60dad5e512f09afafe62df9b_Picture1_Martin%2520B.png)
Martin Blonk, ICT & Business Process Automation
I love to help people implement back office functions like Zoho CRM, Zoho Social and other appropriate software applications.
I speak the language of the entrepreneur and pay close attention to formulating the real question/need; as a result, I propose solutions that directly benefit you.
With more than 30 years of experience in ICT and more than 20 years of experience in automating business processes – feel free to reach out to me today to talk about how I can help your business.
Book some time to chat: https://www.martinblonk.com/contact
Email:martin@martinblonk.com
Web: www.martinblonk.com
Appendix
Custom functions in Zoho Flow
fetchUserByDuxsoupID
string fetchUserByDuxsoupID(string duxsoupID)
{
if(!(duxsoupID == null || duxsoupID == ""))
{
mp = Map();
users = zoho.crm.invokeConnector("crm.getusers",mp);
response = users.get("response").get("users");
for each user in response
{
p_duxsoupID = ifNull(user.getJSON("Duxsoup_user_ID"),"");
if(!p_duxsoupID == null)
{
p_Email = ifNull(user.getJSON("email"),"");
if(p_duxsoupID == duxsoupID)
{
return p_Email;
}
}
}
}
return "";
}
getCityFromLocation
string getCityFromLocation(string LILocation)
{
//Function to get the city from the LinkedIn location
hasComma = LILocation.find(",");
if(hasComma <= 0)
{
return LILocation;
}
else
{
return LILocation.left(hasComma);
}
}
searchContactByLinkedIN
string searchContactByLinkedIN(string LIProfile)
{
LIProfile = trim(LIProfile);
if(LIProfile.subString(LIProfile.length() - 1) == "/")
{
LIProfile = left(LIProfile,LIProfile.length() - 1);
}
//info LIProfile;
searchVar = "(LinkedIn:starts_with:" + trim(LIProfile) + ")";
resp = zoho.crm.searchRecords("Contacts",searchVar);
if(resp.isEmpty())
{
return "";
}
else
{
return resp.getJSON("id");
}
}
determineAcceptOrMessage
string determineAcceptOrMessage(string messageType, string messageText)
{
messageText = trim(messageText);
if(messageType.toUpperCase() == "INVITATION_ACCEPT")
{
result = "Invitation Accepted";
}
else
{
result = messageText;
}
return result;
}
convertTime
string convertTime(string timestamp)
{
//info timestamp;
myDate = timestamp.toTime("yyyy-MM-d'T'HH:mm:ss.SSS'Z'");
//info myDate;
dateTime = myDate.toString("yyyy-MM-dd'T'HH:mm:ss'Z'");
return dateTime;
}
addMessageToContactNote
void addMessageToContactNote(string messageText, string messageUrl, string messageType, string receivedOrSent, string timestamp, string contID, string noteOwner)
{
if(receivedOrSent == "received")
{
noteText = "Received message\n\n";
}
else if(receivedOrSent == "sent")
{
noteText = "Sent message\n\n";
}
noteText = noteText + "Message - type: " + messageType + "\n\n";
noteText = noteText + "Message-text: " + messageText + "\n" + "\n" + "Link to message: " + messageUrl + "\n";
myDate = timestamp.toTime("yyyy-MM-d'T'HH:mm:ss'Z'","Etc/UTC");
dateTime = myDate.toString("dd-MM-yyyy HH:mm:ss","Europe/Amsterdam");
newNote = Map();
newNote.put("Owner",noteOwner);
newNote.put("se_module","Contacts");
newNote.put("Parent_Id",contID);
newNote.put("Note_Title","LinkedIn message dd.: " + dateTime);
newNote.put("Note_Content",noteText);
resp = zoho.crm.createRecord("Notes",newNote);
info resp;
}
© Martin Blonk | martin@martinblonk.com, | www.martinblonk.com