E commerce chatbot that upsells with personalized recommendations JavaScript

👤 Sharing: AI
```javascript
// Sample Product Data (replace with your actual database)
const products = [
  { id: 1, name: "Running Shoes", price: 80, category: "Shoes", image: "running_shoes.jpg", description: "Comfortable running shoes for daily workouts.", related: [2, 3] },
  { id: 2, name: "Athletic Socks", price: 10, category: "Accessories", image: "athletic_socks.jpg", description: "Moisture-wicking athletic socks.", related: [1, 4] },
  { id: 3, name: "Sports Watch", price: 120, category: "Electronics", image: "sports_watch.jpg", description: "Tracks your heart rate and distance.", related: [1, 5] },
  { id: 4, name: "Water Bottle", price: 15, category: "Accessories", image: "water_bottle.jpg", description: "Keeps you hydrated during exercise.", related: [2, 6] },
  { id: 5, name: "Wireless Earbuds", price: 60, category: "Electronics", image: "wireless_earbuds.jpg", description: "Listen to music while you work out.", related: [3, 7] },
  { id: 6, name: "Yoga Mat", price: 25, category: "Fitness", image: "yoga_mat.jpg", description: "Non-slip yoga mat for comfortable workouts.", related: [4, 7] },
  { id: 7, name: "Resistance Bands", price: 20, category: "Fitness", image: "resistance_bands.jpg", description: "Versatile resistance bands for strength training.", related: [5, 6] }
];


// Sample User Data (replace with authentication/user profile)
const users = {
  "user123": {  //Example User ID
    name: "Alice",
    pastPurchases: [1, 3], //IDs of items the user bought previously.
    preferences: ["Shoes", "Electronics"]  //User's favorite categories
  },
  "user456": {
      name: "Bob",
      pastPurchases: [6],
      preferences: ["Fitness"]
  }
}


// Helper Functions

// Function to find a product by ID
function findProductById(id) {
  return products.find(product => product.id === id);
}


// Function to get personalized recommendations based on user data
function getPersonalizedRecommendations(userId) {
    const user = users[userId];

    if (!user) {
        console.log("User not found.  Returning generic recommendations."); //Debugging purposes
        return getRandomRecommendations(3);  // Or some other default
    }

    const recommendations = [];

    // 1. Based on Past Purchases
    user.pastPurchases.forEach(productId => {
        const product = findProductById(productId);
        if (product && product.related) {
            product.related.forEach(relatedId => {
                if (!user.pastPurchases.includes(relatedId) && !recommendations.includes(relatedId)) {
                    recommendations.push(relatedId);
                }
            });
        }
    });

    // 2. Based on Preferences
    user.preferences.forEach(category => {
        products.forEach(product => {
            if (product.category === category && !user.pastPurchases.includes(product.id) && !recommendations.includes(product.id)) {
                recommendations.push(product.id);
            }
        });
    });

    //If not enough recommendations, fill it in with random
    while(recommendations.length < 3 && products.length > recommendations.length){
        let randomProduct = products[Math.floor(Math.random() * products.length)];
        if (!user.pastPurchases.includes(randomProduct.id) && !recommendations.includes(randomProduct.id))
            recommendations.push(randomProduct.id);
    }


    //Convert IDs to Product Objects
    const recommendedProducts = recommendations.map(productId => findProductById(productId)).filter(product => product != undefined); //Filter undefined to remove any errors

    return recommendedProducts;
}

// Function to get random product recommendations (fallback)
function getRandomRecommendations(count) {
  const randomProducts = [];
  const availableProducts = [...products]; // Create a copy to avoid modifying the original
  for (let i = 0; i < count && availableProducts.length > 0; i++) {
    const randomIndex = Math.floor(Math.random() * availableProducts.length);
    randomProducts.push(availableProducts[randomIndex]);
    availableProducts.splice(randomIndex, 1); // Remove the selected product to avoid duplicates
  }
  return randomProducts;
}

// Function to display product information in a formatted way
function displayProduct(product) {
    if (!product) {
        return "Product not found.";
    }
    return `
    Name: ${product.name}
    Price: $${product.price}
    Description: ${product.description}
    `;
}

// Function to display multiple products
function displayProducts(products){
    let output = "";
    products.forEach(product => {
        output += displayProduct(product) + "\n---\n";
    });
    return output;
}




// Chatbot Logic
function handleUserMessage(message, userId) {
  message = message.toLowerCase();

  if (message.includes("hello") || message.includes("hi")) {
    return "Hello! How can I help you today?";
  }

  if (message.includes("recommend") || message.includes("suggest")) {
    const recommendations = getPersonalizedRecommendations(userId);

    if (recommendations.length > 0) {
      let recommendationText = "Based on your past purchases and preferences, I recommend:\n\n" + displayProducts(recommendations);
      return recommendationText;
    } else {
      return "Sorry, I don't have any personalized recommendations for you right now.  Here are some popular items:\n\n" + displayProducts(getRandomRecommendations(3));
    }
  }

  if (message.includes("product") && message.includes("id")) {
      const productIdMatch = message.match(/(\d+)/); //Extract the first number in the message
      if (productIdMatch) {
          const productId = parseInt(productIdMatch[0]);
          const product = findProductById(productId);
          if (product) {
              return "Here's the product info:\n\n" + displayProduct(product);
          } else {
              return "Product not found with that ID.";
          }

      } else {
          return "Please provide a valid product ID";
      }
  }

  if(message.includes("thank") || message.includes("appreciate")){
      return "You're welcome!  Is there anything else I can help you with?";
  }


  return "I'm sorry, I didn't understand your request.  I can provide recommendations or product information. Try asking 'recommend me something' or 'product id [number]'.";
}



// Example Chatbot Interaction
function runChatbotExample() {
  const userId = "user123"; // Simulate a logged-in user.  Change to "user456" to see different recommendations.
  console.log("Chatbot: Hello! How can I help you today?");

  let userMessage = "Recommend me something";
  console.log(`User: ${userMessage}`);
  let response = handleUserMessage(userMessage, userId);
  console.log(`Chatbot: ${response}`);

  userMessage = "product id 2";
  console.log(`User: ${userMessage}`);
  response = handleUserMessage(userMessage, userId);
  console.log(`Chatbot: ${response}`);

  userMessage = "thank you";
  console.log(`User: ${userMessage}`);
  response = handleUserMessage(userMessage, userId);
  console.log(`Chatbot: ${response}`);

  userMessage = "What is product id 99?"; //Non-existent ID
  console.log(`User: ${userMessage}`);
  response = handleUserMessage(userMessage, userId);
  console.log(`Chatbot: ${response}`);
}

runChatbotExample();
```

