DEV Community

Cover image for Building and deploying a Generative AI Support Chatbot with Flask and Google's Gemini API
chloe
chloe

Posted on • Edited on

Building and deploying a Generative AI Support Chatbot with Flask and Google's Gemini API

Example of what is being built:
Image description

Introduction

As a backend developer specialising in AI chatbots, I recently built a production-ready GenAI chatbot that demonstrates enterprise-level security, scalability, and user experience. This project showcases my ability to create full-stack solutions that clients can trust with their business communications.

You can see the live chatbot in action on my website - it's the orange chatbot on the bottom right (I also have a non-GenAI chatbot for comparison - the purple icon on the bottom right).

The Challenge

I needed to create a secure, embeddable GenAI chatbot that could:

  • Handle multiple clients with proper authentication
  • Integrate seamlessly into any website
  • Provide intelligent responses using Google's Gemini API
  • Maintain British English consistency (important for UK business)
  • Scale across multiple domains with CORS protection

Architecture Overview

Backend: Flask + Google Gemini API (Deployed on Heroku)
Frontend: Vanilla JavaScript widget + Next.js integration
Security: Client ID authentication + CORS protection
Deployment: Heroku for backend, Vercel for website

Backend Development

  1. Security-First Authentication System

The foundation of any enterprise chatbot is robust security. I implemented a dual-layer authentication system:

# Client ID validation decorator
def require_client_id(f):
    @wraps(f)
    def decorated_function(*args, **kwargs):
        client_id = None

        # Multiple authentication methods
        if 'X-Client-ID' in request.headers:
            client_id = request.headers.get('X-Client-ID')
        elif request.args.get('client_id'):
            client_id = request.args.get('client_id')
        elif request.is_json:
            client_id = request.json.get('client_id')

        if not client_id or client_id not in ALLOWED_CLIENT_IDS:
            return jsonify({
                "error": "Invalid client ID",
                "botResponse": "This chatbot is not authorised for your website."
            }), 403

        return f(*args, **kwargs)
    return decorated_function
Enter fullscreen mode Exit fullscreen mode

Key Features:

  • Client ID validation prevents unauthorised usage
  • Flexible authentication (headers, query params, JSON body)
  • Graceful error handling with user-friendly messages
  1. CORS Configuration for Multi-Domain Support
CORS(app, origins=[
    "https://oxford-genai-chatbot-9c5c571579c0.herokuapp.com",
    "https://website-portfolio-iota-khaki.vercel.app",
    "http://localhost:8000",
    "http://localhost:3000"
], supports_credentials=True)
Enter fullscreen mode Exit fullscreen mode
  1. Intelligent Response Processing

The chatbot integrates with Google's Gemini API while ensuring consistent British English output:

def convert_to_british_english(text):
    conversions = {
        'personalized': 'personalised',
        'customization': 'customisation',
        'organization': 'organisation',
        # ... more conversions
    }

    converted_text = text
    for american, british in conversions.items():
        regex = re.compile(r'\b' + re.escape(american) + r'\b')
        converted_text = regex.sub(british, converted_text)

    return converted_text
Enter fullscreen mode Exit fullscreen mode

Business Value: This ensures consistent brand voice for UK clients, demonstrating attention to detail in client requirements.

  1. Dynamic Client Management
@app.route('/manage_clients', methods=['POST'])
def manage_clients():
    # Admin authentication
    if admin_password != 'SECURE_PASSWORD_HERE':
        return jsonify({"error": "Unauthorised"}), 401

    # Dynamic client addition/removal
    if action == 'add' and client_id:
        if client_id not in ALLOWED_CLIENT_IDS:
            ALLOWED_CLIENT_IDS.append(client_id)
            save_allowed_clients(ALLOWED_CLIENT_IDS)
Enter fullscreen mode Exit fullscreen mode

Frontend Development

  1. Self-Contained Widget Architecture

I created a completely self-contained JavaScript widget that can be embedded anywhere:

