Large refactor

This commit is contained in:
Profitroll 2023-05-16 20:50:18 +02:00
parent fe5f531c8d
commit 69d63ca1ce
16 changed files with 418 additions and 371 deletions

View File

@ -1,6 +1,6 @@
{ {
"$schema": "https://docs.renovatebot.com/renovate-schema.json", "$schema": "https://docs.renovatebot.com/renovate-schema.json",
"extends": [ "extends": [
"config:base" "config:base"
] ]
} }

229
bwtbot.py
View File

@ -1,214 +1,37 @@
# -*- coding: utf-8 -*- import logging
from os import getpid
from os import getpid, system from convopyro import Conversation
from subprocess import call
from pyrogram import filters
from pyrogram.client import Client
from pyrogram.sync import idle
from pyrogram.types import (
ForceReply,
BotCommand,
BotCommandScopeChat,
Message,
ReplyKeyboardRemove,
)
from pyrogram.enums.chat_action import ChatAction
from convopyro import Conversation, listen_message
from functions import *
from modules.colors import *
from modules.bwt import *
config = jsonLoad("config.json") from modules.app import PyroClient
owner_id = config["owner_id"] logging.basicConfig(
level=logging.INFO,
app = Client( format="%(name)s.%(funcName)s | %(levelname)s | %(message)s",
config["bot_name"], datefmt="[%X]",
api_id=config["api_id"],
api_hash=config["api_hash"],
bot_token=config["bot_token"],
) )
Conversation(app) logger = logging.getLogger(__name__)
try:
import uvloop
uvloop.install()
except ImportError:
pass
@app.on_message( def main():
~filters.scheduled client = PyroClient()
& filters.command(["setcard", "задать карту"], prefixes=["/", ""]) Conversation(client)
)
async def setcard(_: Client, msg: Message):
await msg.reply_text(
string("send_number"),
reply_markup=ForceReply(placeholder=string("enter_number")),
)
answer = await listen_message(_, msg.chat.id, timeout=None)
if answer is None:
return
elif answer.text.strip() in ["/cancel", "cancel", "/відміна", "відміна"]:
await msg.reply_text(string("cancel"), reply_markup=ReplyKeyboardRemove())
return
userSet(answer.from_user.id, "card", answer.text)
appendLog(f"User {str(msg.from_user.id)} set card id to {answer.text}")
await msg.reply_text(
string("card_linked").format(answer.text), reply_markup=ReplyKeyboardRemove()
)
@app.on_message(
~filters.scheduled
& filters.command(["resetcard", "забути картку"], prefixes=["/", ""])
)
async def resetcard(_: Client, msg: Message):
if "card" in jsonLoad("data/database.json")[str(msg.from_user.id)]:
userReset(msg.from_user.id, "card")
await msg.reply_text(string("card_unlinked"))
appendLog(f"User {str(msg.from_user.id)} reseted his card")
else:
await msg.reply_text(string("card_not_linked").format(string("get_number")))
appendLog(f"User {str(msg.from_user.id)} tried to reset non-existent card")
@app.on_message(
~filters.scheduled & filters.command(["balance", "баланс"], prefixes=["/", ""])
)
async def balance(_: Client, msg: Message):
try: try:
if "card" in jsonLoad("data/database.json")[str(msg.from_user.id)]: client.run()
await app.send_chat_action(chat_id=msg.chat.id, action=ChatAction.TYPING) except KeyboardInterrupt:
water_left = await getWaterLeft( logger.warning(f"Forcefully shutting down with PID {getpid()}...")
userGet(msg.from_user.id, "card"), msg.from_user.id, app finally:
) exit()
if water_left == "":
await msg.reply_text(
string("error_new").format(
f'https://bwtaqua.com.ua/card-topup/?id={userGet(msg.from_user.id, "card")}'
)
)
# raise EmptyCardException("Card information is empty")
elif water_left == "Failure":
await msg.reply_text(
string("error_occured").format(string("get_number"))
)
appendLog(
f"User {str(msg.from_user.id)} could not get left water amount"
)
else:
await msg.reply_text(string("card_balance").format(water_left))
appendLog(
f"User {str(msg.from_user.id)} has {water_left} liters remaining"
)
else:
await msg.reply_text(string("card_not_linked").format(string("get_number")))
appendLog(
f"User {str(msg.from_user.id)} tried to get balance without card set"
)
except Exception as exp:
if msg.from_user.id != config["owner_id"]:
await msg.reply_text(string("error_occured").format(string("get_number")))
await app.send_message(
owner_id,
f"Error occured by {str(msg.from_user.id)}:\nException: `{exp}`\nTraceback: `{format_exc()}`",
)
appendLog(f"User {str(msg.from_user.id)} could not get left water amount")
@app.on_message( if __name__ == "__main__":
~filters.scheduled main()
& filters.command(["topup", "refill", "поповнити"], prefixes=["/", ""])
)
async def topup_cmd(_: Client, msg: Message):
try:
if "card" in jsonLoad("data/database.json")[str(msg.from_user.id)]:
await app.send_chat_action(chat_id=msg.chat.id, action=ChatAction.TYPING)
await msg.reply_text(
string("top_up").format(str(userGet(msg.from_user.id, "card")))
)
appendLog(f"User {str(msg.from_user.id)} requested top up")
else:
await msg.reply_text(string("card_not_linked").format(string("get_number")))
appendLog(
f"User {str(msg.from_user.id)} tried to request top up without card set"
)
except Exception as exp:
await msg.reply_text(str(exp))
@app.on_message(
~filters.scheduled
& filters.command(["start", "help", "допомога"], prefixes=["/", ""])
)
async def help(_: Client, msg: Message):
await msg.reply_text(string("welcome").format(string("get_number")))
if msg.from_user.language_code in jsonLoad("strings.json"):
userSet(msg.from_user.id, "locale", msg.from_user.language_code)
else:
userSet(msg.from_user.id, "locale", "en")
pid = getpid()
@app.on_message(
~filters.scheduled & filters.command(["kill", "die", "shutdown"], prefixes="/")
)
async def kill(_: Client, msg: Message):
if msg.from_user.id == owner_id:
await msg.reply_text(f"Shutting down bot with pid **{pid}**")
system(f"kill -9 {pid}")
print(f"{nowtime()} {WHITE}Starting with PID {YELLOW}{pid}{RESET}")
app.start() # type: ignore
app.send_message(owner_id, f"Starting bot with pid **{pid}**") # type: ignore
app.set_bot_commands(
[
BotCommand("help", "Меню допомоги"),
BotCommand("balance", "Баланс картки"),
BotCommand("topup", "Поповнити картку"),
BotCommand("setcard", "Прив'язати картку"),
BotCommand("resetcard", "Відв'язати картку"),
],
language_code="uk",
) # type: ignore
app.set_bot_commands(
[
BotCommand("help", "Меню допомоги"),
BotCommand("balance", "Баланс картки"),
BotCommand("topup", "Поповнити картку"),
BotCommand("setcard", "Прив'язати картку"),
BotCommand("resetcard", "Відв'язати картку"),
],
language_code="ru",
) # type: ignore
app.set_bot_commands(
[
BotCommand("help", "Help menu"),
BotCommand("balance", "Card's balance"),
BotCommand("topup", "Refill card"),
BotCommand("setcard", "Link card"),
BotCommand("resetcard", "Unlink card"),
]
) # type: ignore
app.set_bot_commands(
[
BotCommand("help", "Help menu"),
BotCommand("balance", "Card's balance"),
BotCommand("topup", "Refill card"),
BotCommand("setcard", "Link card"),
BotCommand("resetcard", "Unlink card"),
BotCommand("shutdown", "Turn off the bot"),
],
scope=BotCommandScopeChat(chat_id=owner_id),
) # type: ignore
idle()
app.send_message(owner_id, f"Shutting down bot with pid **{pid}**") # type: ignore
print(f"\n{nowtime()} {WHITE}Shutting down with PID {YELLOW}{pid}{RESET}")
call(f"kill -9 {pid}", shell=True)

