I am creating a telegram bot for ordering food delivery in Python with AIogram 3 and WebApp functions. My catalog is made using HTML and JavaScript; from the window, data about the products selected by the user is transferred to the chat bot. Now I need to implement a full-fledged shopping cart that saves all selected products. However, there is a problem with this, in the script below I have a function ‘web_app’ that receives data from the catalog about the selected products and sends a message, I also made it so that it immediately adds these products to the cart. Then through ‘view_basket’ and ‘clear_basket’ the user can open the basket to view the contents and clear the basket respectively. However, when I try to open the recycle bin itself, I get an error: “in web_app
json_data = callback_query.web_app_data.data
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
AttributeError: ‘NoneType’ object has no attribute ‘data'”
There is no way to fix it, even if you replace callback_query with message. Please tell me how to fix this error so that the data is successfully transferred to the cart, below is the code in python and JS, as well as a video of how the bot works.
basket = {}
@dp.message()
async def web_app(callback_query):
json_data = callback_query.web_app_data.data
parsed_data = json.loads(json_data)
message = ""
for item in parsed_data['items']:
product_name = item['name']
price = item['price']
quantity = item['quantity']
total_item_price = price * quantity
message += f"Продукт: {product_name}n"
message += f"Стоимость: {total_item_price}n"
message += f"Количество: {quantity}nn"
# Добавляем товар в корзину или обновляем количество
if product_name in basket:
basket[product_name] += quantity
else:
basket[product_name] = quantity
message += f"Общая стоимость: {parsed_data['totalPrice']}"
# Отправляем сообщение с информацией о товарах
await bot.send_message(callback_query.from_user.id, f"""
{message}
""")
@dp.message(F.text == 'Корзина')
async def view_basket(message: types.Message):
if basket:
basket_content = "n".join([f"{product}: {quantity}" for product, quantity in basket.items()])
await message.answer(f"Содержимое корзины:n{basket_content}")
else:
await message.answer("Корзина пуста.")
@dp.message(F.text == 'Очистить корзину')
async def clear_basket(message: types.Message):
global basket
basket = {}
await message.answer("Корзина очищена.")
JavaScript:
let tg = window.Telegram.WebApp;
tg.expand();
tg.MainButton.textColor = '#FFFFFF';
tg.MainButton.color = '#2cab37';
let items = {
item1: { id: "item1", price: 80, quantity: 0, name: "Молоко коровка из кореновки 2,5%" },
item2: { id: "item2", price: 120, quantity: 0, name: "Масло сливочное кубанский молочник 82,5%" },
item3: { id: "item3", price: 70, quantity: 0, name: "Творог коровка из кореновки 9%" },
item4: { id: "item4", price: 47, quantity: 0, name: "Пломбир коровка из кореновки" },
item5: { id: "item5", price: 100, quantity: 0, name: "Кефир коровка из кореновки 2,5%" },
item6: { id: "item6", price: 150, quantity: 0, name: "Ряженка коровка из кореновки 2,5%" },
item7: { id: "item7", price: 110, quantity: 0, name: "Йогурт коровка из кореновки" },
item8: { id: "item8", price: 70, quantity: 0, name: "Сгущенка коровка из кореновки 8,5%" }
};
function updateQuantity(itemId, change) {
let item = items[itemId];
item.quantity += change;
if (item.quantity < 0) item.quantity = 0;
if (item.quantity > 10) item.quantity = 10;
document.getElementById("qty" + itemId.slice(-1)).innerText = item.quantity;
toggleItem(itemId);
}
function toggleItem(itemId) {
let item = items[itemId];
let btn = document.getElementById("add" + itemId.slice(-1));
let subtractBtn = document.getElementById("subtract" + itemId.slice(-1));
btn.classList.remove('added-to-cart');
btn.style.display = 'inline-block';
subtractBtn.style.display = 'inline-block';
let totalPrice = calculateTotalPrice();
if (totalPrice > 0) {
tg.MainButton.setText(`Общая цена товаров: ${totalPrice}`);
if (!tg.MainButton.isVisible) {
tg.MainButton.show();
}
} else {
tg.MainButton.hide();
}
}
function openModal(element) {
var productName = element.parentNode.querySelector('p').textContent;
document.getElementById('product-name').textContent = productName;
document.getElementById('my-modal').style.display = 'block';
}
function closeModal() {
document.getElementById('my-modal').style.display = 'none';
}
document.getElementById("open-modal-btn").addEventListener("click", function() {
document.getElementById("my-modal").classList.add("open")
})
document.getElementById("close-my-modal-btn").addEventListener("click", function() {
document.getElementById("my-modal").classList.remove("open")
})
Telegram.WebApp.onEvent("mainButtonClicked", function() {
let data = {
items: Object.values(items).filter(item => item.quantity > 0),
totalPrice: calculateTotalPrice()
};
tg.sendData(JSON.stringify(data));
});
function calculateTotalPrice() {
return Object.values(items).reduce((total, item) => total + (item.price * item.quantity), 0);
}
document.getElementById("add1").addEventListener("click", function() {
updateQuantity("item1", 1);
});
document.getElementById("subtract1").addEventListener("click", function() {
updateQuantity("item1", -1);
});
text
I tried to create separate functions, ChatGPT just can’t work with this bot.