Hey everyone!
Welcome back to another interesting post in the Kaizen series!
Sales teams regularly capture interaction notes in CRM after speaking with prospects. However, drafting a follow-up email that reflects the conversation context can be repetitive and time-consuming.
What if CRM could automatically generate a contextual follow-up email draft based on recent interactions with the lead?
In this Kaizen post, we will create a practical tool that generates context-aware follow-up emails directly from a Lead record. You will see how it pulls recent notes, lead's details, and crafts a ready-to-send draft.
The solution uses three Zoho strengths:
- Widgets for intuitive UI
- Functions for secure backend processing
- External AI APIs (like Groq or OpenAI)
The output displays in the widget. Review, tweak if needed, copy, and paste into your email composer.
The business challenge
Sales reps log calls like "Prospect interested in 20 user licenses but concerned about pricing. Explore volume discounts."
Now, crafting a response involves recalling details, matching tone, and ensuring professionalism. Miss a nuance, and trust erodes.
Our AI generator automates this. It scans the lead's details (name, company, status) and the three most recent notes, then prompts an AI model for a draft.
Example output

Subject: Follow-up on CRM Licensing Discussion
Hi John,
Thanks for the insightful chat today about your team's CRM needs. You're considering licenses for around 20 users, and I appreciate pricing being a top priority.
I'll review our volume options and discount eligibility right away. Expect specifics by EOD tomorrow.
Best regards,
[Your Name]
This keeps the rep in control while slashing draft time from 10 minutes to 10 seconds. Scalable for high-volume teams.
High-level architecture
Think of a layered cake!
- UI Layer (Widget): Button launches it; displays, copies the draft, and sends the email.
- Logic Layer (Function): Fetches CRM data server-side, builds prompt, calls AI securely.
- AI Layer: External service generates natural language.
Flow
Rep clicks a button → Widget gets Lead ID → Calls function → Function queries CRM + AI → Draft back to widget
Secure (no client-side keys), reliable (server-side), and reusable across modules.
Developers often wonder "Why not fetch AI responses straight from widget JavaScript?"
Widgets run in a browser iframe, so embedding API keys exposes them to inspection or misuse. CORS policies can also block external requests, and complex logic like prompt building suits server-side better.
So, the best practice is to use widgets for UI and functions for secure server-side work. This hides credentials and reuses logic.
Follow these steps to build this solution.
Step 1: Add the custom Button
- Head to Setup → Modules and Fields → Leads → Buttons → Create New Button.
- Provide the following details:
- Name: Generate AI Email
- Placement: Record Detail Page (top or bottom)
- Action: Open Widget (select your widget once built)
- Save and add to layout.
- Test: Button appears on Leads; clicking loads widget in context.

Pro tip: Position near the "Send Email" button for seamless workflow.
Step 2: Build the CRM Function
- Go to Setup → Developer Hub → Functions → + Create Function.
- Enter the display name, function name, description, choose Standalone as the category.