View File

@ -1,9 +1,10 @@
{ {
"owner_id": 0, "owner_id": 0,
"log_size": 1024, "bot": {
"api_id": 0, "api_id": 0,
"api_hash": "", "api_hash": "",
"bot_token": "", "bot_token": "",
"bot_name": "", "workers": 1
},
"use_compiled_page_saver": false "use_compiled_page_saver": false
} }

View File

@ -1,125 +0,0 @@
# -*- coding: utf-8 -*-
from os import makedirs, stat
from gzip import open as gzipopen
from shutil import copyfileobj
from time import sleep
from ujson import loads, dumps
from modules.colors import *
from datetime import datetime
users_path = "users/"
logs_folder = "logs/"
def jsonSave(filename, value):
with open(filename, "w", encoding="utf-8") as f:
f.write(dumps(value, indent=4, ensure_ascii=False))
def jsonLoad(filename):
with open(filename, "r", encoding="utf-8") as f:
value = loads(f.read())
return value
config = jsonLoad(f"config.json")
log_size = config["log_size"]
owner_id = config["owner_id"]
def nowtime():
return f'{BBLACK}[{CYAN}{datetime.now().strftime("%H:%M:%S")}{BBLACK}]{RESET}'
def checkSize():
global logs_folder, log_size
i = 0
while i < 2:
try:
log = stat(logs_folder + "latest.log")
if (log.st_size / 1024) > log_size:
with open(logs_folder + "latest.log", "rb") as f_in:
with gzipopen(
f'{logs_folder}{datetime.now().strftime("%d.%m.%Y_%H:%M:%S")}.zip',
"wb",
) as f_out:
copyfileobj(f_in, f_out)
open(logs_folder + "latest.log", "w").close()
i = 2
except FileNotFoundError:
try:
log = open(logs_folder + "latest.log", "a")
open(logs_folder + "latest.log", "a").close()
except:
try:
makedirs(logs_folder, exist_ok=True)
log = open(logs_folder + "latest.log", "a")
open(logs_folder + "latest.log", "a").close()
except:
pass
i += 1
def appendLog(message):
global logs_folder
checkSize()
try:
log = open(logs_folder + "latest.log", "a")
open(logs_folder + "latest.log", "a").close()
except:
try:
makedirs(logs_folder, exist_ok=True)
log = open(logs_folder + "latest.log", "a")
open(logs_folder + "latest.log", "a").close()
except:
sleep(2)
print("Log file could not be created")
return
print(message, flush=True)
log.write(f'[{datetime.now().strftime("%H:%M:%S | %d.%m.%Y")}] {message}\n')
log.close()
def string(key: str, *args: str, userlocale="uk"):
locales = jsonLoad("strings.json")
strings = locales[userlocale]
string = strings
for dict_key in args:
string = string[dict_key]
return string[key]
def userSet(userid, key: str, value):
database = jsonLoad("data/database.json")
if str(userid) not in database:
database[str(userid)] = {}
database[str(userid)][key] = value
jsonSave("data/database.json", database)
def userReset(userid, key: str):
database = jsonLoad("data/database.json")
del database[str(userid)][key]
jsonSave("data/database.json", database)
def userGet(userid, key: str):
try:
return jsonLoad("data/database.json")[str(userid)][key]
except KeyError:
return None
except FileNotFoundError:
return None