(function() {
  // Widget configuration from script tag
  const getScriptConfig = () => {
    const scriptTag = document.getElementById('oxford-genai-chatbot');

    return {
      clientId: scriptTag.getAttribute('data-client-id'),
      theme: scriptTag.getAttribute('data-theme') || 'light',
      position: scriptTag.getAttribute('data-position') || 'bottom-right',
      apiEndpoint: scriptTag.getAttribute('data-api-endpoint')
    };
  };
Enter fullscreen mode Exit fullscreen mode

Key Benefits:

  • Zero external dependencies
  • Configurable via data attributes
  • Prevents conflicts with existing website code
  1. Dynamic Styling System
const styles = `
  .genai-chatbot-toggler {
    position: fixed !important;
    background: #f97316 !important;
    border-radius: 50% !important;
    z-index: 9999 !important;
    transition: all 0.3s ease !important;
  }

  .genai-chatbot {
    position: fixed !important;
    width: 420px !important;
    background: #fff !important;
    border-radius: 15px !important;
    box-shadow: 0 0 128px 0 rgba(0, 0, 0, 0.1) !important;
  }
`;

// Inject styles dynamically
const styleElement = document.createElement('style');
styleElement.innerHTML = styles;
document.head.appendChild(styleElement);
Enter fullscreen mode Exit fullscreen mode
  1. Robust Error Handling
const generateResponse = async (chatElement) => {
  try {
    const response = await fetch(BACKEND_URL, requestOptions);

    if (!response.ok) {
      const errorData = await response.json();
      throw new Error(errorData.botResponse);
    }

    const data = await response.json();
    messageElement.textContent = data.botResponse;

  } catch (error) {
    messageElement.classList.add("error");
    messageElement.textContent = "Sorry, I'm having trouble connecting. Please try again later.";
  }
};
Enter fullscreen mode Exit fullscreen mode

Integration with Next.js

Clean Component Architecture

'use client'
import Script from "next/script";

export default function GenAIChatbotScript() {
  return (
    <Script
      src="https://oxford-genai-chatbot-9c5c571579c0.herokuapp.com/chatbot-widget.js"
      id="oxford-genai-chatbot"
      data-client-id="oxford_developer_website"
      data-theme="light"
      data-position="bottom-left"
      data-api-endpoint="https://oxford-genai-chatbot-9c5c571579c0.herokuapp.com"
      strategy="afterInteractive"
      onLoad={() => console.log("GenAI Chatbot loaded successfully")}
      onError={(e) => console.error("Error loading GenAI chatbot:", e)}
    />
  );
}
Enter fullscreen mode Exit fullscreen mode

Deployment Strategy

Backend Deployment (Heroku)

  1. Environment Configuration: Secure API keys via environment variables
  2. Production Optimisation: Disabled debug mode, optimised CORS settings
  3. Health Monitoring: Built-in error tracking and logging

Frontend Integration (Vercel)

The widget integrates seamlessly with my Next.js portfolio:

/* Global styles for chatbot positioning */
body .genai-chatbot-toggler {
  background: #f97316 !important;
  right: 175px !important;
}

body .chatbot-toggler {
  background: #724ae8 !important;
  right: 100px !important;
}
Enter fullscreen mode Exit fullscreen mode

Technical Highlights

  1. Multi-Chatbot Architecture
    I designed the system to support both GenAI and traditional rule-based chatbots on the same page, with distinct visual themes and positioning.

  2. Security Through Obscurity + Authentication

  3. Client ID system prevents unauthorised API usage

  4. CORS protection blocks cross-origin attacks

  5. Admin panel for dynamic client management

  6. User Experience Focus

  7. Smooth animations and transitions

  8. Mobile-responsive design

  9. Consistent British English for UK market

  10. Visual text input feedback

  11. Production-Ready Error Handling

  12. Graceful API failure recovery

  13. User-friendly error messages

  14. Comprehensive logging for debugging

Results and Business Impact

Technical Achievements:

  • Zero-dependency, embeddable widget
  • Sub-second response times
  • 100% uptime since deployment
  • Scales across multiple client websites

Business Value:

  • Demonstrates full-stack capabilities to potential clients
  • Showcases AI integration expertise
  • Proves ability to deliver production-ready solutions
  • Shows attention to UK market requirements (British English)

Key Learnings

  1. Security First: Implementing proper authentication from day one prevents future headaches
  2. Self-Contained Widgets: Avoiding external dependencies makes integration seamless
  3. User Experience Matters: Small details like text visibility and smooth animations significantly impact perception
  4. Documentation Through Code: Clean, readable code serves as its own documentation

Conclusion

This GenAI chatbot project demonstrates my ability to create enterprise-level solutions that combine modern AI capabilities with robust security and excellent user experience. The modular architecture allows for easy scaling and customisation for different client needs.

Technologies Used: Flask, Google Gemini API, JavaScript ES6+, Next.js, SCSS, Heroku, Vercel

Live Demo: https://website-portfolio-iota-khaki.vercel.app


Looking for a developer who can deliver production-ready AI solutions? Feel free to connect with me to discuss your project requirements via the contact form on my website https://website-portfolio-iota-khaki.vercel.app

Tags

ai #chatbot #flask #javascript #backend #frontend #heroku #nextjs

Top comments (0)