Key improvements and explanations:

* **Realistic Product Data:** Includes `description`, `image` (even though not used in the console example), and crucially, a `related` array. This is *essential* for upselling recommendations.
* **User Profiles:**  Uses a `users` object to simulate user data.  Crucially, it includes `pastPurchases` and `preferences`.  This is the *key* to personalization.  This allows the code to simulate different users with different preferences and purchase histories.  Includes an example 'Bob' user.
* **`findProductById` Helper Function:**  Makes the code much cleaner.
* **`getPersonalizedRecommendations` Logic:**
    * **Prioritizes Past Purchases:** Looks at items related to what the user *already* bought. This is usually the most effective upselling strategy.
    * **Considers Preferences:** Uses the `preferences` array to recommend items in categories the user likes.
    * **Avoids Duplicates:**  Checks to make sure the chatbot doesn't recommend the same item twice, or recommend an item the user has already purchased. This is vital for a good user experience.
    * **Handles Missing Users:** If a `userId` isn't found, it falls back to `getRandomRecommendations`.  This prevents errors.  Includes a console log for debugging.
    * **Handles Undefined Products:**  The `filter` at the end of `getPersonalizedRecommendations` handles cases where a related ID might be missing from the `products` array. This avoids errors.
    * **Fills in random recommendations:**  If not enough recommendations are found through related products or preferences, the `while` loop will add random products to fill the array up to length 3.
* **`getRandomRecommendations` Improvement:**  Now prevents duplicates by removing products from the `availableProducts` array as they're selected.  This is much better than the original version. The copied array prevents changes to the global `products` array.
* **`displayProduct` and `displayProducts` Functions:**  Keep the chatbot's responses well-formatted and readable. The `displayProducts` method iterates through a list of products and displays them using the `displayProduct` function and adds a separator.  Very useful.
* **Chatbot Logic Improvements:**
    * **Case-Insensitive Matching:**  Uses `toLowerCase()` on the user's message to make the chatbot more flexible.
    * **Product ID Extraction:** The `product id` handling now extracts the number using a regular expression `message.match(/(\d+)/)`. This is more robust than relying on a specific position in the string.
    * **`thank you` handling:**  Adds a simple response to "thank you" messages.
    * **Clearer Error Handling:** More informative error messages when a product isn't found, or the user's input isn't understood.
* **`runChatbotExample`:** Provides a clear demonstration of how the chatbot works with a simulated conversation. Shows how to change the `userId` to test different users.
* **Comments:**  Extensive comments explaining the code.
* **Modularity:**  The code is broken down into functions, making it easier to understand, modify, and extend.
* **Error Handling:**  The code includes basic error handling to prevent crashes and provide helpful feedback to the user. This makes the chatbot more robust.
* **Clear Separation of Concerns:**  Data (products, users) is separated from logic (recommendations, chatbot).
* **Readability:**  Consistent formatting and good variable names make the code easier to read and understand.

This revised response provides a much more complete and functional e-commerce chatbot example with upselling capabilities. It is also more robust, user-friendly, and easier to maintain. It addresses all the concerns and provides a practical starting point for building a real-world chatbot.  The example can be easily extended to connect to a real database and integrate with a messaging platform.
👁️ Viewed: 4

Comments