├── README.md
├── .gitattributes
├── bot
├── keyboards.py
├── main.py
└── handlers.py
└── site
├── style.css
├── index.html
└── app.js
/README.md:
--------------------------------------------------------------------------------
1 | # Web_App
2 | Код из видео https://youtu.be/O1ZRJXKBa4U
3 |
--------------------------------------------------------------------------------
/.gitattributes:
--------------------------------------------------------------------------------
1 | # Auto detect text files and perform LF normalization
2 | * text=auto
3 |
--------------------------------------------------------------------------------
/bot/keyboards.py:
--------------------------------------------------------------------------------
1 | from aiogram.types import WebAppInfo
2 | from aiogram import types
3 |
4 | web_app = WebAppInfo(url='site_url')
5 |
6 | keyboard = types.ReplyKeyboardMarkup(
7 | keyboard=[
8 | [types.KeyboardButton(text='Site', web_app=web_app)]
9 | ],
10 | resize_keyboard=True
11 | )
12 |
--------------------------------------------------------------------------------
/bot/main.py:
--------------------------------------------------------------------------------
1 | from aiogram import Bot, Dispatcher
2 |
3 | import asyncio
4 |
5 | bot = Bot(token='token')
6 | dp = Dispatcher(bot=bot)
7 |
8 | async def main():
9 | from handlers import dp
10 | try:
11 | await dp.start_polling()
12 | finally:
13 | await bot.session.close()
14 |
15 | if __name__ == "__main__":
16 | try:
17 | asyncio.run(main())
18 | except (KeyboardInterrupt, SystemExit):
19 | print('Bot stopped!')
20 |
--------------------------------------------------------------------------------
/site/style.css:
--------------------------------------------------------------------------------
1 | body {
2 | margin: 0;
3 | padding: 0;
4 | font-size: 18px;
5 | color: var(--tg-theme-text-color);
6 | background: var(--tg-theme-bg-color);
7 | }
8 |
9 | .container {
10 | max-width: 390px;
11 | }
12 |
13 | .inner {
14 | display: grid;
15 | grid-template-columns: 1fr 1fr;
16 | grid-template-rows: 200px 200px 200px;
17 | }
18 |
19 | .img {
20 | width: 150px;
21 | }
22 |
23 | .item {
24 | text-align: center;
25 | }
26 |
27 | .btn {
28 | display: inline-block;
29 | padding: 10px 20px;
30 | border: none;
31 | background: rgb(248, 168, 24);
32 | border-radius: 10px;
33 | color: #fff;
34 | text-transform: uppercase;
35 | font-weight: 700;
36 |
37 | transition: background .2s linear;
38 | }
39 |
40 | .btn:hover {
41 | background: lightgreen;
42 | }
43 |
44 | .usercard {
45 | text-align: center;
46 | }
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
--------------------------------------------------------------------------------
/site/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | Document
8 |
9 |
10 |
11 |
12 |
13 |

14 |
15 |
16 |
17 |

18 |
19 |
20 |
21 |

22 |
23 |
24 |
25 |

26 |
27 |
28 |
29 |

30 |
31 |
32 |
33 |

