DEV Community

Paul Robertson
Paul Robertson

Posted on

Build Your First AI Chatbot in 30 Minutes: Complete Beginner Tutorial with OpenAI API

This article contains affiliate links. I may earn a commission at no extra cost to you.


title: "Build Your First AI Chatbot in 30 Minutes: Complete Beginner Tutorial with OpenAI API"
published: true
description: "Learn to create a functional AI chatbot with conversation memory, error handling, and deploy it for free - all in 30 minutes!"
tags: ai, tutorial, javascript, openai, beginners

cover_image: https://dev-to-uploads.s3.amazonaws.com/uploads/articles/chatbot-tutorial-cover.png

Build Your First AI Chatbot in 30 Minutes: Complete Beginner Tutorial with OpenAI API

Ever wanted to build your own AI chatbot but felt overwhelmed by the complexity? You're in the right place! In this tutorial, we'll create a fully functional chatbot from scratch using Node.js and OpenAI's API. By the end, you'll have a working chatbot with conversation memory that you can deploy for free.

What We're Building

Our chatbot will:

  • Have natural conversations using OpenAI's GPT models
  • Remember conversation history within each session
  • Handle errors gracefully
  • Cost less than $5/month to run
  • Be deployable to a free hosting service

Prerequisites

You'll need:

  • Basic JavaScript knowledge
  • Node.js installed on your computer
  • An OpenAI account (free tier works fine)
  • 30 minutes of your time

Step 1: Set Up Your OpenAI API Key

First, let's get your OpenAI API credentials:

  1. Visit OpenAI's platform
  2. Sign up or log in to your account
  3. Navigate to "API Keys" in the left sidebar
  4. Click "Create new secret key"
  5. Copy and save this key securely - you won't see it again!

Important: Never commit API keys to version control. We'll use environment variables to keep them safe.

Step 2: Initialize Your Project

Let's create our project structure:

mkdir ai-chatbot
cd ai-chatbot
npm init -y
npm install express openai dotenv
Enter fullscreen mode Exit fullscreen mode

Create these files in your project directory:

touch app.js .env index.html
Enter fullscreen mode Exit fullscreen mode

Add your API key to .env:

OPENAI_API_KEY=your_api_key_here
PORT=3000
Enter fullscreen mode Exit fullscreen mode

Step 3: Build the Backend

Create app.js with our server logic:

const express = require('express');
const OpenAI = require('openai');
require('dotenv').config();

const app = express();
const port = process.env.PORT || 3000;

// Initialize OpenAI
const openai = new OpenAI({
  apiKey: process.env.OPENAI_API_KEY,
});

// Middleware
app.use(express.json());
app.use(express.static('.'));

// Store conversation history (in production, use a database)
const conversations = new Map();

// Cost optimization: limit conversation history
const MAX_HISTORY_LENGTH = 10;

app.post('/chat', async (req, res) => {
  try {
    const { message, sessionId = 'default' } = req.body;

    if (!message) {
      return res.status(400).json({ error: 'Message is required' });
    }

    // Get or create conversation history
    let history = conversations.get(sessionId) || [];

    // Add user message to history
    history.push({ role: 'user', content: message });

    // Limit history length for cost control
    if (history.length > MAX_HISTORY_LENGTH) {
      history = history.slice(-MAX_HISTORY_LENGTH);
    }

    // Create chat completion
    const completion = await openai.chat.completions.create({
      model: 'gpt-3.5-turbo', // Cost-effective model
      messages: [
        {
          role: 'system',
          content: 'You are a helpful assistant. Keep responses concise and friendly.'
        },
        ...history
      ],
      max_tokens: 150, // Limit response length for cost control
      temperature: 0.7,
    });

    const assistantMessage = completion.choices[0].message.content;

    // Add assistant response to history
    history.push({ role: 'assistant', content: assistantMessage });
    conversations.set(sessionId, history);

    res.json({ 
      message: assistantMessage,
      tokensUsed: completion.usage.total_tokens
    });

  } catch (error) {
    console.error('Error:', error);

    // Handle different types of errors
    if (error.code === 'insufficient_quota') {
      res.status(429).json({ error: 'API quota exceeded. Please try again later.' });
    } else if (error.code === 'invalid_api_key') {
      res.status(401).json({ error: 'Invalid API key.' });
    } else {
      res.status(500).json({ error: 'Something went wrong. Please try again.' });
    }
  }
});

// Clear conversation history
app.delete('/chat/:sessionId', (req, res) => {
  const { sessionId } = req.params;
  conversations.delete(sessionId);
  res.json({ message: 'Conversation cleared' });
});

app.listen(port, () => {
  console.log(`Chatbot server running at http://localhost:${port}`);
});
Enter fullscreen mode Exit fullscreen mode

Step 4: Create the Frontend