- Click Create. The Functions IDE opens.
Enter the following function code. Note that this example uses Groq AI API.
string standalone.generate_ai_email(String leadId) {
lead = zoho.crm.getRecordById("Leads",leadId); name = ifnull(lead.get("Full_Name"),""); company = ifnull(lead.get("Company"),""); status = ifnull(lead.get("Lead_Status"),""); // Fetch recent CRM Notes notesResp = zoho.crm.getRelatedRecords("Notes","Leads",leadId); recentNotes = ""; count = 0; for each note in notesResp { noteContent = ifnull(note.get("Note_Content"),""); if(noteContent != "") { recentNotes = recentNotes + "[" + (count + 1) + "] " + noteContent + ". "; } count = count + 1; if(count == 3) { break; } } // Build AI prompt prompt = "You are a sales assistant helping draft follow-up emails. "; prompt = prompt + "Generate a professional follow-up email based on the customer's previous interactions. "; prompt = prompt + "Lead Name: " + name + ". "; prompt = prompt + "Company: " + company + ". "; prompt = prompt + "Lead Status: " + status + ". "; prompt = prompt + "Recent CRM Interaction Notes: " + recentNotes + ". "; prompt = prompt + "Write a professional follow-up email referencing the discussion."; // Sanitize prompt prompt = prompt.replaceAll("\"","\\\""); prompt = prompt.replaceAll("\n"," "); prompt = prompt.replaceAll("\r"," "); // Build AI request message = Map(); message.put("role","user"); message.put("content",prompt); messages = List(); messages.add(message); requestBody = Map(); requestBody.put("model","llama-3.1-8b-instant"); requestBody.put("messages",messages); requestBody.put("temperature",0.4); requestJSON = requestBody.toString(); // Call Groq API response = invokeurl [ type :POST parameters:requestJSON headers:{"Authorization":"Bearer YOUR_API_KEY","Content-Type":"application/json"} ]; // Extract AI email emailContent = ""; if(response.containsKey("choices")) { emailContent = response.get("choices").get(0).get("message").get("content"); } // Return generated email to widget return emailContent; } |
Note for production
- Connections: In the example, the API key is included directly in the function for simplicity. However, production deployments should use Connections instead of hard-coding credentials as they allow developers to store API credentials securely within Zoho CRM and reuse them across multiple integrations.
- Error Handling: Wrap invokeurl in try-catch.
- Limits: Cap notes at 3 to avoid token overflow and tune temperature (0.4 = consistent).
- Logging: Add info prompt before API call for debugging.
- Test: Execute with sample Lead ID. Expect clean email string back.
- Extend: Add phone/email from Lead, or filter notes by date (e.g., last 7 days via criteria).
Step 3: Develop the Widget
The widget provides the user interface for generating and copying the AI email.
When the widget loads, it retrieves the current Lead ID using the CRM widget JS SDK. When the user clicks Generate Email, the widget calls the CRM function and displays the generated email draft.
The widget also provides Send Email and Copy Email buttons that send the email to the lead record's email ID and copies the email content to the clipboard so the rep can past it into the email composer, respectively.
Sample index.html
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <style> <!-- Add your style here--> </style> </head> <body> <div class="widget-card"> <div class="widget-header"> <path d="M20 4H4C2.9 4 2 4.9 2 6v12c0 1.1.9 2 2 2h16c1.1 0 2-.9 2-2V6c0-1.1-.9-2-2-2zm0 4l-8 5-8-5V6l8 5 8-5v2z" fill="white"/> </svg> <h2>AI Follow-up Email Generator</h2> </div> <div class="widget-body"> <div class="email-box-wrapper"> <textarea id="emailBox" placeholder="Click 'Generate Email' to create a contextual follow-up email..."></textarea> </div> <div class="action-bar"> <button class="btn btn-primary" id="generateBtn" onclick="generateEmail()"> <svg width="13" height="13" viewBox="0 0 24 24" fill="none"><path d="M12 2l2.4 7.4H22l-6.2 4.5 2.4 7.4L12 17l-6.2 4.3 2.4-7.4L2 9.4h7.6z" fill="white"/></svg> Generate Email </button> <button class="btn btn-success" id="sendBtn" onclick="sendEmail()"> <svg width="13" height="13" viewBox="0 0 24 24" fill="none"><path d="M2 21l21-9L2 3v7l15 2-15 2v7z" fill="white"/></svg> Send Email </button> <button class="btn btn-secondary" onclick="copyEmail()"> <svg width="13" height="13" viewBox="0 0 24 24" fill="none"><path d="M16 1H4C2.9 1 2 1.9 2 3v14h2V3h12V1zm3 4H8C6.9 5 6 5.9 6 7v14c0 1.1.9 2 2 2h11c1.1 0 2-.9 2-2V7c0-1.1-.9-2-2-2zm0 16H8V7h11v14z" fill="#3D4354"/></svg> Copy </button> </div> <div class="status-bar" id="statusBar"></div> </div> </div> <script src="index.js"></script> </body> </html> |
Sample index.js
let leadId; let leadEmail; let generatedEmail = "";
// Widget initialization ZOHO.embeddedApp.on("PageLoad", function(data){
if(data && data.EntityId){
leadId = data.EntityId[0];
// Fetch Lead email ZOHO.CRM.API.getRecord({ Entity: "Leads", RecordID: leadId }) .then(function(response){
if(response && response.data && response.data.length > 0){ leadEmail = response.data[0].Email; }
});
}
});
ZOHO.embeddedApp.init();
// --- Helper functions used by email generation/sending --- // function formatEmailText(raw) { /* formatting logic */ } // function textToHtml(text) { /* convert plain text to HTML */ } // function setStatus(message, type) { /* UI status logic */ }
// Generate AI email using a CRM function function generateEmail(){
var req_data = { arguments: JSON.stringify({ leadId: leadId }) };
ZOHO.CRM.FUNCTIONS.execute('generate_ai_email', req_data)
.then(function(response){
if(response && response.details){
generatedEmail = formatEmailText(response.details.output); document.getElementById('emailBox').value = generatedEmail;
}
}) .catch(function(error){
console.log('Function error:', error);
});
}
// Send email using ZRC async function sendEmail() {
const emailContent = document.getElementById('emailBox').value.trim();
if (!emailContent) return;
try {
// Get allowed "From" addresses const fromRes = await zrc.get('/crm/v8/settings/emails/actions/from_addresses'); const fromAddress = fromRes.data.from_addresses[0];
const htmlContent = textToHtml(emailContent);
// Send mail const response = await zrc.post(`/crm/v8/Leads/${leadId}/actions/send_mail`, {
data: [ { from: { user_name: fromAddress.display_name || fromAddress.user_name, email: fromAddress.email }, to: [ { email: leadEmail } ], subject: 'Follow-up', content: htmlContent, mail_format: 'html' } ]
});
console.log('Mail sent:', response);
} catch (error) {
console.error('Send mail error:', error);
}
}
// Copy generated email // function copyEmail(){ /* copy logic */ } |
The ZIP containing the complete index.js and index.html files used in this example is attached at the end of this post.
User experience walkthrough
- The salesperson clicks Generate AI Email on the record detail page and the widget opens.
- The salesperson clicks the Generate AI email button. The widget retrieves CRM context and generates a contextual follow-up email draft.
- The email appears inside the widget, allowing the salesperson to quickly review the generated message, and use the Send Email button to send it to the lead's email ID.
This workflow ensures that AI assists with drafting the message while still allowing the salesperson to review and control the final communication.
Here is a GIF explaining the use case in action.
Key takeaways
This example demonstrates how Zoho CRM developers can integrate generative AI into CRM workflows using platform-native tools.
Combine CRM Widgets for user interaction and Functions for secure server-side processing to safely integrate external AI services without exposing credentials or compromising security.
The same architecture can be extended to build more advanced AI features, such as:
- Automated meeting summaries
- Deal health insights
- Proposal drafting assistants
- Intelligent follow-up recommendations
We hope you liked this post. Let us know what you think in the comments or reach out to us at
support@zohocrm.com.
Cheers!
===================================================================================
Recent Topics
Is this a SCAM email or is it really Zoho?
L.S. I received the following message. Is this from Zoho? I have had a Zoho One account for many years and my website has been online for years. If it is a scam, I think you should know about it.
Is it possible to use HTML formatting in SMS messages sent from Zoho?
Hi everyone, I have a question regarding sending SMS from Zoho When we send emails from Zoho, we can include HTML code to format the message (like adding links, styling, etc.). Is it possible to do something similar when sending SMS messages through Zoho
an issue in Zoho CRM where the workflow rule is not triggering
H I’m currently facing an issue in Zoho CRM where the workflow rule is not triggering when a new lead is created through a webform. I’ve double-checked the criteria and field updates, everything seems fine but it still doesn’t fire. Has anyone faced this
Option in pipeline deal to select which hotel or branch or store if client has more than one local store
Hi, I would like to know if there is an option in the deal pipeline to select which hotel, branch, or store a deal is related to—if the company has more than one location. For example, I have a client that owns several hotels under the same company, and
Email Insights included in Bigin emals are marked as SPAM everywhere
Today I noticed that email recipients who use Office 365 never receive emails sent from Bigin. Further examination showed that all Email Insights links in email headers are marked as spam/phishing by Office 365. Example screen included. The problem is
Email Parser Not Extracting Fields Correctly with Certain Label Formats
I’ve been testing the Email Parser functionality in Zoho CRM to automatically extract data from incoming emails and map it to CRM fields. During testing, I noticed that parsing sometimes fails when the email contains field labels formatted like this:
How do I import Connected Records for a Deal?
Can you point me to an example of the CSV file that would add related records to an existing CRM Deal? I imported a Deal, then tried importing a connected record using a unique ID that references the Deal ID, but it doesn't attach it to the Deal rec
File Upload Field in Zoho Forms Not Updating Existing File in Zoho CRM
Hi everyone, I’m trying to understand the behavior of a file upload field mapped from Zoho Forms to Zoho CRM. Scenario There is a File Upload field in a Zoho CRM module. A Zoho Form also has a File Upload field, which is mapped to that CRM field. When
Zoho Training
Greetings! I am trainer. My focus area is Project Management and MS Project. I have used Zoho CRM to a good extent. Though, I was interested in using ZOHO projects, as there were no live projects, I could not take it up for studies. Recently a client
Detailed list of scoring rules in Zoho CRM
Good morning Zoho community, warm greetings The reason for my message today is that I have a problem with my CRM, which I will explain below: Our organization has scoring rules designed to rate our potential customers or leads in the application based
How to create a summary document from Projects details
Hi, Our team is creating many projects inside Zoho Project. When closing a project, they write a summary document containing data from the projects it-self (understand project budget, customers, etc...), and editable (ie the document is either a Writer
Request to Recover Deleted Task List – Project ID: RIV-MOD-10722
Hi Zoho Team, I hope this message finds you well. My Zoho task list associated with Project ID: RIV-MOD-10722 appears to have been deleted. When I clicked on the task link from the email notification, I received the following message: "Task has been deleted
Host in US Data Centre
I humble apply to be registered on US Data centre
convert the project to templet
i have some deployment ME product for different customer , i need to create a fixed template for use it rather then keeping creating this template every time
Best practices for managing Project Charters, Business Case and RAID logs within Zoho?
Hello everyone, I’m currently refining our PMO setup within Zoho Projects and I’m curious how others are handling high-level governance documentation. We’ve been using the standardized Project Charter, Business Case and RAID frameworks from projectmanagertemplate.com
Resource Management System built using Zoho CRM, Creator, Projects, and People:
In a Resource Management System built using Zoho CRM, Creator, Projects, and People: CRM Deal Closed → Creator Allocation Engine → Zoho Projects Task Assignment What is the recommended architecture to handle dynamic reassignment when: an employee goes
Dynamic Remaining Quantity in Lookup During Allocation
Hi everyone, From what I understand in Zoho Creator, lookup fields only display the stored value from the source record and do not dynamically update while a form is being filled. Because of this, showing a real-time updated remaining quantity inside
connect zoho creator with google drive
Hello everyone, I need to connect to a folder drive. The idea, is that google drive loads a text document with some data, I must read that text document to be able to autofill a form that I have in zoho creator with that data. I also attach PDFs and place
Ability to Attach Record-Specific Files Automatically in Workflow Email Templates
Currently in Zoho CRM, email templates allow attachments to be added, but these attachments are static and remain the same for every recipient. There is no straightforward option to automatically attach a file that is stored within the specific CRM record
Uploaded files are not included when using "Include user submitted data" in Email Notification
In Send Email notification workflow in Zoho Creator, there is an option called "Include user submitted data" which allows the email to contain all the form submission details. However, when this option is enabled, files or images uploaded through File
kanban view for client portal
Are kanban views an option for client portals? Access to Kanban views in the client portals would solve some mobile-compliant issues I have with the UI. Kanban functions very nicely on mobile and would be a super asset for my clients and vendors as they
Credit Card Pre-Authorization with later Capture/Settlement
We really enjoy the convenience of being able to pay off a customer's invoice using our Auth.Net integration with Zoho Books. Unfortunately, we can only take advantage of this feature with a small percentage of our customers as it leaves a gaping hole
Zoho Cliq not working on airplanes
Hi, My team and I have been having this constant issue of cliq not working when connected to an airplane's wifi. Is there a reason for this? We have tried on different Airlines and it doesn't work on any of them. We need assistance here since we are constantly
Zoho Sign 2025–2026: What's new and what's next
Hello! Every year at Zoho Sign, we work hard to make document signing and agreement execution easy for all users. This year we sat down with our head of product, Mr. Subramanian Thayumanasamy, to discuss what we delivered in 2025 and our goals for 2026.
Work Orders / Bundle Requests
Zoho Inventory needs a work order / bundle request system. This record would be analogous to a purchase order in the purchasing workflow or a sales order in the sales cycle. It would be non-journaling, but it would reserve the appropriate inventory of
Izettle or Sumup Integration for Zoho Books.
The Stripe & Square clearing works great in Zoho Books. Any further integrations planned in the future for Izettle or Sumup? These card processors are very common for taking payments with a card reader.
Train Zoho Answer Bot Based on Customer
Hi all, Is it currently possible to mark Help Centre articles to a specific customer, and restrict the answer bot to only use relevant information if it is either marked as "General", or tagged for the specific customer in question? We currently have
Trying to access records in a custom module in Zoho Desk and not having luck
I've built a custom module in Zoho Desk and am using a custom function to query the records in the module and I'm not having any luck. The only way I have found to retreive a record is by getting it by its recordID (the long zoho assigned one). The function
Composite items inside of composite items; bill of materials needed
Hi Zoho and Everyone, I am evaluating whether Zoho Inventory will work for my small business. I grow and harvest herbs and spices but also get from wholesalers. I use all these items to make herbal teas, but also sell them as individual items on my Shopify store and Etsy. I discovered the composite item bundling and am wondering if I could get some assistance since there is no bill of materials: Our herbal company's best selling tea is a sleepytime tea. Sleepytime Tea can be purchased in three weights
ZOHO Books Smart Accounting Software for Travel Agency
Dear Travel partner, Contact for Travel Agency Accounting Setup & Training Vansh Travel (ZOHO Books Authorised partner) Email: info@vanshtravel.com Mo: +91 98984 95155 Please find PDF
452 Mailbox delivery restricted by policy error
We have been testing Zoho desk for about a week now and have been forwarding emails in via an Exchange Online Mail flow rule without issue until yesterday. Suddenly yesterday morning we started getting the vast majority of the emails stuck in Pending
Send Email reply on behalf of Agent
Hi, When using the send email reply via the API I can set the reply on behalf of the customer by using impersonatedUserId in the header of the API call. Is there a way to do this for Agents too? I need to be able to send an email reply on behalf of an
Sharing Tickets to a team within a department
Hi there, We have a need for one department to be able to share tickets to a specific team within a department, I'm wondering if this is possible? All the shared tickets are going into the 'Shared Tickets' view for the whole department but is there a
Removing To or CC Addresses from Desk Ticket
I was hoping i could find a way to remove unnecessary email addresses from tickets submitted via email. For example, a customer may email the support address AND others who are in the helpdesk notification group, in either the TO or CC address. This results
Do not use isnull()
Does not always return booleans. Can also return null. Never use this function. Just use var==null instead.
Organization wide Account and Contacts Visibility/Sharing Capabilities?
Has anyone figured out a way to make visibility or sharing of Accounts and Contacts to be available across the entire organization without having to have every individual user edit their Sharing permissions? For our sales folks they need to be able to
Is there a way to configure dark mode for Campaigns emails that go out to customers?
I've found a lot of information on how to configure dark mode for my (The user) personal Zoho workspace and email, but is there any way to edit dark mode settings on emails that we send out to customers via campaigns? We sent out a test email the other
When Does WorkDrive integrate with Books?
When Does WorkDrive integrate with Books?
FSM integration with Books
Hi, I have spent a few months working with FSM and have come across a critical gap in the functionality, which I find almost shocking....either that, or I am an idiot. The lack of bi-directional sync between Books and FSM on Sales Orders/ Work Orders
How to close an estimate ?
Hello, I have created estimates, and converted them to invoices to get 50% payment. Now I have 2 cases where the estimate stills shows status partially invoiced, however: 1. for one of them, project stopped half way, so the remaining part will never be
Next Page