We Put an AI Chatbot on Every Website (That Actually Knows the Business)
We Put an AI Chatbot on Every Website (That Actually Knows the Business)
TL;DR: We built an AI chatbot that automatically knows everything about the business—services, pricing, hours, reviews, competitive advantages, even the target audience. It’s injected into every generated website as a plugin. No setup required. Users get a 24/7 AI assistant that can actually answer customer questions.
The Problem: Chatbots Are Usually Useless
We’ve all experienced it: You visit a website, click the chat bubble, and get a bot that says “How can I help you?” You ask a simple question and get:
- “I don’t understand that question”
- “Please contact us during business hours”
- “Here’s a link to our FAQ”
The problem: Most chatbots don’t know anything about the business. They’re just glorified contact forms.
Bad: Generic chatbot → Can’t answer questions → User leaves frustrated Good: AI chatbot with full business context → Answers 90% of questions → User converts
The Breakthrough: We Already Have All the Data
Here’s what we realized: We already research every business extensively before generating their website.
During website generation, we collect:
- Business name, type, services
- Contact info, hours, location
- Customer reviews and testimonials
- Competitive intelligence
- Target audience analysis
- Pricing information
- Unique selling propositions
- Service areas
The insight: Why not feed all this data to a chatbot?
How It Works: The Technical Architecture
1. Data Collection During Generation
When we generate a website, we already collect comprehensive business data:
interface BusinessData {
businessName: string;
businessType: string;
services: string[];
location: string;
contactInfo: {
phone?: string;
email?: string;
address?: string;
hours?: string;
};
uniqueSellingPoints: string[];
targetAudience: string;
customerReviews: string[];
missionStatement: string;
serviceAreas: string[];
pricing?: string;
companyHistory?: string;
teamMembers: string[];
competitors: string[];
awards: string[];
// Competitive intelligence
competitiveIntelligence?: {
onlinePresenceScore?: 'low' | 'medium' | 'high';
reputationSentiment?: 'negative' | 'neutral' | 'positive';
competitivePosition?: string;
keyInsights: string[];
mainCompetitors: string[];
competitiveAdvantages: string[];
};
// Strategy insights
strategyInsights?: {
primaryGoal?: string;
strategicPriorities: string[];
contentStrategy?: string;
};
}
This data is already in our database. We just need to expose it to the chatbot.
2. The Chatbot Plugin
The chatbot is a runtime plugin that injects itself into every website:
export class ChatbotPlugin implements Plugin {
name = 'chatbot';
version = '1.0.0';
private businessId: string;
private conversationHistory: Array<{ role: 'user' | 'assistant'; content: string }> = [];
private contactInfo: { phone?: string; email?: string; address?: string } = {};
async initialize(config: CoreConfig): Promise<void> {
// Extract business ID from meta tag
this.businessId = this.getBusinessIdFromMeta();
if (!this.businessId) {
console.warn('[CHATBOT] No business ID found, chatbot disabled');
return;
}
// Create the chat widget UI
this.createChatWidget();
console.log('[CHATBOT] Initialized for business:', this.businessId);
}
private createChatWidget(): void {
// Create floating chat button
const chatButton = document.createElement('button');
chatButton.className = 'webzum-chat-button';
chatButton.innerHTML = `
<svg viewBox="0 0 24 24" fill="currentColor">
<path d="M20 2H4c-1.1 0-2 .9-2 2v18l4-4h14c1.1 0 2-.9 2-2V4c0-1.1-.9-2-2-2z"/>
</svg>
`;
chatButton.onclick = () => this.toggleChat();
// Create chat container
const chatContainer = document.createElement('div');
chatContainer.className = 'webzum-chat-container hidden';
chatContainer.innerHTML = `
<div class="webzum-chat-header">
<span>Chat with us</span>
<button class="webzum-chat-close">×</button>
</div>
<div class="webzum-chat-messages"></div>
<div class="webzum-chat-input">
<input type="text" placeholder="Type a message..." />
<button>Send</button>
</div>
`;
document.body.appendChild(chatButton);
document.body.appendChild(chatContainer);
}
}
3. The API: Loading Business Context
When a user sends a message, the chatbot calls our API:
export async function POST(request: NextRequest) {
const { businessId, message, conversationHistory } = await request.json();
// Load comprehensive business data
const businessData = await loadBusinessData(businessId);
if (!businessData) {
return NextResponse.json({ error: 'Business not found' }, { status: 404 });
}
// Generate AI response with full business context
const response = await generateChatbotResponse(
message,
businessData,
conversationHistory.slice(-10) // Last 10 messages for context
);
return NextResponse.json({
success: true,
response,
businessName: businessData.businessName,
contactInfo: {
phone: businessData.contactInfo.phone,
email: businessData.contactInfo.email,
address: businessData.contactInfo.address,
},
});
}
4. Loading Business Intelligence
We pull data from multiple sources to build comprehensive context:
async function loadBusinessData(businessId: string): Promise<BusinessData | null> {
// First, try to get business intelligence from the live version
const liveVersion = await VersionHistoryManager.getLiveVersion(businessId);
if (liveVersion) {
const biData = await BusinessIntelligenceManager.getBusinessIntelligenceForVersion(
businessId,
liveVersion.version.uuid
);
if (biData) {
console.log(`📊 [CHATBOT] Loaded business intelligence for ${businessId}`);
return extractBusinessDataFromBI(biData);
}
}
// Fallback: try to get from business registry
const businessEntry = await BusinessRegistryManager.findByBusinessId(businessId);
if (businessEntry) {
return {
businessName: businessEntry.candidate.businessName,
businessType: 'Business',
services: [],
location: businessEntry.candidate.address || '',
contactInfo: {
phone: businessEntry.candidate.phone,
address: businessEntry.candidate.address,
},
// ... other fields
};
}
return null;
}
5. AI Response Generation
The AI gets full business context in its system prompt:
async function generateChatbotResponse(
userMessage: string,
businessData: BusinessData,
conversationHistory: Array<{ role: 'user' | 'assistant'; content: string }>
): Promise<string> {
const businessContext = buildBusinessContext(businessData);
const systemPrompt = `You are a helpful, friendly assistant for ${businessData.businessName}.
CRITICAL RULES:
1. You ONLY answer questions about ${businessData.businessName} and its services.
2. If asked about competitors or unrelated topics, politely redirect to how ${businessData.businessName} can help.
3. Always be helpful, professional, and conversational.
4. If you don't know something specific, suggest contacting the business directly.
5. When mentioning contact info, use the exact details provided below.
BUSINESS INFORMATION:
${businessContext}
RESPONSE GUIDELINES:
- Keep responses concise (2-3 sentences max for simple questions)
- Be warm and helpful, not robotic
- Proactively offer relevant information
- If the user seems ready to book/call, encourage them to do so
- Use the business's actual phone, email, and address when relevant`;
const messages = [
{ role: 'system', content: systemPrompt },
...conversationHistory,
{ role: 'user', content: userMessage }
];
const response = await anthropic.messages.create({
model: 'claude-3-haiku-20240307', // Fast, cheap, good for chat
max_tokens: 500,
messages
});
return response.content[0].text;
}
6. Building Rich Business Context
We format all the business data for the AI:
function buildBusinessContext(data: BusinessData): string {
let context = `
BUSINESS NAME: ${data.businessName}
BUSINESS TYPE: ${data.businessType}
SERVICES OFFERED:
${data.services.map(s => `- ${s}`).join('\n')}
CONTACT INFORMATION:
- Phone: ${data.contactInfo.phone || 'Not available'}
- Email: ${data.contactInfo.email || 'Not available'}
- Address: ${data.contactInfo.address || 'Not available'}
- Hours: ${data.contactInfo.hours || 'Contact for hours'}
LOCATION & SERVICE AREAS:
- Primary Location: ${data.location}
- Service Areas: ${data.serviceAreas.join(', ') || 'Contact for service area'}
UNIQUE SELLING POINTS:
${data.uniqueSellingPoints.map(usp => `- ${usp}`).join('\n')}
TARGET AUDIENCE: ${data.targetAudience}
`;
// Add customer reviews if available
if (data.customerReviews.length > 0) {
context += `\nCUSTOMER REVIEWS:\n${data.customerReviews.slice(0, 5).map(r => `- "${r}"`).join('\n')}`;
}
// Add competitive intelligence if available
if (data.competitiveIntelligence) {
context += `\n\nCOMPETITIVE ADVANTAGES:\n${data.competitiveIntelligence.competitiveAdvantages.map(a => `- ${a}`).join('\n')}`;
}
// Add pricing if available
if (data.pricing) {
context += `\n\nPRICING: ${data.pricing}`;
}
return context;
}
Real-World Examples
Example 1: Plumbing Business
User: “Do you do emergency calls?”
AI Response: “Yes! Baird Drain Service offers 24/7 emergency plumbing services in San Diego. We can typically respond within 60 minutes for urgent issues like burst pipes or major leaks. Just call us at (619) 555-1234 anytime—we’re here to help!”
Why it works: The AI knows:
- Business name
- Services (emergency plumbing)
- Location (San Diego)
- Response time (from competitive research)
- Phone number (from contact info)
Example 2: Restaurant
User: “What time do you close on Sundays?”
AI Response: “We’re open until 9 PM on Sundays! Our full hours are Monday-Saturday 11 AM - 10 PM, and Sunday 11 AM - 9 PM. Would you like to make a reservation? You can call us at (555) 123-4567.”
Why it works: The AI knows the actual business hours from our research.
Example 3: Handling Off-Topic Questions
User: “What’s the weather like today?”
AI Response: “I’m here to help with questions about Joe’s Pizza! Is there anything I can help you with—like our menu, hours, or placing an order?”
Why it works: The AI is trained to redirect off-topic questions back to the business.
The Challenges We Solved
Challenge 1: Data Freshness
Problem: Business info changes (new hours, new services)
Solution: Pull from live version data, which updates when website regenerates
const liveVersion = await VersionHistoryManager.getLiveVersion(businessId);
const biData = await BusinessIntelligenceManager.getBusinessIntelligenceForVersion(
businessId,
liveVersion.version.uuid
);
Challenge 2: Conversation Context
Problem: Users ask follow-up questions that require context
Solution: Pass conversation history to AI
const response = await generateChatbotResponse(
message,
businessData,
conversationHistory.slice(-10) // Last 10 messages
);
Challenge 3: Clickable Contact Info
Problem: AI mentions phone/email but users can’t click them
Solution: Return contact info separately, render as clickable links
return NextResponse.json({
success: true,
response,
contactInfo: {
phone: businessData.contactInfo.phone,
email: businessData.contactInfo.email,
},
});
// Frontend renders phone as tel: link
if (contactInfo.phone) {
const phoneLink = `<a href="tel:${contactInfo.phone}">${contactInfo.phone}</a>`;
message = message.replace(contactInfo.phone, phoneLink);
}
Challenge 4: Cost Control
Problem: AI API calls can get expensive
Solution: Use Claude Haiku (fast, cheap) + limit conversation history
const response = await anthropic.messages.create({
model: 'claude-3-haiku-20240307', // $0.25/M input, $1.25/M output
max_tokens: 500, // Keep responses concise
messages: messages.slice(-10) // Limit context
});
Cost: ~$0.001 per conversation turn
The Results: 24/7 AI Customer Service
What every WebZum website now has:
- ✅ AI chatbot that knows the business
- ✅ Answers questions about services, hours, location
- ✅ Handles pricing inquiries
- ✅ Provides contact info with clickable links
- ✅ Redirects off-topic questions
- ✅ Maintains conversation context
- ✅ Works 24/7
User feedback:
“The chatbot actually knew my business hours and services. I didn’t have to set anything up.” - Bakery owner
“A customer asked about our service area at 2 AM and got an accurate answer. That’s a first.” - HVAC contractor
Why This Matters for Small Businesses
Most small businesses can’t afford:
- 24/7 customer service
- Custom chatbot development
- AI training and maintenance
We give them all of this for free, automatically, because we already have the data.
Key Insights
- Data reuse is powerful: We already collect business data for website generation—reusing it for chatbot context is essentially free
- Context is everything: A chatbot without business context is useless
- Keep it simple: Users want quick answers, not lengthy conversations
- Clickable actions: Phone numbers and emails should be tappable/clickable
What’s Next
We’re exploring:
- Lead capture: Chatbot can collect contact info for follow-up
- Appointment booking: Integration with scheduling tools
- Multi-language support: Chatbot responds in user’s language
- Voice support: “Hey, ask the website a question”
But the core insight remains: If you already have business data, use it everywhere.
Try it yourself: Generate a website with WebZum. Click the chat bubble in the bottom right. Ask it about the business—it actually knows the answers.
Building a SaaS? Key takeaway: Reuse data you already collect. If you research businesses, feed that data to a chatbot. If you have user profiles, personalize everything.
The best features are the ones that require zero setup.