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
Bulk Associate Tasks/Task Lists to Milestones (Similar to Issues)
Hello Zoho Projects Team, We hope you are doing well. We would like to request an enhancement regarding Milestone management for Tasks in Zoho Projects. Current Behavior: In the Issues module, it is possible to select multiple issues and easily associate
Is Zoho Sites still actively being developed?
Hello, Is Zoho Sites still actively being developed as part of the Zoho ecosystem? I noticed that the What's New page (https://www.zoho.com/sites/whats-new.html) does not show any updates since Q1 2025. We were considering migrating our website from Squarespace
Adding new data to the sheet with most recent data being added to top row.
I am using a form that I built from within sheets. When the form is submitted, is it possible to have the data entered in (for example) row 2 (since row 1 is the heading) instead of being added into the next available row which should be hundreds of
need a packing list feature
In our business, goods listed on an invoice are packed in separate boxes and shipped off. for e.g. an invoice may have 10 items. each item could then be packed in different boxes depending on qty of each item. this packing list is as important as the invoice for purposes of shipping documents. Request you to add this feature asap.
Editing Item Group to add Image
I did not have the image of the product when the Item Group was created. Now I have the product image, and would like to associate/add to the Item Group. However the Item Group Edit functionality does not show/allow adding/changing image. Please hel
Zoho CRM Queries Now Support Databases and Cloud Data Sources
Hello everyone! We're thrilled to announce a major enhancement to the Queries feature in Zoho CRM! Queries now support a broader range of external data sources, allowing you to fetch live data and combine it with CRM records, all using a unified query
Re: Application Architecture in Zoho Creator — A Platform-Specific Deep Dive
A recent community post on application architecture made some excellent points about planning architecture early in Zoho Creator projects. The core message is right — Creator applications have a habit of growing organically into maintenance nightmares,
Introducing a smarter, faster, and more flexible charting experience
Hello Zoho Sheet users, We're delighted to share the latest news about a major update to charts in Zoho Sheet! The new version supports dynamic data ranges, granular styling options, faster loading, and other interesting enhancements that allow you to
Zoho Bookings - Feature Request - Services Which Include A Resource and Consultant
Hi Bookings Team, My feature request is to have the ability to add Consultants and Resources to Services. Use case: Your business provides first aid training and there are certain equpment you require to provide the half day training. There are only specific
Assign Meeting in records
It would be nice to be able to "call and assing" meetings from a record, for example from a Deal. Right now - calendar is synced with CRM - meetings show in calendar - you can go in each meeting and assign it to a record It would be nice to be able to
Sincronizar eventos de Bigin en Zoho Calendar (Zoho Mail)
Hola Me gustaría poder sincronizar mi Calendario de Zoho (Mail) con los eventos de Bigin. No veo la opción disponible.
Sales Receipts in UK Free tier
Is Sales Receipts available in UK Books, specifically at the Free tier? None of the options from the help pages are available to me.
My client requires me to have custom pdf file names to except payment for invoices, how can I customize this before emailing.
Hello! I love the program so far but there are a few things that are standing in the way. I hope you guys can code them in so I can keep the program for years to come. My client requires I customize the pdf file names I send in for billing. Can you please
When I schedule calendar appointments in zoho and invite external emails, they do not receive invites
Hello, We have recently transitioned to zoho and are having a problem with the calendar feature. When we schedule new calendar appointments in zoho the invite emails aren't being sent to the external users that we list in participants. However, this works
Migrate different zoho subscription to zoho one
Dear We have different zoho subscription we need to migrate it to zoho one. Currently we are paying for zoho email, zoho expense, zoho payroll etc under different admin We need to move it too zoho one flexlible plan for all my employees
Bigin use in hospital- Human Med or Veterinary
I am looking for users who are in either human or veterinary medicine and use the CRM specifically for referral management tasks. Are you using the basic version? How many users update the CRM and is it effective? Did you pay for additional customizations?
Standardize email communication with Signature Template
Maintaining a consistent and professional signature across all outgoing emails is essential for any organization. However, when users manage their signatures individually, it often leads to inconsistencies like varying formats, missing designations, or
Zoho Books: tax is not automatically pulled from product-data anymore - why?
Hi, until a short time ago, you could set a default taxrate for each product/item. This taxrate automatically appeared each time the item was chosen in an invoice or quote. Why does this not work anymore? The field is still there at the product record,
Setting up property management in Zoho Books
Hi, I run a property management business that manages property complexes. There are multiple owners, some owning more than one property on the same complex. My role is to manage the fees they pay for maintenance of common areas, such as the swimming pool
Zoho Creator to GMAIL API Setup - Where Do I Begin?
Does anyone know how to connect Zoho Creator to Google Workspace (Specifically GMAIL?) We have FLOW setup and working fine to send emails via GMAIL, but Flow doesn't accept file attachments which is a major problem. So, we need to be able to send an email
Kiosk Page Refresh
We have a Kiosk running from a button in contacts to update values and also add related lists, which works great, but when the kiosk is finished the page does not refresh to show the changes. Is there a way to force the contact to refresh/update when
Setting GC session variable programatically in a website
Hi! Is there a way now to programatically set session variables from a website for a Guided Conversations? The current available methods are dependent on react-native.
Ticket Merge Error
Refresh frequency
Dear Zoho Team, I really, truly appreciate that Zoho Books gets frequent updates. As a matter of fact this is how a good SaaS company should stay on top. However, I feel that I have to hit refresh almost every day. This was exciting at the beginning but
Update application by uploading an updated DS file
Is it possible? I have been working with AI on my desktop improving my application, and I have to keep copy pasting stuff... Would it be possible to import the DS file on top of an existing application to update the app accordingly?
Two-factor authentication (2FA) Log-in Problems
The Two-factor authentication (2FA) Login on my passwords doesn't match , so it wont accept login I'm down to my last backup code.
Remove my video
Hi, How can I remove my video so that I don't have to see myself. It's weird so I always remove my own video from what I see but cannot find this feature here. Thanks!
Client Script: Any plans to add support for multi-select field with onChange
Client Script is fantastic and the documentation lists multiselect form fields as unsupported. Just wondering if there are any plans to make this a supported field. https://www.zoho.com/crm/developer/docs/client-script/client-script-events.html 2. Field
Feature Reqeust - Include MPN In Selectable FIelds
I have noticed that the MPN is not available to show in the list view of Items. Please consider adding it as EAN, UPC and ISBN are all available, so it doesn't make much sense to exclude this similar option. Thanks for considering my feedback.
Experience effortless record management in CRM For Everyone with the all-new Grid View!
Hello Everyone, Hope you are well! As part of our ongoing series of feature announcements for Zoho CRM For Everyone, we’re excited to bring you another type of module view : Grid View. In addition to Kanban view, List view, Canvas view, Chart view and
Windows Desktop Application for Bigin
I'm finding the need for a standalone Bigin desktop app for Windows users. Most of my daily work is done through a browser, so I often have several open tabs while working with customers and checking product information, etc. With Bigin currently only
Set another Layout as Standard
We created a few layouts and we want to set another one to standard:
Salesforceに添付ファイルを格納したい
お世話になっております。 Salesforceに添付ファイルを格納したく、カスタムオブジェクトに連携し、 「ファイルのアップロード」項目を設けました。 実際、エラーもなく送信出来たのですが、実際生成されたカスタムオブジェクトのレコードを見ると、どこにも添付ファイルがありません。仕様として、この添付ファイルはSalesforceのどこに格納されるのでしょうか? 今回作りたいフォームは、複数の書類を添付するため、Zohoformのファイルアップロード項目「本人確認書類」「源泉徴収票」などの項目を、Salesforce側にも設けた「本人確認書類」「源泉徴収票」という各項目にURLリンクとして紐づけたいと思っておりました。
Knowledge Base article lists
Is it possible to adjust the number of articles that are visible under a category of the Knowledge Base portal? Currently it looks like by default it populates about 5 articles before it puts the "more" option at the bottom. Looking to see if I can extend
Discrepancy in Contracts with Fields list/Layout
The Support Plan field on the layout isn't in the fields list. What am I missing?
Migrating all workflows to another Zoho account
We are going to transfer into another company, and we are going to get new emails and new Zoho accounts. Is there a way to migrate (or save in some sort of external file) all presets and settings that we have on this account? That includes primarily workflows,
Edit The Newsletter
There doesn't seem to be the ability add a title and a caption below the button. Can this be done?
Unable to Delete Items – No Visible Transactions but Error “Items which are a part of other transactions cannot be deleted…”
Hello Community, We are using Zoho Inventory for our business and encountered a persistent issue that is preventing us from deleting certain items. The message shown is: “Items which are a part of other transactions cannot be deleted. Instead, mark them
Keyboard UX for Assemblies
The new Assembly module has a counter-intuitive behavior that ought to be corrected. When an Assembly is ready to be entered, there are two options given, the blue-highlighted "Assemble" and the gray "Save as Draft". This correctly implies that the normal
landed cost-need help with different currency under the same bill
I’m having trouble recording landed costs in Zoho Inventory/Books. My purchase order is in CNY, but the landed cost (freight) I pay is in USD. Zoho forces everything under the same bill to use one currency, so I can’t enter the landed cost in its actual
Next Page