An article to ensure I never spend this long on such a request again. The brief is: "Follow up when a lead is created and not converted within 1 day send an email and notification to sales person everyday for 3 days then escalate to a specified user".
Why?
Sorry Zoho! I tried using the interface to set up a workflow or any other mechanisms within ZohoCRM that allowed me to set up a daily reminder to the lead record owner but to no avail. An assignment rule wouldn't work in this case as it had to be the lead owner (there is no owner at assignment rule stage). A workflow email notification doesn't do the popup on the CRM as well. A workflow notify by email didn't give the option to remind daily... only weekly or monthly.
Spent a while trying not to use code but here we are. Code is our friend.
How?
So we'll run a workflow that triggers on the creation of a lead and runs a function which will simultaneously create a task with a reminder both on popup and email which repeats every day until an end date.
We then carry out the last bit of the brief with a separate workflow that runs exactly 4 days after the lead creation time and assigns it to the specified user (full name of user was given in the brief but removed here for privacy).
Finally, we delete any of these tasks when they get transferred to the contact record.
Step 1: Workflow on Create and function to create task:
Create a workflow that runs on lead create (record action) and the criteria can be where "Lead Conversion Time" is less than 4 (4 days not 4 business days?). Though I've removed this condition since go live and simply specified "All Leads".
I'm calling my function fn_Leads_FollowUpNonConverted with the parameter being the Lead Record ID:
/* ******************************************************************************* Function: void fn_Leads_FollowUpNonConverted(Int p_LeadID) Label: Fn - Leads - Follow Up Non Converted Lead Trigger: Triggered 24 hours after a lead is created. Purpose: Follow up when a lead is created and not converted within 1 day send an email and notification to sales person everyday for 3 days then escalate to Dan Inputs: The Lead Record ID Outputs: A task with a daily reminder until after 3 reminders Date Created: 2024-05-13 (Joel Lipman) - Initial release Date Modified: 2024-05-14 (Joel Lipman) - After the 3rd reminder (3 days overdue) then assign to Dan (set as a separate workflow 4 days after creation of lead? Ensure that when this has been converted to a contact it removes this task.) - Use connection as system user rather than default crm connection - Reminder cannot be set for task creation time so create task at the same time as lead and set reminders daily 24 hours after until end date ******************************************************************************* */ // // blank map to use m_Blank = Map(); // // set timezone of this user (this CRM is set to GMT-07:00 with daylight savings in effect) v_ThisTimeZone = "Europe/London"; // // get details from lead record r_LeadDetails = zoho.crm.getRecordById("Leads",p_LeadID); // // get created time (no need to check if null?) v_LeadCreatedTime = r_LeadDetails.get("Created_Time"); // // convert to time datatype v_TimeOffset = (v_LeadCreatedTime.subString(0,10) + " " + v_LeadCreatedTime.subString(11,25)).toString("yyyy-MM-dd HH:mm:ss", v_ThisTimeZone); // // set reminder time (exactly 1 working day after created time) v_RemindTime = v_TimeOffset.addBusinessDay(1).toString("yyyy-MM-dd'T'HH:mm:ss", v_ThisTimeZone); // // want the reminder to appear daily until 3 days after creation date (inclusive of 4th?) v_EndTime = v_TimeOffset.addBusinessDay(3).toString("yyyy-MM-dd'T'HH:mm:ss", v_ThisTimeZone); // // create the task at the same time as lead creation m_NewTask = Map(); m_NewTask.put("$se_module","Leads"); m_NewTask.put("Owner",r_LeadDetails.get("Owner").get("id")); m_NewTask.put("What_Id",p_LeadID); m_NewTask.put("Subject","Follow Up Non Converted Lead"); m_NewTask.put("Due_Date",v_EndTime.toDate()); m_NewTask.put("Status","Not Started"); // // configure reminder on task to run daily at the same time as creation time m_Reminder = Map(); m_Reminder.put("ALARM","FREQ=DAILY;UNTIL="+v_EndTime+"ACTION=EMAILANDPOPUP;TRIGGER=DATE-TIME:" + v_RemindTime); m_NewTask.put("Remind_At",m_Reminder); // // check what we're sending info m_NewTask; // // create the task in CRM r_NewResp = zoho.crm.createRecord("Tasks",m_NewTask, m_Blank, "systemcrm"); // // output response of task creation from CRM info r_NewResp;
- /* *******************************************************************************
- Function: void fn_Leads_FollowUpNonConverted(Int p_LeadID)
- Label: Fn - Leads - Follow Up Non Converted Lead
- Trigger: Triggered 24 hours after a lead is created.
- Purpose: Follow up when a lead is created and not converted within 1 day send an email and notification to sales person everyday for 3 days then escalate to Dan
- Inputs: The Lead Record ID
- Outputs: A task with a daily reminder until after 3 reminders
- Date Created: 2024-05-13 (Joel Lipman)
- - Initial release
- Date Modified: 2024-05-14 (Joel Lipman)
- - After the 3rd reminder (3 days overdue) then assign to Dan
- (set as a separate workflow 4 days after creation of lead? Ensure that when this has been converted to a contact it removes this task.)
- - Use connection as system user rather than default crm connection
- - Reminder cannot be set for task creation time so create task at the same time as lead and set reminders daily 24 hours after until end date
- ******************************************************************************* */
- //
- // blank map to use
- m_Blank = Map();
- //
- // set timezone of this user (this CRM is set to GMT-07:00 with daylight savings in effect)
- v_ThisTimeZone = "Europe/London";
- //
- // get details from lead record
- r_LeadDetails = zoho.crm.getRecordById("Leads",p_LeadID);
- //
- // get created time (no need to check if null?)
- v_LeadCreatedTime = r_LeadDetails.get("Created_Time");
- //
- // convert to time datatype
- v_TimeOffset = (v_LeadCreatedTime.subString(0,10) + " " + v_LeadCreatedTime.subString(11,25)).toString("yyyy-MM-dd HH:mm:ss", v_ThisTimeZone);
- //
- // set reminder time (exactly 1 working day after created time)
- v_RemindTime = v_TimeOffset.addBusinessDay(1).toString("yyyy-MM-dd'T'HH:mm:ss", v_ThisTimeZone);
- //
- // want the reminder to appear daily until 3 days after creation date (inclusive of 4th?)
- v_EndTime = v_TimeOffset.addBusinessDay(3).toString("yyyy-MM-dd'T'HH:mm:ss", v_ThisTimeZone);
- //
- // create the task at the same time as lead creation
- m_NewTask = Map();
- m_NewTask.put("$se_module","Leads");
- m_NewTask.put("Owner",r_LeadDetails.get("Owner").get("id"));
- m_NewTask.put("What_Id",p_LeadID);
- m_NewTask.put("Subject","Follow Up Non Converted Lead");
- m_NewTask.put("Due_Date",v_EndTime.toDate());
- m_NewTask.put("Status","Not Started");
- //
- // configure reminder on task to run daily at the same time as creation time
- m_Reminder = Map();
- m_Reminder.put("ALARM","FREQ=DAILY;UNTIL="+v_EndTime+"ACTION=EMAILANDPOPUP;TRIGGER=DATE-TIME:" + v_RemindTime);
- m_NewTask.put("Remind_At",m_Reminder);
- //
- // check what we're sending
- info m_NewTask;
- //
- // create the task in CRM
- r_NewResp = zoho.crm.createRecord("Tasks",m_NewTask, m_Blank, "systemcrm");
- //
- // output response of task creation from CRM
- info r_NewResp;
Step 2: Setup workflow to escalate after 4 days:
No code here necessary, this screenshot shows the settings I put in as a separate workflow:
Step 3: Delete transferred tasks on converted contact
Having disregarded the happy path, what if a lead gets converted to a contact? We then need to remove this task as it will transfer to the contact record on conversion. This has been applied for my client, but I'm awaiting feedback (UAT = User Acceptance Testing) to ensure this behaves as expected. So I found another function was being run when a contact record is created and I appended this snippet of code to the end of it. Note that this identifies the task by the subject so you'd need to be using the same subject as set in Step 1:
// ******************************************************************************* // delete any tasks that were transferred from the lead record relating to reminding staff to convert the lead. // l_RelatedTasks = zoho.crm.getRelatedRecords("Tasks", "Contacts", p_ContactID); for each m_RelatedTask in l_RelatedTasks { if(!isNull(m_RelatedTask.get("Subject"))) { if(m_RelatedTask.get("Subject")=="Follow Up Non Converted Lead") { m_Delete = map(); m_Delete.put("module", "Tasks"); m_Delete.put("id",m_RelatedTask.get("id")); r_Delete = zoho.crm.invokeConnector("crm.delete", m_Delete); info r_Delete; } } }
- // *******************************************************************************
- // delete any tasks that were transferred from the lead record relating to reminding staff to convert the lead.
- //
- l_RelatedTasks = zoho.crm.getRelatedRecords("Tasks", "Contacts", p_ContactID);
- for each m_RelatedTask in l_RelatedTasks
- {
- if(!isNull(m_RelatedTask.get("Subject")))
- {
- if(m_RelatedTask.get("Subject")=="Follow Up Non Converted Lead")
- {
- m_Delete = map();
- m_Delete.put("module", "Tasks");
- m_Delete.put("id",m_RelatedTask.get("id"));
- r_Delete = zoho.crm.invokeConnector("crm.delete", m_Delete);
- info r_Delete;
- }
- }
- }
Caveat(s)
- I've set it to only remind on business days excluding Saturdays and Sundays but you could modify the above to simply AddDay(n) instead of AddBusinessDay(n) if your guys operate over the weekends.
- The task will be on the lead record as soon as it is created which might confuse the staff member dealing with the lead but it's there until conversion.
- The re-assignment of the lead (or escalation thereof) had to be added as a separate workflow as I didn't want to spend more time trying to see how I could automate this at the end of this function.
Error(s) Encountered
{"code":"INVALID_DATA","details":{"api_name":"Remind_At"},"message":"invalid reminder time","status":"error"}
There was nothing wrong with the date time format here. Just that I was submitting a TRIGGER=DATE-TIME but without the correct additional parameters omitted/needed (in my case the UNTIL given a CRM/Atom date time format).m_Recurrer.put("RRULE","FREQ=DAILY;INTERVAL=1;DTSTART=" + v_StartDate + ";UNTIL=" + v_EndDate);
This isn't an error but just here to remind me how to repeat the task. Unnecessary here as the staff member only needs repeatedly reminding but only to perform the task once.- Incorrect Time: In my case, this was due to the CRM being set to a different timezone (7 hours off) and for testing purposes, I need to add the second parameter of toString() to a desired timezone. The CRM format without a second parameter is .toString("yyyy-MM-dd'T'HH:mm:ssXXX") which uses the timezone of the system but to override this I need .toString("yyyy-MM-dd'T'HH:mm:ss", v_ThisTimeZone)
- Incorrect Created By: this is because the system manager who initially set up CRM is used by default. By creating a connection as a system user with the necessary scopes to this CRM instance, untick use credentials of logged-in user, and authorized as the system account (a separate Zoho user we have named SYSTEM ADMIN); this reduces the amount of blame on the system manager believed to be assigning these manually.
Source(s):
- Zoho Community - Zoho CRM - Zoho CRM Developer - Kaizen #36 - Tasks #API
Some noteworthy notes from this source in case it disappears in the future:- Subject (String): Subject of the task. This key is mandatory.
- Who_Id (JSON Object or Int): ID of the contact or lead the task is related to.
- What_Id (JSON Object or Int): ID of the account the contact is associated with. Specify this only when the Who_Id is a contact.
- $se_module (String): The API name of the parent module that the contact is associated with. This key is mandatory when you include Who_id and What_Id.
- FREQ (String): Defines the frequency of the reminder. The possible values are DAILY, WEEKLY, MONTHLY, YEARLY, NONE. If you specify, NONE, the system sets a one-time reminder and TRIGGER becomes mandatory.
- Action (String): Represents how you want to remind the task owner about the task. The possible values are EMAIL, POPUP, EMAILANDPOPUP.
- TRIGGER=DATE-TIME (DateTime ISO8601): Defines when you want to trigger the reminder. Example: 2020-05-01T12:28:00+05:30.
- TRIGGER=TIME (hh:mm): 24-hour time format at which the system must trigger the reminder. Example: 23:45
- Triggers can be given based on due date. For instance, if you want the reminder to be triggered one day before the due date:TRIGGER = -P1D.
- Similarly, if you want the reminder to be triggered two weeks before the due date:TRIGGER= -P2W. This applies only to recurring tasks, and the trigger time is mandatory.
- Error: INVALID_DATA: The ID you specified in what_id or who_id is invalid. Specify the correct ID.
- Error: MANDATORY_NOT_FOUND: You have not specified TRIGGER in "Remind_At" or UNTIL and DTSTART in RRULE keys. Specify the mandatory keys.
- Error: INVALID_RRULE: You have specified an incorrect value for FREQ, INTERVAL, or BYMONTHDAY, BYDAY, BYMONTH, BYSETPOS. Specify the correct value for RRULE.