void schedule.IntegratedLeadProcessing()
{
// STEP 1: Retrieve Leads from CRM
leads = zoho.crm.getRecords("Leads",1,200);
if(leads == null || leads.size() == 0)
{
return;
}
// STEP 2: Process Timeline Engagement & Update Lead Status
currentDate = zoho.currentdate.toDate();
thirtyDaysAgo = currentDate.addDay(-30);
leadIds = list();
for each lead in leads
{
if(lead.get("id") != null)
{
leadIds.add(lead.get("id"));
}
}
timelineMap = Map();
for each leadId in leadIds
{
timelineURL = "
https://www.zohoapis.com/crm/v7/Leads/" + leadId + "/__timeline?sort_by=audited_time" + "&include_inner_details=field_history.data_type,field_history.field_label,field_history.enable_colour_code,field_history.pick_list_values,done_by.type__s,done_by.profile";
timelineResponse = invokeurl
[
url :timelineURL
type :GET
connection:"zoho_crm"
];
timelineList = list();
if(timelineResponse.containsKey("__timeline"))
{
timelineList = timelineResponse.get("__timeline");
}
timelineMap.put(leadId,timelineList);
}
leadEngagementMap = Map();
desiredModules = list();
desiredModules.add("calls");
desiredModules.add("meetings");
desiredModules.add("emails");
desiredModules.add("tasks");
for each lead in leads
{
leadId = lead.get("id");
leadName = ifnull(lead.get("Lead_Name"),ifnull(lead.get("Full_Name"),"Unknown Lead"));
createdTimeStr = lead.get("Created_Time");
if(createdTimeStr != null)
{
createdDate = createdTimeStr.toDate("yyyy-MM-dd'T'HH:mm:ssXXX");
}
else
{
createdDate = currentDate;
}
lastEngagementDate = null;
engagementDates = list();
leadTimeline = timelineMap.get(leadId);
for each event in leadTimeline
{
if(event.containsKey("audited_time") && event.containsKey("record"))
{
rec = event.get("record");
moduleName = "";
if(rec.containsKey("link_data"))
{
linkData = rec.get("link_data");
if(linkData != null && linkData.size() > 0)
{
moduleName = linkData.get(0);
}
}
if(moduleName == "" && rec.containsKey("module") && rec.get("module").containsKey("api_name"))
{
moduleName = rec.get("module").get("api_name");
}
if(moduleName == "" && event.containsKey("description"))
{
description = event.get("description").toLowerCase();
if(description.contains("task"))
{
moduleName = "tasks";
}
else if(description.contains("call"))
{
moduleName = "calls";
}
else if(description.contains("meeting"))
{
moduleName = "meetings";
}
else if(description.contains("email"))
{
moduleName = "emails";
}
}
moduleNameLower = moduleName.toLowerCase();
if(desiredModules.contains(moduleNameLower))
{
try
{
eventTimeStr = event.get("audited_time");
eventDate = eventTimeStr.toDate("yyyy-MM-dd'T'HH:mm:ssXXX");
engagementDates.add(eventDate);
}
catch (e)
{
}
}
}
}
if(engagementDates.size() > 0)
{
mostRecentEvent = engagementDates.get(0);
for each dt in engagementDates
{
if(dt.toLong() > mostRecentEvent.toLong())
{
mostRecentEvent = dt;
}
}
lastEngagementDate = mostRecentEvent;
}
else
{
lastEngagementDate = createdDate;
}
daysSinceEngagement = (currentDate.toLong() - lastEngagementDate.toLong()) / 86400000;
if(engagementDates.size() > 0)
{
if(daysSinceEngagement <= 7)
{
leadStatus = "Hot";
}
else if(daysSinceEngagement <= 14)
{
leadStatus = "Warm";
}
else
{
leadStatus = "Cold";
}
}
else
{
leadStatus = "Cold";
}
updateData = Map();
updateData.put("Last_Engagement_Date",lastEngagementDate.toString("yyyy-MM-dd"));
updateData.put("Lead_Status",leadStatus);
leadEngagementMap.put(leadId,updateData);
}
for each leadId in leadEngagementMap.keys()
{
updateData = leadEngagementMap.get(leadId);
updateResp = zoho.crm.updateRecord("Leads",leadId,updateData);
}
// STEP 3: Apply Score Decay Adjustments
scoringRules = list();
scoringRules.add("Industry_Fit");
scoringRules.add("Company_Size");
scoringRules.add("Location_Priority");
scoringRules.add("Intent");
scoringRules.add("Buying_Group_Role");
baseScores = Map();
baseScores.put("Industry_Fit",0);
baseScores.put("Company_Size",15);
baseScores.put("Location_Priority",10);
baseScores.put("Intent",0);
baseScores.put("Buying_Group_Role",0);
processedCount = 0;
updatedCount = 0;
for each lead in leads
{
processedCount = processedCount + 1;
leadId = lead.get("id");
positiveTP = ifnull(lead.get("Positive_Touch_Points"),0).toLong();
negativeTP = ifnull(lead.get("Negative_Touch_Points"),0).toLong();
engaged = positiveTP > 0 && positiveTP > negativeTP;
refDate = lead.get("Last_Engagement_Date");
if(refDate != null)
{
refDate = refDate.toDate();
}
else
{
refDate = lead.get("Created_Time");
if(refDate != null)
{
refDate = refDate.toDate();
}
}
updateData = Map();
if(engaged)
{
updateData.put("Score_Decay_Counter",0);
updateData.put("Score_Decay_Reason","");
for each rule in scoringRules
{
currentScore = 0;
try
{
currentScore = ifnull(lead.get(rule),"0").toDecimal();
}
catch (e)
{
currentScore = 0;
}
baseScore = baseScores.get(rule).toDecimal();
if(currentScore < baseScore)
{
updateData.put(rule,baseScore);
}
}
}
else if(refDate != null)
{
daysInactive = (currentDate.toLong() - refDate.toLong()) / 86400000;
if(daysInactive >= 14)
{
decayCounter = (daysInactive / 14).toLong();
for each rule in scoringRules
{
currentScore = 0;
try
{
currentScore = ifnull(lead.get(rule),"0").toDecimal();
}
catch (e)
{
currentScore = 0;
}
if(currentScore > 0)
{
updateData.put(rule,currentScore * 0.95);
}
}
updateData.put("Score_Decay_Counter",decayCounter);
updateData.put("Score_Decay_Reason","Score reduced due to lack of engagement (" + daysInactive.toLong() + " days since last engagement)");
}
}
if(updateData.size() > 0)
{
updateResponse = zoho.crm.updateRecord("Leads",leadId,updateData);
updatedCount = updatedCount + 1;
}
}
// STEP 4: Process Tagging for Leads
getTagsResp = invokeurl
[
url :settingsUrl
type :GET
connection:"zoho_crm"
];
existingTagsList = list();
if(getTagsResp.containsKey("tags"))
{
existingTagsList = getTagsResp.get("tags");
}
plannedTags = list();
plannedTags.add({"name":"Introduction","color_code":"#F17574"});
plannedTags.add({"name":"Rapport Building","color_code":"#F48435"});
plannedTags.add({"name":"Existing Business","color_code":"#E7A826"});
plannedTags.add({"name":"Closing","color_code":"#A8C026"});
plannedTags.add({"name":"0-5m/yr","color_code":"#63C57E"});
plannedTags.add({"name":"5-50m/yr","color_code":"#1DB9B4"});
plannedTags.add({"name":"50m-100m/yr","color_code":"#57B1FD"});
plannedTags.add({"name":"100m+/yr","color_code":"#879BFC"});
plannedTags.add({"name":"0-20 Users","color_code":"#D297EE"});
plannedTags.add({"name":"20-60 Users","color_code":"#FD87BD"});
plannedTags.add({"name":"60+ Users","color_code":"#969696"});
plannedTags.add({"name":"Wichita (Local)","color_code":"#658BA8"});
plannedTags.add({"name":"Mid West (Regional)","color_code":"#B88562"});
plannedTags.add({"name":"National","color_code":"#F17574"});
plannedTags.add({"name":"Data Incomplete","color_code":"#ECE81A"});
for each tagMap in plannedTags
{
plannedTagName = tagMap.get("name");
tagExists = false;
for each existTag in existingTagsList
{
if(existTag.get("name") == plannedTagName)
{
tagExists = true;
break;
}
}
if(!tagExists)
{
inputJSON = {"tags":{{"name":plannedTagName,"color_code":tagMap.get("color_code")}}};
createResp = invokeurl
[
url :createUrl
type :POST
parameters:inputJSON.toString()
connection:"zoho_crm"
];
}
}
updated_leads = 0;
for each lead in leads
{
leadId = lead.get("id");
newTagsList = list();
leadDetails = zoho.crm.getRecordById("Leads",leadId);
existingTags = ifnull(leadDetails.get("Tag"),list());
if(existingTags.size() > 0)
{
removeParam = Map();
removeParam.put("ids",list(leadId));
removeParam.put("tags",existingTags);
removeResp = invokeurl
[
url :removeTagsUrl
type :POST
parameters:removeParam.toString()
connection:"zoho_crm"
];
}
newTagsList.add("Data Incomplete");
if(newTagsList.size() > 0)
{
param = Map();
formattedTags = list();
for each tagName in newTagsList
{
formattedTags.add({"name":tagName});
}
param.put("tags",formattedTags);
param.put("ids",list(leadId));
tagResp = invokeurl
[
url :addTagsUrl
type :POST
parameters:param.toString()
connection:"zoho_crm"
];
updated_leads = updated_leads + 1;
}
}
// STEP 5: Lead Routing & Conversion
salesAgents = list();
salesAgents.add({"id":"owner_id","name":"owner_name"});
totalAgents = salesAgents.size();
currentAgentIndex = 0;
agentLeadCount = Map();
for each agent in salesAgents
{
agentLeadCount.put(agent.get("id"),{"name":agent.get("name"),"count":0});
}
allLeads = zoho.crm.getRecords("Leads",1,200);
if(allLeads == null || allLeads.isEmpty())
{
return;
}
for each lead in allLeads
{
leadOwner = lead.get("Owner");
if(leadOwner != null)
{
ownerId = leadOwner.get("id");
ownerName = leadOwner.get("name");
if(agentLeadCount.containsKey(ownerId))
{
agentLeadCount.put(ownerId,{"name":ownerName,"count":agentLeadCount.get(ownerId).get("count") + 1});
}
else
{
agentLeadCount.put(ownerId,{"name":ownerName,"count":1});
}
}
}
assignedLeads = 0;
for each lead in allLeads
{
if(lead.get("Owner") == null)
{
assignedAgent = salesAgents.get(currentAgentIndex % totalAgents);
updateData = Map();
updateData.put("Owner",assignedAgent.get("id"));
updateResp = zoho.crm.updateRecord("Leads",lead.get("id"),updateData);
assignedLeads = assignedLeads + 1;
if(agentLeadCount.containsKey(assignedAgent.get("id")))
{
agentLeadCount.put(assignedAgent.get("id"),{"name":assignedAgent.get("name"),"count":agentLeadCount.get(assignedAgent.get("id")).get("count") + 1});
}
else
{
agentLeadCount.put(assignedAgent.get("id"),{"name":assignedAgent.get("name"),"count":1});
}
currentAgentIndex = (currentAgentIndex + 1) % totalAgents;
}
}
convertedLeads = 0;
currentDate = zoho.currentdate.toDate();
sevenDaysAgo = currentDate.addDay(-7);
for each lead in allLeads
{
leadId = lead.get("id");
timeline = zoho.crm.getRelatedRecords("Activities","Leads",leadId);
if(timeline.isEmpty())
{
continue;
}
activityFound = false;
lastValidActivity = null;
for each activity in timeline
{
activityType = activity.get("Activity_Type");
activityStatus = activity.get("Status");
activityTime = activity.get("Created_Time").toDate();
if((activityType == "Call" || activityType == "Meeting") && activityTime >= sevenDaysAgo)
{
lastValidActivity = activity;
if(activityStatus == "Completed")
{
activityFound = true;
break;
}
}
}
if(activityFound)
{
conversionMap = Map();
dealList = list();
dealList.add("Deals");
dealList.add("Accounts");
conversionMap.put("create",dealList);
convertResp = zoho.crm.convertLead(leadId,conversionMap);
convertedLeads = convertedLeads + 1;
assignedAgent = salesAgents.get(currentAgentIndex % totalAgents);
dealData = Map();
dealData.put("Owner",assignedAgent.get("id"));
dealUpdateResp = zoho.crm.updateRecord("Deals",convertResp.get("Deals"),dealData);
currentAgentIndex = (currentAgentIndex + 1) % totalAgents;
}
}
}