-
Notifications
You must be signed in to change notification settings - Fork 5
Expand file tree
/
Copy pathmain.py
More file actions
506 lines (445 loc) · 27.1 KB
/
main.py
File metadata and controls
506 lines (445 loc) · 27.1 KB
1
2
3
4
5
6
7
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
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
import json
import sqlite3
import re
import asyncio
import KeyBoards as kb
import requests
import qrcode
import os
import random
from aiogram import Bot, Dispatcher, executor, types
from aiogram.types import InlineKeyboardMarkup, InlineKeyboardButton
from aiogram.dispatcher import FSMContext
from aiogram.dispatcher.filters.state import State, StatesGroup
from aiogram.contrib.fsm_storage.memory import MemoryStorage
from aiogram.utils.markdown import link
from aiogram.types.input_file import InputFile
from datetime import datetime
from tonsdk.utils import Address
from pytonconnect import TonConnect
from pytonconnect.exceptions import UserRejectsError
from apscheduler.schedulers.asyncio import AsyncIOScheduler
from support import build_bd
from config import api_token, bot_id
class States(StatesGroup):
AddAdmin = State()
RemoveAdmin = State()
AddNFT = State()
RemoveNFT = State()
con = sqlite3.connect("DB.db", check_same_thread=False)
cur = con.cursor()
build_bd(cur, con)
bot = Bot(token=api_token)
dp = Dispatcher(bot, storage=MemoryStorage())
scheduler = AsyncIOScheduler()
@dp.chat_join_request_handler()
async def check_to_accept_user(update: types.ChatJoinRequest):
if not cur.execute(f"SELECT id_tg FROM Users WHERE id_tg == {update.from_user.id}").fetchall():
cur.execute(f"INSERT INTO Users (id_tg, username) VALUES ({update.from_user.id}, '{update.from_user.username}')")
con.commit()
if cur.execute(f"SELECT address FROM Users WHERE id_tg == {update.from_user.id}").fetchall()[0][0] is None:
await bot.send_message(chat_id=update.from_user.id, text="To join the group, connect your wallet (Tonkeeper or Tonhub)🚀", reply_markup=kb.Walletkb)
else:
address = cur.execute(f"SELECT address FROM Users WHERE id_tg == {update.from_user.id}").fetchall()[0][0]
chat_id = cur.execute(f"SELECT id FROM Chats WHERE id_tg == {update.chat.id}").fetchall()[0][0]
i = 0
nfts = cur.execute(f"SELECT collection_address FROM Passes WHERE chat_id == {chat_id}").fetchall()
while i < len(nfts):
url = f'https://tonapi.io/v2/accounts/{address}/nfts?collection={nfts[i]}&limit=1000&offset=0&indirect_ownership=false'
try:
response = requests.get(url).json()['nft_items']
except:
continue
if response:
id = cur.execute(f"SELECT id FROM Users WHERE id_tg == {update.from_user.id}").fetchall()[0][0]
cur.execute(f"INSERT INTO Members (user_id, chat_id) VALUES ({id}, {chat_id})")
con.commit()
await update.approve()
return
else:
i += 1
await bot.send_message(chat_id=update.from_user.id, text="You don't have the necessary NFT to join the group 😢")
@dp.message_handler(text = 'Tonkeeper', state='*', chat_type=types.ChatType.PRIVATE)
async def connect_wallet_tonkeeper(message: types.Message):
connector = TonConnect(manifest_url='https://raw.githubusercontent.com/AndreyBur/Access_control_bot/master/pytonconnect-manifest.json')
is_connected = await connector.restore_connection()
wallets_list = connector.get_wallets()
generated_url_tonkeeper = await connector.connect(wallets_list[0])
urlkb = InlineKeyboardMarkup(row_width=1)
urlButton = InlineKeyboardButton(text='Open Tonkeeper', url=generated_url_tonkeeper)
urlkb.add(urlButton)
img = qrcode.make(generated_url_tonkeeper)
path = f'image{random.randint(0, 100000)}.png'
img.save(path)
photo = InputFile(path)
msg = await bot.send_photo(chat_id=message.chat.id, photo=photo, reply_markup=urlkb)
os.remove(path)
flag = True
while flag:
await asyncio.sleep(1)
if connector.connected:
if connector.account.address:
flag = False
address = Address(connector.account.address).to_string(True, True, True)
break
await connector.disconnect()
await msg.delete()
await bot.send_message(message.from_user.id, 'Your wallet has been successfully connect.👌\nSend the application again🔄')
cur.execute(f"UPDATE Users SET address = '{address}' WHERE id_tg = {message.from_user.id}")
con.commit()
@dp.message_handler(text = 'Tonhub', state='*', chat_type=types.ChatType.PRIVATE)
async def connect_wallet_tonhub(message: types.Message):
connector = TonConnect(manifest_url='https://raw.githubusercontent.com/AndreyBur/Access_control_bot/master/pytonconnect-manifest.json')
is_connected = await connector.restore_connection()
wallets_list = connector.get_wallets()
generated_url_tonhub = await connector.connect(wallets_list[2])
urlkb = InlineKeyboardMarkup(row_width=1)
urlButton = InlineKeyboardButton(text='Open Tonhub', url=generated_url_tonhub)
urlkb.add(urlButton)
img = qrcode.make(generated_url_tonhub)
path = f'image{random.randint(0, 100000)}.png'
img.save(path)
photo = InputFile(path)
msg = await bot.send_photo(chat_id=message.chat.id, photo=photo, reply_markup=urlkb)
os.remove(path)
flag = True
while flag:
await asyncio.sleep(1)
if connector.connected:
if connector.account.address:
flag = False
address = Address(connector.account.address).to_string(True, True, True)
break
await connector.disconnect()
await msg.delete()
await bot.send_message(message.from_user.id, 'Your wallet has been successfully connect.👌\nSend the application again 🔄')
cur.execute(f"UPDATE Users SET address = '{address}' WHERE id_tg = {message.from_user.id}")
con.commit()
@dp.message_handler(state='*', content_types=['new_chat_members'])
async def update_chats(message: types.Message):
if not cur.execute(f"SELECT id FROM Chats WHERE id_tg == {message.chat.id}").fetchall():
chat_admins = await bot.get_chat_administrators(message.chat.id)
owner_id = -1
for user in chat_admins:
if user['status'] == 'creator':
owner_id = user['user']['id']
cur.execute(f"INSERT INTO Chats (id_tg, name, owner_id) VALUES ({message.chat.id}, '{message.chat.title}', {owner_id})")
con.commit()
@dp.message_handler(state='*', content_types=['left_chat_member'])
async def update_members(message: types.Message):
chat_id = cur.execute(f"SELECT id FROM Chats WHERE id_tg == {message.chat.id}").fetchall()[0][0]
if message.left_chat_member.id == bot_id:
cur.execute(f"DELETE FROM Members WHERE chat_id == {chat_id}")
con.commit()
cur.execute(f"DELETE FROM Admins WHERE chat_id == {chat_id}")
con.commit()
cur.execute(f"DELETE FROM Passes WHERE chat_id == {chat_id}")
con.commit()
cur.execute(f"DELETE FROM Chats WHERE id_tg == {message.chat.id}")
con.commit()
elif not message.left_chat_member.is_bot:
user_id = cur.execute(f"SELECT id FROM Users WHERE id_tg == {message.left_chat_member.id}").fetchall()[0][0]
cur.execute(f"DELETE FROM Admins WHERE id_users == {user_id} AND chat_id == {chat_id}")
con.commit()
cur.execute(f"DELETE FROM Members WHERE user_id == {user_id} AND chat_id == {chat_id}")
con.commit()
@dp.message_handler(commands=['add_nft'], state='*', chat_type=[types.ChatType.GROUP, types.ChatType.SUPERGROUP])
async def add_nft(message: types.Message, state: FSMContext):
if not cur.execute(f"SELECT id FROM Chats WHERE id_tg == {message.chat.id}").fetchall():
chat_admins = await bot.get_chat_administrators(message.chat.id)
owner_id = -1
for user in chat_admins:
if user['status'] == 'creator':
owner_id = user['user']['id']
cur.execute(f"INSERT INTO Chats (id_tg, name, owner_id) VALUES ({message.chat.id}, '{message.chat.title}', {owner_id})")
con.commit()
owner_id = cur.execute(f"SELECT owner_id FROM Chats WHERE id_tg == {message.chat.id}").fetchall()[0][0]
chat_id = cur.execute(f"SELECT id FROM Chats WHERE id_tg == {message.chat.id}").fetchall()[0][0]
admins = cur.execute(f"SELECT id_users FROM Admins WHERE chat_id == {chat_id}").fetchall()
users = []
for adm in admins:
users.append(cur.execute(f"SELECT id_tg FROM Users WHERE id == {adm[0]}").fetchall()[0][0])
users.append(owner_id)
if message.from_user.id in users:
await message.answer('To add a new NFT for access, send colection address.\n❗️Reply for this message❗️')
await States.AddNFT.set()
else:
await message.answer("You don't have enough permission ❌")
await message.delete()
@dp.message_handler(commands=['remove_nft'], state='*', chat_type=[types.ChatType.GROUP, types.ChatType.SUPERGROUP])
async def remove_nft(message: types.Message, state: FSMContext):
if not cur.execute(f"SELECT id FROM Chats WHERE id_tg == {message.chat.id}").fetchall():
chat_admins = await bot.get_chat_administrators(message.chat.id)
owner_id = -1
for user in chat_admins:
if user['status'] == 'creator':
owner_id = user['user']['id']
cur.execute(f"INSERT INTO Chats (id_tg, name, owner_id) VALUES ({message.chat.id}, '{message.chat.title}', {owner_id})")
con.commit()
owner_id = cur.execute(f"SELECT owner_id FROM Chats WHERE id_tg == {message.chat.id}").fetchall()[0][0]
chat_id = cur.execute(f"SELECT id FROM Chats WHERE id_tg == {message.chat.id}").fetchall()[0][0]
admins = cur.execute(f"SELECT id_users FROM Admins WHERE chat_id == {chat_id}").fetchall()
users = []
for adm in admins:
users.append(cur.execute(f"SELECT id_tg FROM Users WHERE id == {adm[0]}").fetchall()[0][0])
users.append(owner_id)
if message.from_user.id in users:
await message.answer('To remove NFT for access, send colection address.\n❗️Reply for this message❗️')
await States.RemoveNFT.set()
else:
await message.answer("You don't have enough permission ❌")
await message.delete()
@dp.message_handler(commands=['show_nft'], state='*', chat_type=[types.ChatType.GROUP, types.ChatType.SUPERGROUP])
async def show_nft(message: types.Message, state: FSMContext):
if not cur.execute(f"SELECT id FROM Chats WHERE id_tg == {message.chat.id}").fetchall():
chat_admins = await bot.get_chat_administrators(message.chat.id)
owner_id = -1
for user in chat_admins:
if user['status'] == 'creator':
owner_id = user['user']['id']
cur.execute(f"INSERT INTO Chats (id_tg, name, owner_id) VALUES ({message.chat.id}, '{message.chat.title}', {owner_id})")
con.commit()
owner_id = cur.execute(f"SELECT owner_id FROM Chats WHERE id_tg == {message.chat.id}").fetchall()[0][0]
chat_id = cur.execute(f"SELECT id FROM Chats WHERE id_tg == {message.chat.id}").fetchall()[0][0]
admins = cur.execute(f"SELECT id_users FROM Admins WHERE chat_id == {chat_id}").fetchall()
users = []
for adm in admins:
users.append(cur.execute(f"SELECT id_tg FROM Users WHERE id == {adm[0]}").fetchall()[0][0])
users.append(owner_id)
if message.from_user.id in users:
nfts = cur.execute(f"SELECT collection_address FROM Passes WHERE chat_id == {chat_id}").fetchall()
if not nfts:
await message.answer(f'There are no valid passes in this group❗️')
await state.finish()
return
text = ''
for i in range(len(nfts)):
url = f'https://tonapi.io/v2/nfts/collections/{nfts[i][0]}'
response = requests.get(url).json()
name = response['metadata']['name']
link = f'https://tonscan.org/nft/{nfts[i][0]}'
text += f'{i + 1}\) ' + '*' + '[' + name + ']' + '(' + link + ') ' + '*' + '`' + nfts[i][0] + '`' + '\n\n'
await message.answer(f'List of NFTs Providing Users Access:\n\n{text}', parse_mode='MarkdownV2', disable_web_page_preview=True)
await state.finish()
else:
await message.answer("You don't have enough permission ❌")
await message.delete()
@dp.message_handler(commands=['add_admin'], state='*', chat_type=[types.ChatType.GROUP, types.ChatType.SUPERGROUP])
async def add_admin(message: types.Message, state: FSMContext):
if not cur.execute(f"SELECT id FROM Chats WHERE id_tg == {message.chat.id}").fetchall():
chat_admins = await bot.get_chat_administrators(message.chat.id)
owner_id = -1
for user in chat_admins:
if user['status'] == 'creator':
owner_id = user['user']['id']
cur.execute(f"INSERT INTO Chats (id_tg, name, owner_id) VALUES ({message.chat.id}, '{message.chat.title}', {owner_id})")
con.commit()
owner_id = cur.execute(f"SELECT owner_id FROM Chats WHERE id_tg == {message.chat.id}").fetchall()[0][0]
if message.from_user.id == owner_id:
await message.answer('To add a new admin, send his username.\n⚠️ Example: "@username"\n❗️Reply for this message❗️')
await States.AddAdmin.set()
else:
await message.answer("You don't have enough permission ❌")
await message.delete()
@dp.message_handler(commands=['remove_admin'], state='*', chat_type=[types.ChatType.GROUP, types.ChatType.SUPERGROUP])
async def remove_admin(message: types.Message, state: FSMContext):
if not cur.execute(f"SELECT id FROM Chats WHERE id_tg == {message.chat.id}").fetchall():
chat_admins = await bot.get_chat_administrators(message.chat.id)
owner_id = -1
for user in chat_admins:
if user['status'] == 'creator':
owner_id = user['user']['id']
cur.execute(f"INSERT INTO Chats (id_tg, name, owner_id) VALUES ({message.chat.id}, '{message.chat.title}', {owner_id})")
con.commit()
owner_id = cur.execute(f"SELECT owner_id FROM Chats WHERE id_tg == {message.chat.id}").fetchall()[0][0]
if message.from_user.id == owner_id:
await message.answer('To remove admin, send his username.\n⚠️ Example: "@username"\n❗️Reply for this message❗️')
await States.RemoveAdmin.set()
else:
await message.answer("You don't have enough permission ❌")
await message.delete()
@dp.message_handler(commands=['reg'], state='*', chat_type=[types.ChatType.GROUP, types.ChatType.SUPERGROUP])
async def remove_admin(message: types.Message, state: FSMContext):
if not cur.execute(f"SELECT id FROM Chats WHERE id_tg == {message.chat.id}").fetchall():
chat_admins = await bot.get_chat_administrators(message.chat.id)
owner_id = -1
for user in chat_admins:
if user['status'] == 'creator':
owner_id = user['user']['id']
cur.execute(f"INSERT INTO Chats (id_tg, name, owner_id) VALUES ({message.chat.id}, '{message.chat.title}', {owner_id})")
con.commit()
bot_username = await bot.get_me()
bot_username = bot_username.username
if not cur.execute(f"SELECT id_tg FROM Users WHERE id_tg == {message.from_user.id}").fetchall():
cur.execute(f"INSERT INTO Users (id_tg, username) VALUES ({message.from_user.id}, '{message.from_user.username}')")
con.commit()
chat_id = cur.execute(f"SELECT id FROM Chats WHERE id_tg == {message.chat.id}").fetchall()[0][0]
id = cur.execute(f"SELECT id FROM Users WHERE id_tg == {message.from_user.id}").fetchall()[0][0]
cur.execute(f"INSERT INTO Members (user_id, chat_id) VALUES ({id}, {chat_id})")
con.commit()
await message.answer(f'@{message.from_user.username} have successfully registered ✅\n')
if cur.execute(f"SELECT address FROM Users WHERE id_tg == {message.from_user.id}").fetchall()[0][0] is None:
await message.answer(f'You have not connected the wallet if the bot has not written to you, you should start a dialogue with @{bot_username} and re-send /reg')
await bot.send_message(chat_id=message.from_user.id, text="Connect your wallet (Tonkeeper or Tonhub)🚀", reply_markup=kb.Walletkb)
await message.delete()
@dp.message_handler(state = States.AddAdmin, chat_type=[types.ChatType.GROUP, types.ChatType.SUPERGROUP])
async def check_to_add_admin(message: types.Message, state: FSMContext):
if message['reply_to_message'] is None or not (message['reply_to_message']['from']['id'] == bot_id):
return
await state.finish()
if ('@' not in message.text):
await message.answer("incorrectly entered a username ❌")
return
username = re.search(r'@(\w+)', message.text).string[1::]
owner_id = cur.execute(f"SELECT owner_id FROM Chats WHERE id_tg == {message.chat.id}").fetchall()[0][0]
chat_id = cur.execute(f"SELECT id FROM Chats WHERE id_tg == {message.chat.id}").fetchall()[0][0]
if message.from_user.id != owner_id:
return
for member in cur.execute(f"SELECT user_id FROM Members WHERE chat_id == '{chat_id}'").fetchall():
user = await bot.get_chat_member(message.chat.id, cur.execute(f"SELECT id_tg FROM Users WHERE id == {member[0]}").fetchall()[0][0])
if (user.user.username != cur.execute(f"SELECT username FROM Users WHERE id_tg == {user.user.id}").fetchall()[0][0]):
cur.execute(f"UPDATE Users SET username = '{user.user.username}' WHERE id_tg = {user.user.id}")
con.commit()
id = cur.execute(f"SELECT id FROM Users WHERE username == '{username}'").fetchall()
id_tg = cur.execute(f"SELECT id_tg FROM Users WHERE username == '{username}'").fetchall()
if id_tg and id_tg == owner_id:
await message.answer("This user is the owner ❌")
elif id:
if not cur.execute(f"SELECT id_users FROM Admins WHERE id_users == {id[0][0]} AND chat_id == {chat_id}").fetchall():
cur.execute(f"INSERT INTO Admins (id_users, chat_id) VALUES ({id[0][0]}, {chat_id})")
con.commit()
await message.answer("The user is assigned as an admin ✅")
else:
await message.answer("This user is already an admin ⚠️")
else:
await message.answer("This user not registered (he can try write /reg) or incorrectly entered a username ❌")
@dp.message_handler(state = States.RemoveAdmin, chat_type=[types.ChatType.GROUP, types.ChatType.SUPERGROUP])
async def check_to_remove_admin(message: types.Message, state: FSMContext):
if message['reply_to_message'] is None or not (message['reply_to_message']['from']['id'] == bot_id):
return
await state.finish()
if ('@' not in message.text):
await message.answer("incorrectly entered a username ❌")
return
username = re.search(r'@(\w+)', message.text).string[1::]
owner_id = cur.execute(f"SELECT owner_id FROM Chats WHERE id_tg == {message.chat.id}").fetchall()[0][0]
chat_id = cur.execute(f"SELECT id FROM Chats WHERE id_tg == {message.chat.id}").fetchall()[0][0]
id = cur.execute(f"SELECT id FROM Users WHERE username == '{username}'").fetchall()
id_tg = cur.execute(f"SELECT id_tg FROM Users WHERE username == '{username}'").fetchall()[0][0]
if message.from_user.id != owner_id:
return
for member in cur.execute(f"SELECT user_id FROM Members WHERE chat_id == '{chat_id}'").fetchall():
user = await bot.get_chat_member(message.chat.id, cur.execute(f"SELECT id_tg FROM Users WHERE id == {member[0]}").fetchall()[0][0])
if (user.user.username != cur.execute(f"SELECT username FROM Users WHERE id_tg == {user.user.id}").fetchall()[0][0]):
cur.execute(f"UPDATE Users SET username = '{user.user.username}' WHERE id_tg = {user.user.id}")
con.commit()
if id_tg and id_tg == owner_id:
await message.answer("This user is the owner ❌")
elif id:
if cur.execute(f"SELECT id_users FROM Admins WHERE id_users == {id[0][0]} AND chat_id == {chat_id}").fetchall():
cur.execute(f"DELETE from Admins where id_users == {id[0][0]} AND chat_id == {chat_id}")
con.commit()
await message.answer("The user has been removed from the admin position ✅")
else:
await message.answer("This user is not an admin ⚠️")
else:
await message.answer("This user not registr or incorrectly entered a username ❌")
@dp.message_handler(state = States.AddNFT, chat_type=[types.ChatType.GROUP, types.ChatType.SUPERGROUP])
async def check_to_add_nft(message: types.Message, state: FSMContext):
if message['reply_to_message'] is None or not (message['reply_to_message']['from']['id'] == bot_id):
return
owner_id = cur.execute(f"SELECT owner_id FROM Chats WHERE id_tg == {message.chat.id}").fetchall()[0][0]
chat_id = cur.execute(f"SELECT id FROM Chats WHERE id_tg == {message.chat.id}").fetchall()[0][0]
admins = cur.execute(f"SELECT id_users FROM Admins WHERE chat_id == {chat_id}").fetchall()
await state.finish()
users = []
for adm in admins:
users.append(cur.execute(f"SELECT id_tg FROM Users WHERE id == {adm[0]}").fetchall()[0][0])
users.append(owner_id)
if message.from_user.id in users:
collection_address = message.text
if not cur.execute(f"SELECT chat_id FROM Passes WHERE collection_address == '{collection_address}' AND chat_id == {chat_id}").fetchall():
url = f'https://tonapi.io/v2/nfts/collections/{collection_address}'
try:
response = requests.get(url).json()
except:
await message.answer("something went wrong, try again later...")
return
if 'error' in response:
await message.answer('Invalid or non-existent address ❌')
return
chat_id = cur.execute(f"SELECT id FROM Chats WHERE id_tg == {message.chat.id}").fetchall()[0][0]
cur.execute(f"INSERT INTO Passes (chat_id, collection_address) VALUES ({chat_id}, '{collection_address}')")
con.commit()
await message.answer('NFT successfully added ✅')
else:
await message.answer('This address has already been added ⚠️')
@dp.message_handler(state = States.RemoveNFT, chat_type=[types.ChatType.GROUP, types.ChatType.SUPERGROUP])
async def check_to_remove_nft(message: types.Message, state: FSMContext):
if message['reply_to_message'] is None or not (message['reply_to_message']['from']['id'] == bot_id):
return
owner_id = cur.execute(f"SELECT owner_id FROM Chats WHERE id_tg == {message.chat.id}").fetchall()[0][0]
chat_id = cur.execute(f"SELECT id FROM Chats WHERE id_tg == {message.chat.id}").fetchall()[0][0]
admins = cur.execute(f"SELECT id_users FROM Admins WHERE chat_id == {chat_id}").fetchall()
await state.finish()
users = []
for adm in admins:
users.append(cur.execute(f"SELECT id_tg FROM Users WHERE id == {adm[0]}").fetchall()[0][0])
users.append(owner_id)
if message.from_user.id in users:
collection_address = message.text
if cur.execute(f"SELECT chat_id FROM Passes WHERE collection_address == '{collection_address}'").fetchall():
chat_id = cur.execute(f"SELECT id FROM Chats WHERE id_tg == {message.chat.id}").fetchall()[0][0]
cur.execute(f"DELETE FROM Passes WHERE chat_id == {chat_id} AND collection_address == '{collection_address}'")
con.commit()
await message.answer('Address successfully removed ✅')
else:
await message.answer('This address was not added ⚠️')
async def check_users_in_chats():
members = cur.execute(f"SELECT * FROM Members").fetchall()
for member in members:
address = cur.execute(f"SELECT address FROM Users WHERE id == {member[0]}").fetchall()[0][0]
if address is None:
user_id = cur.execute(f"SELECT id_tg FROM Users WHERE id == {member[0]}").fetchall()[0][0]
chat_id = cur.execute(f"SELECT id_tg FROM Chats WHERE id == {member[1]}").fetchall()[0][0]
if await bot.ban_chat_member(chat_id, user_id):
await bot.unban_chat_member(chat_id, user_id)
cur.execute(f"DELETE FROM Admins WHERE id_users == {user_id} AND chat_id == {chat_id}")
con.commit()
cur.execute(f"DELETE FROM Members WHERE user_id == {user_id} AND chat_id == {chat_id}")
con.commit()
continue
chat_id = member[1]
i = 0
nfts = cur.execute(f"SELECT collection_address FROM Passes WHERE chat_id == {chat_id}").fetchall()
while i < len(nfts):
url = f'https://tonapi.io/v2/accounts/{address}/nfts?collection={nfts[i]}&limit=1000&offset=0&indirect_ownership=false'
try:
response = requests.get(url).json()
except:
continue
if response:
return
else:
i += 1
user_id = cur.execute(f"SELECT id_tg FROM Users WHERE id == {member[0]}").fetchall()[0][0]
chat_id = cur.execute(f"SELECT id_tg FROM Chats WHERE id == {member[1]}").fetchall()[0][0]
if await bot.ban_chat_member(chat_id, user_id):
await bot.unban_chat_member(chat_id, user_id)
cur.execute(f"DELETE FROM Admins WHERE id_users == {user_id} AND chat_id == {chat_id}")
con.commit()
cur.execute(f"DELETE FROM Members WHERE user_id == {user_id} AND chat_id == {chat_id}")
con.commit()
@dp.message_handler(state = '*', commands=['start'], chat_type=[types.ChatType.GROUP, types.ChatType.SUPERGROUP, types.ChatType.PRIVATE])
async def start_command(message: types.Message):
await message.answer("The Access Control Bot is a specialized bot that utilizes NTFs (Non Fungible Tokens) or SBTs to manage access to your Telegram groups. This comfortable solution allows you to control who has access to your groups and when, with NFTs/SBTs as unique, non-transferable identifiers for each member.")
@dp.message_handler(commands = ['help'], state = '*', chat_type=[types.ChatType.GROUP, types.ChatType.SUPERGROUP, types.ChatType.PRIVATE])
async def help_instructions(message: types.Message, state: FSMContext):
await message.answer("1\. To get started, add the bot to your group\! It's as easy as inviting a new member\. Look for the bot by its username and add it\.\n2\. Next, make sure you give the bot the necessary powers to perform its tasks\. You can do this by promoting the bot to an administrator role in your group settings\.\n3\. Write the /add\_nft command in the group and reply to the bot's message with the address of the collection\.\n\nYour bot should now be up and running smoothly\.\n\nWe're here to help you at every step\. If you run into any issues or need help understanding anything about the bot's functionalities, don't hesitate to reach out to @Andreyburnosov\.\n\nFor more detailed guidance, you might also want to check out our 'Access control bot' guide on GitHub\. Here's the link to the readme: [Access control bot](https://github.com/AndreyBurnosov/Access_control_bot)", parse_mode='MarkdownV2', disable_web_page_preview=True)
@dp.message_handler(state = '*', chat_type=types.ChatType.PRIVATE)
async def unknown_command(message: types.Message):
await message.answer("Unknown command ⚠️\nMost commands are intended for use in a group.")
if __name__ == '__main__':
scheduler.add_job(check_users_in_chats, "interval", minutes=10)
scheduler.start()
executor.start_polling(dp, skip_updates=True)