Back to Guides
Code Examples & Practical Samples
Production-ready code examples for integrating TalkBuildr into your applications. All examples include error handling, security best practices, and are ready for production use.
Knowledge Base Integration
Upload documents and manage knowledge base via API
- File Upload with JavaScript
- File Upload with React
- Check Processing Status
- Error Handling & Retry Logic
API Integration
Connect TalkBuildr with external systems
- Webhook Handler (Node.js)
- Zapier Code Steps
- API Authentication
- Event Processing
Customization
Customize chatbot appearance and behavior
- Custom CSS Styling
- API Configuration
- Multi-Language Setup
- Testing Scripts
Analytics & Monitoring
Track performance and user engagement
- Fetch Analytics Data
- Real-time Monitoring
- Error Tracking
- Performance Metrics
Troubleshooting
Common issues and their solutions
- Upload Error Solutions
- Rate Limiting Handling
- Authentication Issues
- Processing Timeouts
Featured Examples
Complete File Upload Component
Production-ready React component with progress tracking and error handling
React
import { useState, useRef } from 'react';
function KnowledgeBaseUploader({ chatbotId, apiKey }) {
const [uploading, setUploading] = useState(false);
const [progress, setProgress] = useState(0);
const [error, setError] = useState(null);
const fileInputRef = useRef(null);
const validateFile = (file) => {
const maxSize = 10 * 1024 * 1024; // 10MB
const allowedTypes = [
'application/pdf',
'text/plain',
'application/vnd.openxmlformats-officedocument.wordprocessingml.document'
];
if (file.size > maxSize) {
throw new Error('File too large. Maximum size is 10MB.');
}
if (!allowedTypes.includes(file.type)) {
throw new Error('Unsupported file type. Use PDF, TXT, or DOCX.');
}
return true;
};
const handleFileUpload = async (file) => {
try {
validateFile(file);
setUploading(true);
setError(null);
const formData = new FormData();
formData.append('file', file);
formData.append('chatbotId', chatbotId);
const response = await fetch('/api/knowledge-base/upload', {
method: 'POST',
headers: {
'Authorization': `Bearer ${apiKey}`
},
body: formData
});
if (!response.ok) {
const errorData = await response.json().catch(() => ({}));
throw new Error(errorData.error || errorData.message || `Upload failed: ${response.statusText}`);
}
const result = await response.json();
console.log('Upload successful:', result);
alert('File uploaded successfully!');
} catch (err) {
setError(err.message);
console.error('Upload error:', err);
} finally {
setUploading(false);
setProgress(0);
}
};
const handleFileSelect = (event) => {
const file = event.target.files[0];
if (file) {
handleFileUpload(file);
}
};
return (
<div className="upload-container">
<input
ref={fileInputRef}
type="file"
accept=".pdf,.txt,.docx"
onChange={handleFileSelect}
style={{ display: 'none' }}
/>
<button
onClick={() => fileInputRef.current?.click()}
disabled={uploading}
className="upload-button"
>
{uploading ? 'Uploading...' : 'Choose File'}
</button>
{uploading && (
<div className="progress-bar">
<div className="progress-fill" style={{ width: `${progress}%` }} />
</div>
)}
{error && (
<div className="error-message" style={{ color: 'red' }}>
{error}
</div>
)}
</div>
);
}
export default KnowledgeBaseUploader;→ Usage Notes:
- • Replace
chatbotIdandapiKeywith your actual values - • Add proper error handling for production use
- • Consider rate limiting and caching for high-traffic applications
- • Test thoroughly before deploying to production
Webhook Handler with HMAC Verification
Secure webhook endpoint with signature verification
Node.js
const express = require('express');
const crypto = require('crypto');
const app = express();
app.use(express.json());
// HMAC signature verification
function verifyWebhookSignature(payload, signature, secret) {
const expectedSignature = crypto
.createHmac('sha256', secret)
.update(JSON.stringify(payload))
.digest('hex');
return crypto.timingSafeEqual(
Buffer.from(signature, 'hex'),
Buffer.from(expectedSignature, 'hex')
);
}
// Webhook event handler
app.post('/webhooks/talkbuildr', (req, res) => {
try {
const signature = req.headers['x-talkbuildr-signature'];
const secret = process.env.WEBHOOK_SECRET;
// Verify webhook signature for security
if (!verifyWebhookSignature(req.body, signature, secret)) {
return res.status(401).json({ error: 'Invalid signature' });
}
const { event, data } = req.body;
console.log(`Received ${event}:`, data);
// Handle different event types
switch (event) {
case 'message.created':
// Process new message
handleNewMessage(data);
break;
case 'conversation.started':
// Handle new conversation
handleNewConversation(data);
break;
case 'user.feedback':
// Process user feedback
handleUserFeedback(data);
break;
case 'error.occurred':
// Handle system errors
handleSystemError(data);
break;
default:
console.log('Unknown event:', event);
}
res.status(200).json({ received: true });
} catch (error) {
console.error('Webhook processing error:', error);
res.status(500).json({ error: 'Internal server error' });
}
});
// Event handlers
function handleNewMessage(data) {
console.log('New message:', data.message.content);
// Save to database, send notifications, etc.
}
function handleNewConversation(data) {
console.log('New conversation:', data.conversation.id);
// Create CRM contact, send welcome email, etc.
}
function handleUserFeedback(data) {
console.log('User feedback:', data.rating);
// Update satisfaction metrics, trigger alerts, etc.
}
function handleSystemError(data) {
console.error('System error:', data.error);
// Send alerts to developers, log for analysis, etc.
}
app.listen(3000, () => {
console.log('Webhook server running on port 3000');
});→ Usage Notes:
- • Replace
chatbotIdandapiKeywith your actual values - • Add proper error handling for production use
- • Consider rate limiting and caching for high-traffic applications
- • Test thoroughly before deploying to production
Custom Chat Widget Styling
Brand-aligned CSS for complete visual customization
CSS
/* Custom TalkBuildr Chat Widget Styles */
:root {
/* Brand color variables */
--brand-primary: #6366f1; /* Indigo */
--brand-secondary: #8b5cf6; /* Purple */
--brand-accent: #f59e0b; /* Amber */
--brand-text: #1f2937; /* Gray-800 */
--brand-background: #ffffff; /* White */
--brand-border: #e5e7eb; /* Gray-200 */
}
/* Main widget container */
.talkbuildr-widget {
/* Brand typography */
font-family: 'Inter', -apple-system, sans-serif;
font-size: 14px;
line-height: 1.5;
color: var(--brand-text);
/* Custom dimensions */
width: 380px;
height: 600px;
border-radius: 16px;
box-shadow: 0 10px 40px rgba(0, 0, 0, 0.15);
/* Brand background */
background: var(--brand-background);
border: 1px solid var(--brand-border);
}
/* Launcher button */
.talkbuildr-launcher {
width: 60px;
height: 60px;
border-radius: 50%;
background: linear-gradient(135deg, var(--brand-primary), var(--brand-secondary));
border: none;
cursor: pointer;
/* Hover effects */
transition: all 0.3s ease;
box-shadow: 0 4px 20px rgba(99, 102, 241, 0.4);
}
.talkbuildr-launcher:hover {
transform: scale(1.1);
box-shadow: 0 6px 25px rgba(99, 102, 241, 0.6);
}
/* Message bubbles */
.talkbuildr-message-assistant {
background: linear-gradient(135deg, #f8fafc, #f1f5f9);
border: 1px solid var(--brand-border);
border-radius: 16px 16px 16px 4px;
color: var(--brand-text);
padding: 12px 16px;
margin: 8px 0;
box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1);
max-width: 80%;
word-wrap: break-word;
}
.talkbuildr-message-user {
background: linear-gradient(135deg, var(--brand-primary), var(--brand-secondary));
color: white;
border-radius: 16px 16px 4px 16px;
padding: 12px 16px;
margin: 8px 0 8px auto;
box-shadow: 0 2px 8px rgba(99, 102, 241, 0.3);
max-width: 80%;
word-wrap: break-word;
}
/* Input field */
.talkbuildr-input {
width: 100%;
border: 2px solid var(--brand-border);
border-radius: 24px;
padding: 12px 20px;
font-size: 16px;
font-family: inherit;
transition: border-color 0.3s ease;
background: var(--brand-background);
color: var(--brand-text);
}
.talkbuildr-input:focus {
outline: none;
border-color: var(--brand-primary);
box-shadow: 0 0 0 3px rgba(99, 102, 241, 0.1);
}
.talkbuildr-input::placeholder {
color: #9ca3af;
}
/* Send button */
.talkbuildr-send-button {
background: var(--brand-primary);
color: white;
border: none;
border-radius: 50%;
width: 40px;
height: 40px;
cursor: pointer;
transition: all 0.3s ease;
box-shadow: 0 2px 8px rgba(99, 102, 241, 0.3);
}
.talkbuildr-send-button:hover {
background: var(--brand-secondary);
transform: scale(1.05);
box-shadow: 0 4px 12px rgba(99, 102, 241, 0.4);
}
/* Typing indicator */
.talkbuildr-typing {
display: flex;
align-items: center;
padding: 12px 16px;
color: #6b7280;
font-size: 14px;
}
.talkbuildr-typing-dots {
display: flex;
gap: 4px;
margin-left: 8px;
}
.talkbuildr-typing-dot {
width: 6px;
height: 6px;
border-radius: 50%;
background: var(--brand-primary);
animation: typing 1.4s infinite ease-in-out;
}
.talkbuildr-typing-dot:nth-child(1) { animation-delay: -0.32s; }
.talkbuildr-typing-dot:nth-child(2) { animation-delay: -0.16s; }
@keyframes typing {
0%, 80%, 100% {
opacity: 0.3;
transform: scale(0.8);
}
40% {
opacity: 1;
transform: scale(1);
}
}
/* Scrollbar styling */
.talkbuildr-chat::-webkit-scrollbar {
width: 6px;
}
.talkbuildr-chat::-webkit-scrollbar-track {
background: #f1f1f1;
border-radius: 10px;
}
.talkbuildr-chat::-webkit-scrollbar-thumb {
background: var(--brand-primary);
border-radius: 10px;
}
.talkbuildr-chat::-webkit-scrollbar-thumb:hover {
background: var(--brand-secondary);
}
/* Mobile responsiveness */
@media (max-width: 480px) {
.talkbuildr-widget {
width: 100vw;
height: 100vh;
max-width: none;
max-height: none;
border-radius: 0;
position: fixed;
top: 0;
left: 0;
z-index: 9999;
}
.talkbuildr-launcher {
position: fixed;
bottom: 20px;
right: 20px;
z-index: 9998;
}
}→ Usage Notes:
- • Replace
chatbotIdandapiKeywith your actual values - • Add proper error handling for production use
- • Consider rate limiting and caching for high-traffic applications
- • Test thoroughly before deploying to production