Как правильно использовать webAppData в telebot?

Есть веб страница с кнопкой и счетчиком кликов на эту кнопку. Счетчик засчитывает количество кликов в переменную. Из этой переменной хочу сделать вывод в самого бота на telebot. Как вывести через web_app_data.data я понял, но выводится в формате {"clicks":1}. Как вывести только числовое значение? Почему по нажатию кнопки закрывается веб страничка в телеграмме и выводится сообщение о том, что данные пользователя были переданы боту, как это решить? Возможно есть аналогичные способы вывода данных из веб страницы в бота? Есть ли какие то советы по моему html или css?

<script src="https://telegram.org/js/telegram-web-app.js"></script>
<!doctype html>
<html lang="ru">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <title>BestShop</title>
  <style>
    @import url('https://fonts.googleapis.com/css2?family=Montserrat:wght@200;500&display=swap');
    * {
      margin: 0;
      padding: 0;
      box-sizing: border-box;
    }
    
    .image-coin {
      margin-top: 10%;
      margin-left: 25%;
      width: 200px;
      height: 200px;
      border: none;
      border-radius: 50%;
      background-image: url('https://i.sstatic.net/fzSbVP56.jpg');
      background-size: 111%;
      background-position: 50% 50%;
    }
  </style>
</head>

<body>
  <div>
    <p>Clicks: <a id="clicks">0</a></p>
    <button id="coin_click" class="image-coin" onClick="onClick()"></button>
  </div>
  <script src="https://telegram.org/js/telegram-web-app.js"></script>
  <script>
    let tg = window.Telegram.WebApp;
    let coin_click = document.getElementById("coin_click")

    var clicks = 0;

    function onClick() {
      clicks += 1;
      document.getElementById("clicks").innerHTML = clicks;
    }

    coin_click.addEventListener("click", () => {
      let data = {
        clicks: clicks
      }

      tg.sendData(JSON.stringify(data));
    })
  </script>
</body>

</html>

import telebot

from config import token
from telebot import types
from telebot.types import WebAppInfo

bot = telebot.TeleBot(token, parse_mode=None)


@bot.message_handler(commands=['start'])
def start_message(message):
    keyboard = types.ReplyKeyboardMarkup(resize_keyboard=True)
    button = types.KeyboardButton(text="Тестовая страница", web_app=WebAppInfo(weburl))
    keyboard.add(button)
    bot.send_message(message.chat.id, "Привет :)", reply_markup=keyboard)


@bot.message_handler(content_types=['web_app_data'])
def web_app(webAppMes):
    print(webAppMes.web_app_data.data)


bot.infinity_polling(none_stop=True)

Ответы (1 шт):

Автор решения: Ben Puls

Для начала преобразуйте данные webAppMes.web_app_data.data из строки в словарь. Для этого импортируем в код модуль json import json, затем преобразовываем, используя метод loads(). И тогда получается:

data = json.loads(webAppMes.web_app_data.data) # Теперь это словарь

print(data['clicks']) # Получаем содержимое

Что касается закрытия страницы. Создайте отдельную Telegram кнопку, которая будет появляться после первого нажатия на монетку:

function onClick() {
  clicks += 1;
  document.getElementById("clicks").innerHTML = clicks;
  if (!tg.MainButton.isVisible){ // Проверяем, что пользователь не видит кнопку
     tg.MainButton.show(); // Отображаем кнопку
  }
}

А затем обработайте её нажатие и вот уже после зарегистрированного нажатия смело отправляйте данные.

Telegram.WebApp.onEvent('mainButtonClicked', function() {
    tg.sendData(JSON.stringify({clicks: clicks}));
});
→ Ссылка