59
modules/app.py Normal file
View File

@ -0,0 +1,59 @@
import logging
from os import getpid
from time import time
import pyrogram
from libbot import config_get
from pyrogram.client import Client
from pyrogram.errors import BadRequest
from pyrogram.raw.all import layer
from ujson import loads
logger = logging.getLogger(__name__)
class PyroClient(Client):
def __init__(self):
with open("config.json", "r", encoding="utf-8") as f:
config = loads(f.read())
super().__init__(
name="bwtbot",
api_id=config["bot"]["api_id"],
api_hash=config["bot"]["api_hash"],
bot_token=config["bot"]["bot_token"],
workers=config["bot"]["workers"],
plugins=dict(root="plugins", exclude=config["disabled_plugins"]),
sleep_threshold=120,
)
async def start(self):
await super().start()
self.start_time = time()
logger.info(
"Bot is running with Pyrogram v%s (Layer %s) and has started as @%s on PID %s.",
pyrogram.__version__,
layer,
self.me.username,
getpid(),
)
try:
await self.send_message(
chat_id=await config_get("chat_id", "reports"),
text=f"Bot started PID `{getpid()}`",
)
except BadRequest:
logger.warning("Unable to send message to report chat.")
async def stop(self):
try:
await self.send_message(
chat_id=await config_get("chat_id", "reports"),
text=f"Bot stopped with PID `{getpid()}`",
)
except BadRequest:
logger.warning("Unable to send message to report chat.")
await super().stop()
logger.warning(f"Bot stopped with PID {getpid()}.")

