Creating a cart system for Telegram bot with WebApp feature

Hey everyone! I’m working on a Telegram bot for my thesis using aiogram 3 in Python. I’ve implemented the WebApp feature to create a product catalog that looks like a real app window. I’ve got the basics working - users can view products and add them to a list. The bot receives this info through the ‘web_app’ method.

My issue is setting up a proper cart system. I want the bot to remember selected items, let me add more, and have options to remove individual products or clear the entire cart. I’m aiming to do this without a database since it’s just a template.

I’ve tried several approaches but I’m really stuck. Any ideas on how to implement this? I’m using HTML, CSS, and JavaScript to build the catalog windows. Here’s a simplified version of my current setup:

@dp.message()
async def handle_webapp_data(message):
    data = json.loads(message.web_app_data.data)
    response = "Selected items:\n"
    for item in data['items']:
        response += f"{item['name']}: {item['price']}\n"
    response += f"Total: {data['totalPrice']}"
    await message.answer(response)
let cart = {};

function updateCart(itemId, change) {
  if (!cart[itemId]) cart[itemId] = 0;
  cart[itemId] += change;
  if (cart[itemId] <= 0) delete cart[itemId];
  updateDisplay();
}

function updateDisplay() {
  // Update UI based on cart contents
}

// Event listener for 'Add to Cart' button

Any suggestions on improving this to create a full cart system?

I’ve implemented a similar cart system for a Telegram bot before. One approach that worked well was using Python’s shelve module to create a simple persistent storage solution. It allows you to store Python objects in a file-based database without needing a full DB setup.

Here’s a basic example of how you could use shelve:

import shelve

def get_user_cart(user_id):
    with shelve.open('user_carts') as db:
        return db.get(str(user_id), {})

def update_user_cart(user_id, cart):
    with shelve.open('user_carts') as db:
        db[str(user_id)] = cart

# In your message handler:
cart = get_user_cart(message.from_user.id)
# Update cart based on WebApp data
update_user_cart(message.from_user.id, cart)

This approach gives you persistence between bot restarts while keeping things relatively simple. You can easily add, remove, or modify items in the cart dictionary before saving it back to the shelf. Just be mindful of concurrent access if you scale up significantly.

hey henryg, i’ve tackled similar projects before. instead of using a database, you could store the cart data in the user’s session or a temporary memory structure.

try using a dictionary with user IDs as keys and their cart contents as values. this way, you can easily add, remove, and modify items for each user.

hope this helps! lemme know if u need more details.

For a cart system without a database, consider implementing a memory-based solution using Python’s built-in data structures. You could create a dictionary where each key is a user’s Telegram ID, and the value is another dictionary representing their cart.

Here’s a basic structure:

user_carts = {}

def add_to_cart(user_id, item):
    if user_id not in user_carts:
        user_carts[user_id] = {}
    user_carts[user_id][item['id']] = user_carts[user_id].get(item['id'], 0) + 1


def remove_from_cart(user_id, item_id):
    if user_id in user_carts and item_id in user_carts[user_id]:
        user_carts[user_id][item_id] -= 1
        if user_carts[user_id][item_id] <= 0:
            del user_carts[user_id][item_id]


def clear_cart(user_id):
    user_carts[user_id] = {}

This approach allows for easy manipulation of cart contents while keeping the data in memory. Remember to handle potential memory issues for long-running bots with many users.