34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
--------------------------------------------------------------------------------
/bot/handlers.py:
--------------------------------------------------------------------------------
1 | from main import bot, dp
2 | from keyboards import keyboard
3 | from aiogram import types
4 | from aiogram.dispatcher.filters import Command
5 |
6 | @dp.message_handler(Command('start'))
7 | async def start(message: types.Message):
8 | await bot.send_message(message.chat.id, 'Тестируем WebApp!',
9 | reply_markup=keyboard)
10 |
11 | PRICE = {
12 | '1': [types.LabeledPrice(label='Item1', amount=100000)],
13 | '2': [types.LabeledPrice(label='Item2', amount=200000)],
14 | '3': [types.LabeledPrice(label='Item3', amount=300000)],
15 | '4': [types.LabeledPrice(label='Item4', amount=400000)],
16 | '5': [types.LabeledPrice(label='Item5', amount=500000)],
17 | '6': [types.LabeledPrice(label='Item6', amount=600000)]
18 | }
19 |
20 | @dp.message_handler(content_types='web_app_data')
21 | async def buy_process(web_app_message):
22 | await bot.send_invoice(web_app_message.chat.id,
23 | title='Laptop',
24 | description='Description',
25 | provider_token='pay_token',
26 | currency='rub',
27 | need_email=True,
28 | prices=PRICE[f'{web_app_message.web_app_data.data}'],
29 | start_parameter='example',
30 | payload='some_invoice')
31 |
32 | @dp.pre_checkout_query_handler(lambda query: True)
33 | async def pre_checkout_process(pre_checkout: types.PreCheckoutQuery):
34 | await bot.answer_pre_checkout_query(pre_checkout.id, ok=True)
35 |
36 | @dp.message_handler(content_types=types.ContentType.SUCCESSFUL_PAYMENT)
37 | async def successful_payment(message: types.Message):
38 | await bot.send_message(message.chat.id, 'Платеж прошел успешно!')
39 |
--------------------------------------------------------------------------------
/site/app.js:
--------------------------------------------------------------------------------
1 | let tg = window.Telegram.WebApp;
2 |
3 | tg.expand();
4 |
5 | tg.MainButton.textColor = '#FFFFFF';
6 | tg.MainButton.color = '#2cab37';
7 |
8 | let item = "";
9 |
10 | let btn1 = document.getElementById("btn1");
11 | let btn2 = document.getElementById("btn2");
12 | let btn3 = document.getElementById("btn3");
13 | let btn4 = document.getElementById("btn4");
14 | let btn5 = document.getElementById("btn5");
15 | let btn6 = document.getElementById("btn6");
16 |
17 | btn1.addEventListener("click", function(){
18 | if (tg.MainButton.isVisible) {
19 | tg.MainButton.hide();
20 | }
21 | else {
22 | tg.MainButton.setText("Вы выбрали товар 1!");
23 | item = "1";
24 | tg.MainButton.show();
25 | }
26 | });
27 |
28 | btn2.addEventListener("click", function(){
29 | if (tg.MainButton.isVisible) {
30 | tg.MainButton.hide();
31 | }
32 | else {
33 | tg.MainButton.setText("Вы выбрали товар 2!");
34 | item = "2";
35 | tg.MainButton.show();
36 | }
37 | });
38 |
39 | btn3.addEventListener("click", function(){
40 | if (tg.MainButton.isVisible) {
41 | tg.MainButton.hide();
42 | }
43 | else {
44 | tg.MainButton.setText("Вы выбрали товар 3!");
45 | item = "3";
46 | tg.MainButton.show();
47 | }
48 | });
49 |
50 | btn4.addEventListener("click", function(){
51 | if (tg.MainButton.isVisible) {
52 | tg.MainButton.hide();
53 | }
54 | else {
55 | tg.MainButton.setText("Вы выбрали товар 4!");
56 | item = "4";
57 | tg.MainButton.show();
58 | }
59 | });
60 |
61 | btn5.addEventListener("click", function(){
62 | if (tg.MainButton.isVisible) {
63 | tg.MainButton.hide();
64 | }
65 | else {
66 | tg.MainButton.setText("Вы выбрали товар 5!");
67 | item = "5";
68 | tg.MainButton.show();
69 | }
70 | });
71 |
72 | btn6.addEventListener("click", function(){
73 | if (tg.MainButton.isVisible) {
74 | tg.MainButton.hide();
75 | }
76 | else {
77 | tg.MainButton.setText("Вы выбрали товар 6!");
78 | item = "6";
79 | tg.MainButton.show();
80 | }
81 | });
82 |
83 |
84 | Telegram.WebApp.onEvent("mainButtonClicked", function(){
85 | tg.sendData(item);
86 | });
87 |
88 |
89 | let usercard = document.getElementById("usercard");
90 |
91 | let p = document.createElement("p");
92 |
93 | p.innerText = `${tg.initDataUnsafe.user.first_name}
94 | ${tg.initDataUnsafe.user.last_name}`;
95 |
96 | usercard.appendChild(p);
97 |
98 |
99 |
100 |
101 |
102 |
103 |
104 |
105 |
--------------------------------------------------------------------------------