View File

@ -1,13 +1,17 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
import logging
from os import makedirs, path from os import makedirs, path
from subprocess import check_output from subprocess import check_output
from traceback import format_exc from traceback import format_exc
from uuid import uuid4 from uuid import uuid4
from functions import *
from bs4 import BeautifulSoup
config = jsonLoad("config.json") from bs4 import BeautifulSoup
from libbot import config_get
from modules.utils import *
logger = logging.getLogger(__name__)
class EmptyCardException(Exception): class EmptyCardException(Exception):
@ -21,9 +25,9 @@ async def getWaterLeft(cardid, filename, app=None):
# if path.exists(f"data/pages/{str(filename)}.html") is False: # if path.exists(f"data/pages/{str(filename)}.html") is False:
# run(["touch", f"data/pages/{str(filename)}.html"]) # run(["touch", f"data/pages/{str(filename)}.html"])
appendLog(f"Trying to get liters for url '{url}'") logger.info(f"Trying to get liters for url '{url}'")
if config["use_compiled_page_saver"] is True: if await config_get("use_compiled_page_saver") is True:
proc = check_output( proc = check_output(
[ [
"PageSaver/pageSaver", "PageSaver/pageSaver",
@ -58,12 +62,14 @@ async def getWaterLeft(cardid, filename, app=None):
.replace(" л", "") .replace(" л", "")
) )
appendLog( logger.info(
f"Parsed {output} liters of water remaining (user: {str(filename)}, cardid: {cardid})" f"Parsed {output} liters of water remaining (user: {str(filename)}, cardid: {cardid})"
) )
except Exception as exp: except Exception as exp:
appendLog(f"Exception occured: {exp} (user: {str(filename)}, cardid: {cardid})") logger.exception(
f"Exception occured: {exp} (user: {str(filename)}, cardid: {cardid})", exp
)
try: try:
tmp_name = str(uuid4()) tmp_name = str(uuid4())
@ -72,16 +78,16 @@ async def getWaterLeft(cardid, filename, app=None):
f.write(html_file) f.write(html_file)
except NameError: except NameError:
tmp_name = "N/A" tmp_name = "N/A"
appendLog(f"'html_file' is not defined so I won't gather any tmp data") logger.warning(f"'html_file' is not defined so I won't gather any tmp data")
if app != None: if app != None:
await app.send_message( await app.send_message(
config["owner_id"], await config_get("owner_id"),
f"**Exception occured:**\n • User: `{str(filename)}`\n • Card: [{cardid}]({url})\n • Exception: `{exp}`\n • TMP UUID: `{tmp_name}`\n • Traceback: `{format_exc()}`", f"**Exception occured:**\n • User: `{str(filename)}`\n • Card: [{cardid}]({url})\n • Exception: `{exp}`\n • TMP UUID: `{tmp_name}`\n • Traceback: `{format_exc()}`",
disable_web_page_preview=True, disable_web_page_preview=True,
) )
else: else:
appendLog(f"Exception occured and could not send to user: {exp}") logger.warning(f"Exception occurred and could not send to user: {exp}")
output = "Failure" output = "Failure"

View File

@ -1,22 +0,0 @@
RESET = "\u001b[0m"
BLACK = "\u001b[30m"
RED = "\u001b[31m"
GREEN = "\u001b[32m"
YELLOW = "\u001b[33m"
BLUE = "\u001b[34m"
MAGENTA = "\u001b[35m"
CYAN = "\u001b[36m"
WHITE = "\u001b[37m"
BBLACK = "\u001b[30;1m"
BRED = "\u001b[31;1m"
BGREEN = "\u001b[32;1m"
BYELLOW = "\u001b[33;1m"
BBLUE = "\u001b[34;1m"
BMAGENTA = "\u001b[35;1m"
BCYAN = "\u001b[36;1m"
BWHITE = "\u001b[37;1m"
ULINE = "\u001b[4m"
REVERSE = "\u001b[7m"

35
modules/utils.py Normal file
View File

@ -0,0 +1,35 @@
# -*- coding: utf-8 -*-
from libbot import json_read, sync
async def string(key: str, *args: str, userlocale="uk"):
locales = await json_read("strings.json")
strings = locales[userlocale]
string = strings
for dict_key in args:
string = string[dict_key]
return string[key]
def userSet(userid, key: str, value):
database = sync.json_read("data/database.json")
if str(userid) not in database:
database[str(userid)] = {}
database[str(userid)][key] = value
sync.json_write(database, "data/database.json")
def userReset(userid, key: str):
database = sync.json_read("data/database.json")
del database[str(userid)][key]
sync.json_write(database, "data/database.json")
def userGet(userid, key: str):
try:
return sync.json_read("data/database.json")[str(userid)][key]
except KeyError:
return None
except FileNotFoundError:
return None

63
plugins/balance.py Normal file
View File

@ -0,0 +1,63 @@
# -*- coding: utf-8 -*-
import logging
from traceback import format_exc
from libbot import config_get, json_read
from pyrogram import filters
from pyrogram.client import Client
from pyrogram.enums.chat_action import ChatAction
from pyrogram.types import Message
from modules.utils import string, userGet
from modules.bwt import getWaterLeft
logger = logging.getLogger(__name__)
@Client.on_message(
~filters.scheduled & filters.command(["balance", "баланс"], prefixes=["/", ""]) # type: ignore
)
async def command_balance(app: Client, msg: Message):
try:
if "card" in (await json_read("data/database.json"))[str(msg.from_user.id)]:
await app.send_chat_action(chat_id=msg.chat.id, action=ChatAction.TYPING)
water_left = await getWaterLeft(
userGet(msg.from_user.id, "card"), msg.from_user.id, app
)
if water_left == "":
await msg.reply_text(
(await string("error_new")).format(
f'https://bwtaqua.com.ua/card-topup/?id={userGet(msg.from_user.id, "card")}'
)
)
# raise EmptyCardException("Card information is empty")
elif water_left == "Failure":
await msg.reply_text(
(await string("error_occured")).format(await string("get_number"))
)
logger.warning(
f"User {str(msg.from_user.id)} could not get left water amount"
)
else:
await msg.reply_text((await string("card_balance")).format(water_left))
logger.info(
f"User {str(msg.from_user.id)} has {water_left} liters remaining"
)
else:
await msg.reply_text(
(await string("card_not_linked")).format(await string("get_number"))
)
logger.info(
f"User {str(msg.from_user.id)} tried to get balance without card set"
)
except Exception as exp:
if msg.from_user.id != await config_get("owner_id"):
await msg.reply_text(
(await string("error_occured")).format(await string("get_number"))
)
await app.send_message(
await config_get("owner_id"),
f"Error occured by {str(msg.from_user.id)}:\nException: `{exp}`\nTraceback: `{format_exc()}`",
)
logger.warning(f"User {str(msg.from_user.id)} could not get left water amount")

24
plugins/help.py Normal file
View File

@ -0,0 +1,24 @@
# -*- coding: utf-8 -*-
import logging
from libbot import json_read
from pyrogram import filters
from pyrogram.client import Client
from pyrogram.types import Message
from modules.utils import string, userSet
logger = logging.getLogger(__name__)
@Client.on_message(
~filters.scheduled
& filters.command(["start", "help", "допомога"], prefixes=["/", ""]) # type: ignore
)
async def command_help(app: Client, msg: Message):
await msg.reply_text((await string("welcome")).format(await string("get_number")))
if msg.from_user.language_code in await json_read("strings.json"):
userSet(msg.from_user.id, "locale", msg.from_user.language_code)
else:
userSet(msg.from_user.id, "locale", "en")

View File

@ -0,0 +1,60 @@
# -*- coding: utf-8 -*-
import logging
from libbot import config_get
from pyrogram import filters
from pyrogram.client import Client
from pyrogram.types import BotCommand, BotCommandScopeChat, Message
logger = logging.getLogger(__name__)
@Client.on_message(
~filters.scheduled & filters.command(["register_commands"], prefixes="/") # type: ignore
)
async def command_register_commands(app: Client, msg: Message):
if msg.from_user.id == await config_get("owner_id"):
app.set_bot_commands(
[
BotCommand("help", "Меню допомоги"),
BotCommand("balance", "Баланс картки"),
BotCommand("topup", "Поповнити картку"),
BotCommand("setcard", "Прив'язати картку"),
BotCommand("resetcard", "Відв'язати картку"),
],
language_code="uk",
) # type: ignore
app.set_bot_commands(
[
BotCommand("help", "Меню допомоги"),
BotCommand("balance", "Баланс картки"),
BotCommand("topup", "Поповнити картку"),
BotCommand("setcard", "Прив'язати картку"),
BotCommand("resetcard", "Відв'язати картку"),
],
language_code="ru",
) # type: ignore
app.set_bot_commands(
[
BotCommand("help", "Help menu"),
BotCommand("balance", "Card's balance"),
BotCommand("topup", "Refill card"),
BotCommand("setcard", "Link card"),
BotCommand("resetcard", "Unlink card"),
]
) # type: ignore
app.set_bot_commands(
[
BotCommand("help", "Help menu"),
BotCommand("balance", "Card's balance"),
BotCommand("topup", "Refill card"),
BotCommand("setcard", "Link card"),
BotCommand("resetcard", "Unlink card"),
BotCommand("shutdown", "Turn off the bot"),
],
scope=BotCommandScopeChat(chat_id=await config_get("owner_id")),
) # type: ignore

28
plugins/resetcard.py Normal file
View File

@ -0,0 +1,28 @@
# -*- coding: utf-8 -*-
import logging
from libbot import json_read
from pyrogram import filters
from pyrogram.client import Client
from pyrogram.types import Message
from modules.utils import string, userReset
logger = logging.getLogger(__name__)
@Client.on_message(
~filters.scheduled
& filters.command(["resetcard", "забути картку"], prefixes=["/", ""]) # type: ignore
)
async def command_resetcard(app: Client, msg: Message):
if "card" in (await json_read("data/database.json"))[str(msg.from_user.id)]:
userReset(msg.from_user.id, "card")
await msg.reply_text(await string("card_unlinked"))
logger.info(f"User {str(msg.from_user.id)} reseted his card")
else:
await msg.reply_text(
(await string("card_not_linked")).format(await string("get_number"))
)
logger.info(f"User {str(msg.from_user.id)} tried to reset non-existent card")

35
plugins/setcard.py Normal file
View File

@ -0,0 +1,35 @@
# -*- coding: utf-8 -*-
import logging
from convopyro import listen_message
from pyrogram import filters
from pyrogram.client import Client
from pyrogram.types import ForceReply, Message, ReplyKeyboardRemove
from modules.utils import string, userSet
logger = logging.getLogger(__name__)
@Client.on_message(
~filters.scheduled
& filters.command(["setcard", "задать карту"], prefixes=["/", ""]) # type: ignore
)
async def command_setcard(app: Client, msg: Message):
await msg.reply_text(
await string("send_number"),
reply_markup=ForceReply(placeholder=await string("enter_number")),
)
answer = await listen_message(app, msg.chat.id, timeout=None)
if answer is None:
return
elif answer.text.strip() in ["/cancel", "cancel", "/відміна", "відміна"]:
await msg.reply_text(await string("cancel"), reply_markup=ReplyKeyboardRemove())
return
userSet(answer.from_user.id, "card", answer.text)
logger.info(f"User {str(msg.from_user.id)} set card id to {answer.text}")
await msg.reply_text(
(await string("card_linked")).format(answer.text),
reply_markup=ReplyKeyboardRemove(),
)

21
plugins/shutdown.py Normal file
View File

@ -0,0 +1,21 @@
# -*- coding: utf-8 -*-
import logging
from os import getpid
from libbot import config_get
from pyrogram import filters
from pyrogram.client import Client
from pyrogram.types import Message
logger = logging.getLogger(__name__)
@Client.on_message(
~filters.scheduled & filters.command(["kill", "die", "shutdown"], prefixes="/") # type: ignore
)
async def kill(app: Client, msg: Message):
if msg.from_user.id == await config_get("owner_id"):
await msg.reply_text(f"Shutting down bot with pid **{getpid()}**")
logger.info(f"Shutting down as requested by {msg.from_user.id}")
exit()

36
plugins/topup.py Normal file
View File

@ -0,0 +1,36 @@
# -*- coding: utf-8 -*-
import logging
from libbot import json_read
from pyrogram import filters
from pyrogram.client import Client
from pyrogram.enums.chat_action import ChatAction
from pyrogram.types import Message
from modules.utils import string, userGet
logger = logging.getLogger(__name__)
@Client.on_message(
~filters.scheduled
& filters.command(["topup", "refill", "поповнити"], prefixes=["/", ""]) # type: ignore
)
async def command_topup(app: Client, msg: Message):
try:
if "card" in (await json_read("data/database.json"))[str(msg.from_user.id)]:
await app.send_chat_action(chat_id=msg.chat.id, action=ChatAction.TYPING)
await msg.reply_text(
(await string("top_up")).format(str(userGet(msg.from_user.id, "card")))
)
logger.info(f"User {str(msg.from_user.id)} requested top up")
else:
await msg.reply_text(
(await string("card_not_linked")).format(await string("get_number"))
)
logger.info(
f"User {str(msg.from_user.id)} tried to request top up without card set"
)
except Exception as exp:
await msg.reply_text(str(exp))

View File

@ -3,4 +3,7 @@ convopyro==0.5
pathlib~=1.0.1 pathlib~=1.0.1
pyrogram==2.0.106 pyrogram==2.0.106
tgcrypto==1.2.5 tgcrypto==1.2.5
ujson==5.7.0 ujson==5.7.0
uvloop==0.17.0
--extra-index-url https://git.end-play.xyz/api/packages/profitroll/pypi/simple
libbot[speed,pyrogram]==0.4