Add this to index.html:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>AI Chatbot</title>
    <style>
        body {
            font-family: Arial, sans-serif;
            max-width: 800px;
            margin: 0 auto;
            padding: 20px;
            background-color: #f5f5f5;
        }
        .chat-container {
            background: white;
            border-radius: 10px;
            padding: 20px;
            box-shadow: 0 2px 10px rgba(0,0,0,0.1);
        }
        .messages {
            height: 400px;
            overflow-y: auto;
            border: 1px solid #ddd;
            padding: 15px;
            margin-bottom: 15px;
            border-radius: 5px;
        }
        .message {
            margin-bottom: 15px;
            padding: 10px;
            border-radius: 5px;
        }
        .user {
            background-color: #007bff;
            color: white;
            text-align: right;
        }
        .assistant {
            background-color: #e9ecef;
            color: #333;
        }
        .input-container {
            display: flex;
            gap: 10px;
        }
        input[type="text"] {
            flex: 1;
            padding: 10px;
            border: 1px solid #ddd;
            border-radius: 5px;
        }
        button {
            padding: 10px 20px;
            background-color: #007bff;
            color: white;
            border: none;
            border-radius: 5px;
            cursor: pointer;
        }
        button:hover {
            background-color: #0056b3;
        }
        button:disabled {
            background-color: #ccc;
            cursor: not-allowed;
        }
        .error {
            color: #dc3545;
            font-style: italic;
        }
    </style>
</head>
<body>
    <div class="chat-container">
        <h1>AI Chatbot</h1>
        <div id="messages" class="messages"></div>
        <div class="input-container">
            <input type="text" id="messageInput" placeholder="Type your message..." onkeypress="handleKeyPress(event)">
            <button onclick="sendMessage()" id="sendButton">Send</button>
            <button onclick="clearChat()" id="clearButton">Clear</button>
        </div>
    </div>

    <script>
        const messagesDiv = document.getElementById('messages');
        const messageInput = document.getElementById('messageInput');
        const sendButton = document.getElementById('sendButton');
        const sessionId = 'session_' + Date.now();

        function addMessage(content, role) {
            const messageDiv = document.createElement('div');
            messageDiv.className = `message ${role}`;
            messageDiv.textContent = content;
            messagesDiv.appendChild(messageDiv);
            messagesDiv.scrollTop = messagesDiv.scrollHeight;
        }

        async function sendMessage() {
            const message = messageInput.value.trim();
            if (!message) return;

            // Disable input while processing
            messageInput.disabled = true;
            sendButton.disabled = true;
            sendButton.textContent = 'Sending...';

            // Add user message to chat
            addMessage(message, 'user');
            messageInput.value = '';

            try {
                const response = await fetch('/chat', {
                    method: 'POST',
                    headers: {
                        'Content-Type': 'application/json',
                    },
                    body: JSON.stringify({ message, sessionId }),
                });

                const data = await response.json();

                if (response.ok) {
                    addMessage(data.message, 'assistant');
                } else {
                    addMessage(`Error: ${data.error}`, 'error');
                }
            } catch (error) {
                addMessage('Network error. Please check your connection.', 'error');
            }

            // Re-enable input
            messageInput.disabled = false;
            sendButton.disabled = false;
            sendButton.textContent = 'Send';
            messageInput.focus();
        }

        function handleKeyPress(event) {
            if (event.key === 'Enter') {
                sendMessage();
            }
        }

        async function clearChat() {
            try {
                await fetch(`/chat/${sessionId}`, { method: 'DELETE' });
                messagesDiv.innerHTML = '';
            } catch (error) {
                console.error('Error clearing chat:', error);
            }
        }

        // Focus input on page load
        messageInput.focus();
    </script>
</body>
</html>
Enter fullscreen mode Exit fullscreen mode

Step 5: Test Your Chatbot

Run your chatbot locally:

node app.js
Enter fullscreen mode Exit fullscreen mode

Open your browser to http://localhost:3000 and start chatting!

Step 6: Deploy to Railway (Free)

Railway offers free hosting perfect for our chatbot:

  1. Create a Railway account
  2. Install Railway CLI: npm install -g @railway/cli
  3. Login: railway login
  4. Deploy: railway deploy

Railway will automatically detect your Node.js app and deploy it. Don't forget to add your environment variables in the Railway dashboard!

Cost Optimization Tips

To keep costs under $5/month:

  1. Use GPT-3.5-turbo: Much cheaper than GPT-4
  2. Limit conversation history: We keep only 10 messages
  3. Set max_tokens: Prevents overly long responses
  4. Monitor usage: Check your OpenAI dashboard regularly
  5. Add rate limiting: Prevent abuse in production

Common Troubleshooting

"Invalid API Key" error: Double-check your .env file and ensure the key is correct.

"Quota exceeded" error: You've hit your API limit. Check your OpenAI billing dashboard.

Deployment issues: Ensure all environment variables are set in your hosting platform.

Slow responses: This is normal - AI models take time to generate responses.

Download the Complete Code

You can find the complete starter code on GitHub with additional examples and improvements.

What's Next?

Now that you have a working chatbot, consider these enhancements:

  • Add user authentication
  • Implement persistent storage with a database
  • Add file upload capabilities
  • Create different chatbot personalities
  • Add voice input/output
  • Implement rate limiting for production use

Conclusion

Congratulations! You've built a fully functional AI chatbot with conversation memory, error handling, and cost optimization. The best part? It's deployable for free and costs less than a coffee per month to run.

This foundation gives you everything you need to start experimenting with AI in your projects. The key is to start simple and iterate - exactly what we've done here.

What will you build next with your new AI skills? Share your creations in the comments below!


Found this tutorial helpful? Give it a ❤️ and follow for more practical AI tutorials!


Tools mentioned:

Top comments (0)