* add tron support

* update README

* update README

* add notification
This commit is contained in:
Benny 2023-12-08 18:56:57 +01:00 committed by GitHub
parent 37f1d4c2ba
commit a09cce4856
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
12 changed files with 230 additions and 112 deletions

25
FAQ.md
View file

@ -1,25 +0,0 @@
# Project status
This project is currently inactive and is no longer being maintained.
No new features will be added, and no bugs will be fixed.
While the existing code and bot will continue to work, there are no guarantees regarding their reliability or
functionality.
# Can you support downloading from XXX?
Please reach out to [yt-dlp](https://github.com/yt-dlp/yt-dlp)
# My video is not downloading, slow, or not downloading at all
Just wait. It is a free service, and it is not guaranteed to work.
# Why is the bot not responding?
If `/start` command is not responding, please contact me [@BennyThink](https://t.me/BennyThink)
# Can't redeem VIP
If you are not able to redeem VIP, please contact me [@BennyThink](https://t.me/BennyThink)

View file

@ -2,14 +2,10 @@
[![docker image](https://github.com/tgbot-collection/ytdlbot/actions/workflows/builder.yaml/badge.svg)](https://github.com/tgbot-collection/ytdlbot/actions/workflows/builder.yaml) [![docker image](https://github.com/tgbot-collection/ytdlbot/actions/workflows/builder.yaml/badge.svg)](https://github.com/tgbot-collection/ytdlbot/actions/workflows/builder.yaml)
YouTube Download Bot🚀 YouTube Download Bot🚀🎬⬇️
This Telegram bot allows you to download videos from YouTube and other supported platforms, including Instagram! This Telegram bot allows you to download videos from YouTube and other supported websites, including Instagram!
-----
**READ [FAQ](FAQ.md) FIRST IF YOU ENCOUNTER ANY ISSUES.**
-----
<details> <summary>Deploy to heroku</summary> <details> <summary>Deploy to heroku</summary>
<a href="https://heroku.com/deploy"><img src="https://www.herokucdn.com/deploy/button.svg" alt="Deploy to Heroku"></a> <a href="https://heroku.com/deploy"><img src="https://www.herokucdn.com/deploy/button.svg" alt="Deploy to Heroku"></a>
@ -26,14 +22,14 @@ longer be available.**
[https://t.me/benny_ytdlbot](https://t.me/benny_ytdlbot) [https://t.me/benny_ytdlbot](https://t.me/benny_ytdlbot)
Send link directly to the bot. Any Send link directly to the bot. Any
Websites [supported by youtube-dl](https://ytdl-org.github.io/youtube-dl/supportedsites.html) will work to. Websites [supported by yt-dlp](https://github.com/yt-dlp/yt-dlp/blob/master/supportedsites.md) will work t0o.
# Limitations of my bot # Limitations of my bot
Due to limitations on servers and bandwidth, there are some restrictions on this free service. Due to limitations on servers and bandwidth, there are some restrictions on this free service.
* Each user is limited to 20 free downloads per 24-hour period * Each user is limited to 20 free downloads per 24-hour period
* there is a maximum of three subscriptions allowed for YouTube channels. * Maximum of three subscriptions allowed for YouTube channels.
If you need more downloads, you can purchase additional tokens. Additionally, you have the option of deploying your If you need more downloads, you can purchase additional tokens. Additionally, you have the option of deploying your
own bot. See below instructions. own bot. See below instructions.
@ -44,14 +40,14 @@ own bot. See below instructions.
2. ads free 2. ads free
3. support progress bar 3. support progress bar
4. audio conversion 4. audio conversion
5. playlist support 5. playlist download
6. payment support 6. payment support: afdian, buy me a coffee, Telegram Payment and Tron(TRX)
7. support different video resolutions 7. different video resolutions
8. support sending as file or streaming as video 8. sending as file or streaming as video
9. supports celery worker distribution - faster than before. 9. celery worker distribution - faster than before.
10. subscriptions to YouTube Channels 10. subscriptions to YouTube Channels
11. cache mechanism - download once for the same video. 11. cache mechanism - download once for the same video.
12. support instagram posts 12. instagram posts
# Screenshots # Screenshots
@ -71,19 +67,17 @@ own bot. See below instructions.
This bot can be deployed on any platform that supports Python. This bot can be deployed on any platform that supports Python.
Need help with deployment or exclusive features? I offer paid service - contact me at @BennyThink
## Run natively on your machine ## Run natively on your machine
To deploy this bot, follow these steps: To deploy this bot, follow these steps:
1. Install bot dependencies 1. Install bot dependencies
* Install Python 3.6 or a later version, FFmpeg. * Install Python 3.6 or a later version, FFmpeg.
* Aria2 and add it to the PATH. * (optional)Aria2 and add it to the PATH.
2. Clone the code from the repository and cd into it. 2. Clone the code from the repository and cd into it.
* ```Bash * ```Bash
git clone "https://github.com/tgbot-collection/ytdlbot.git git clone https://github.com/tgbot-collection/ytdlbot
``` ```
* ```Bash * ```Bash
cd ytdlbot/ cd ytdlbot/
@ -93,9 +87,9 @@ To deploy this bot, follow these steps:
python -m venv venv python -m venv venv
``` ```
* ```Bash * ```Bash
source venv/bin/activate #Linux source venv/bin/activate # Linux
#or #or
.\venv\Scripts\activate #Windows .\venv\Scripts\activate # Windows
``` ```
* ```Python * ```Python
pip install --upgrade pip pip install --upgrade pip
@ -106,13 +100,14 @@ To deploy this bot, follow these steps:
4. Set the environment variables `TOKEN`, `APP_ID`, `APP_HASH`, and any others that you may need. 4. Set the environment variables `TOKEN`, `APP_ID`, `APP_HASH`, and any others that you may need.
* Change values in ytdlbot/config.py or * Change values in ytdlbot/config.py or
* Use export APP_ID=111 APP_HASH=111 TOKEN=123 * Use export APP_ID=111 APP_HASH=111 TOKEN=123
5. Finally run the bot with 5. Finally, run the bot with
* ```Python * ```Python
python ytdl_bot.py python ytdl_bot.py
``` ```
## Docker ## Docker
This bot has a simple one-line code and some functions, such as VIP and ping, are disabled. One line command to run the bot
```shell ```shell
docker run -e APP_ID=111 -e APP_HASH=111 -e TOKEN=370FXI bennythink/ytdlbot docker run -e APP_ID=111 -e APP_HASH=111 -e TOKEN=370FXI bennythink/ytdlbot
@ -121,7 +116,7 @@ docker run -e APP_ID=111 -e APP_HASH=111 -e TOKEN=370FXI bennythink/ytdlbot
# Complete deployment guide for docker-compose # Complete deployment guide for docker-compose
* contains every functionality * contains every functionality
* compatible with amd64, arm64 and armv7l * compatible with amd64 and arm64
## 1. get docker-compose.yml ## 1. get docker-compose.yml
@ -174,6 +169,8 @@ You can configure all the following environment variables:
* GOOGLE_API_KEY: YouTube API key, required for YouTube video subscription. * GOOGLE_API_KEY: YouTube API key, required for YouTube video subscription.
* RCLONE_PATH: rclone path to upload files to cloud storage * RCLONE_PATH: rclone path to upload files to cloud storage
* TMPFILE_PATH: tmpfile path(file download path) * TMPFILE_PATH: tmpfile path(file download path)
* TRONGRID_KEY: TronGrid key, better use your own key to avoid rate limit
* TRON_MNEMONIC: Tron mnemonic, the default one is on nile testnet.
## 3.2 Set up init data ## 3.2 Set up init data
@ -181,7 +178,7 @@ If you only need basic functionality, you can skip this step.
### 3.2.1 Create MySQL db ### 3.2.1 Create MySQL db
Required for VIP, settings, YouTube subscription. Required for VIP(Download token), settings, YouTube subscription.
```shell ```shell
docker-compose up -d docker-compose up -d
@ -204,15 +201,11 @@ Type "help", "copyright", "credits" or "license" for more information.
>>> import dbm;dbm.open("flower","n");exit() >>> import dbm;dbm.open("flower","n");exit()
``` ```
### 3.2.3 Setup instagram cookies
You don't need to do this anymore! This bot support instagram posts out of the box, including photos, videos and reels.
## 3.3 Tidy docker-compose.yml ## 3.3 Tidy docker-compose.yml
In `flower` service section, you may want to change your basic authentication username password and publish port. In `flower` service section, you may want to change your basic authentication username password and publish port.
You can also limit CPU and RAM usage by adding a `deploy' key: You can also limit CPU and RAM usage by adding a `deploy` key, use `--compatibility` when deploying.
```docker ```docker
deploy: deploy:
@ -222,8 +215,6 @@ You can also limit CPU and RAM usage by adding a `deploy' key:
memory: 1500M memory: 1500M
``` ```
Be sure to use `--compatibility` when deploying.
## 4. run ## 4. run
### 4.1. standalone mode ### 4.1. standalone mode
@ -256,7 +247,7 @@ On the other machine:
docker-compose -f worker.yml up -d docker-compose -f worker.yml up -d
``` ```
**⚠️ Please bear in mind that you should not publish Redis directly on the internet. **⚠️ You should not publish Redis directly on the internet.
Instead, you can use WireGuard to wrap it up for added security.** Instead, you can use WireGuard to wrap it up for added security.**
## kubernetes ## kubernetes
@ -306,20 +297,32 @@ https://www.instagram.com/p/CZtUDyyv1u1/
# Donation # Donation
Found this bot useful? You can donate to support the development of this bot.
## Donation Platforms
* [Buy me a coffee](https://www.buymeacoffee.com/bennythink) * [Buy me a coffee](https://www.buymeacoffee.com/bennythink)
* [Afdian](https://afdian.net/@BennyThink) * [Afdian](https://afdian.net/@BennyThink)
* [GitHub Sponsor](https://github.com/sponsors/BennyThink) * [GitHub Sponsor](https://github.com/sponsors/BennyThink)
## Stripe ## Stripe
You can choose to donate via Stripe by clicking the button below. You can choose to donate via Stripe.
Select the currency and payment method that suits you. | USD(Card, Apple Pay and Google Pay) | CNY(Card, Apple Pay, Google Pay and Alipay) |
|--------------------------------------------------|--------------------------------------------------|
| [USD](https://buy.stripe.com/cN203sdZB98RevC3cd) | [CNY](https://buy.stripe.com/dR67vU4p13Ox73a6oq) |
| ![](assets/USD.png) | ![](assets/CNY.png) |
| USD(Card, Apple Pay and Google Pay) | SEK(Card, Apple Pay and Google Pay) | CNY(Card, Apple Pay, Google Pay and Alipay) | ## Cryptocurrency
|--------------------------------------------------|--------------------------------------------------|--------------------------------------------------|
| [USD](https://buy.stripe.com/cN203sdZB98RevC3cd) | [SEK](https://buy.stripe.com/bIYbMa9JletbevCaEE) | [CNY](https://buy.stripe.com/dR67vU4p13Ox73a6oq) | TRX or USDT(TRC20)
| ![](assets/USD.png) | ![](assets/SEK.png) | ![](assets/CNY.png) |
![](assets/tron.png)
```
TF9peZjC2FYjU4xNMPg3uP4caYLJxtXeJS
```
# License # License

Binary file not shown.

Before

Width:  |  Height:  |  Size: 57 KiB

BIN
assets/tron.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

View file

@ -5,7 +5,7 @@ APScheduler==3.10.4
beautifultable==1.1.0 beautifultable==1.1.0
ffmpeg-python==0.2.0 ffmpeg-python==0.2.0
PyMySQL==1.1.0 PyMySQL==1.1.0
celery==5.3.5 celery==5.3.6
filetype==1.2.0 filetype==1.2.0
flower==2.0.1 flower==2.0.1
psutil==5.9.6 psutil==5.9.6
@ -22,3 +22,7 @@ ffpb==0.4.1
youtube-search-python==1.6.6 youtube-search-python==1.6.6
token-bucket==0.3.0 token-bucket==0.3.0
coloredlogs==15.0.1 coloredlogs==15.0.1
tronpy==0.4.0
mnemonic==0.20
qrcode==7.4.2
blinker==1.7.0

28
scripts/transfer.py Normal file
View file

@ -0,0 +1,28 @@
#!/usr/bin/env python3
# coding: utf-8
# ytdlbot - transfer.py
# 2023-12-07 18:21
from tronpy import Tron
from tronpy.hdwallet import seed_from_mnemonic, key_from_seed
from tronpy.keys import PrivateKey
mnemonic = "web horse smile ramp olive slush blue property world physical donkey pumpkin"
client = Tron(network="nile")
from_ = client.generate_address_from_mnemonic(mnemonic, account_path="m/44'/195'/0'/0/0")["base58check_address"]
print("my addr: ", from_)
to = input("to: ")
amount = int(input("amount: 1_000_000\n"))
def mnemonic_to_private_key():
seed = seed_from_mnemonic(mnemonic, passphrase="")
private_key = key_from_seed(seed, account_path="m/44'/195'/0'/0/0")
return PrivateKey(private_key)
t = client.trx.transfer(from_, to, amount).build().inspect().sign(mnemonic_to_private_key()).broadcast()
print(t.wait())

View file

@ -9,6 +9,8 @@ __author__ = "Benny <benny.think@gmail.com>"
import os import os
from blinker import signal
# general settings # general settings
WORKERS: int = int(os.getenv("WORKERS", 100)) WORKERS: int = int(os.getenv("WORKERS", 100))
PYRO_WORKERS: int = int(os.getenv("PYRO_WORKERS", min(64, (os.cpu_count() + 4) * 10))) PYRO_WORKERS: int = int(os.getenv("PYRO_WORKERS", min(64, (os.cpu_count() + 4) * 10)))
@ -24,11 +26,6 @@ TG_MAX_SIZE = 2000 * 1024 * 1024
EXPIRE = 24 * 3600 EXPIRE = 24 * 3600
ENABLE_VIP = os.getenv("VIP", False) ENABLE_VIP = os.getenv("VIP", False)
AFD_LINK = os.getenv("AFD_LINK", "https://afdian.net/@BennyThink")
COFFEE_LINK = os.getenv("COFFEE_LINK", "https://www.buymeacoffee.com/bennythink")
COFFEE_TOKEN = os.getenv("COFFEE_TOKEN")
AFD_TOKEN = os.getenv("AFD_TOKEN")
AFD_USER_ID = os.getenv("AFD_USER_ID")
OWNER = os.getenv("OWNER", "BennyThink") OWNER = os.getenv("OWNER", "BennyThink")
# limitation settings # limitation settings
@ -52,16 +49,11 @@ ARCHIVE_ID = os.getenv("ARCHIVE_ID")
IPv6 = os.getenv("IPv6", False) IPv6 = os.getenv("IPv6", False)
ENABLE_FFMPEG = os.getenv("ENABLE_FFMPEG", False) ENABLE_FFMPEG = os.getenv("ENABLE_FFMPEG", False)
# Stripe setting
PROVIDER_TOKEN = os.getenv("PROVIDER_TOKEN") or "1234"
PLAYLIST_SUPPORT = os.getenv("PLAYLIST_SUPPORT", False) PLAYLIST_SUPPORT = os.getenv("PLAYLIST_SUPPORT", False)
M3U8_SUPPORT = os.getenv("M3U8_SUPPORT", False) M3U8_SUPPORT = os.getenv("M3U8_SUPPORT", False)
ENABLE_ARIA2 = os.getenv("ENABLE_ARIA2", False) ENABLE_ARIA2 = os.getenv("ENABLE_ARIA2", False)
FREE_DOWNLOAD = os.getenv("FREE_DOWNLOAD", 20)
TOKEN_PRICE = os.getenv("BUY_UNIT", 20) # one USD=20 credits
RATE_LIMIT = os.getenv("RATE_LIMIT", 120) RATE_LIMIT = os.getenv("RATE_LIMIT", 120)
SS_YOUTUBE = os.getenv("SS_YOUTUBE", "https://ytdlbot.dmesg.app?token=123456") SS_YOUTUBE = os.getenv("SS_YOUTUBE", "https://ytdlbot.dmesg.app?token=123456")
@ -72,3 +64,17 @@ RCLONE_PATH = os.getenv("RCLONE")
# Please ensure that the directory exists and you have necessary permissions to write to it. # Please ensure that the directory exists and you have necessary permissions to write to it.
# If you don't know what this is just leave it as it is. # If you don't know what this is just leave it as it is.
TMPFILE_PATH = os.getenv("TMPFILE") TMPFILE_PATH = os.getenv("TMPFILE")
# payment settings
AFD_LINK = os.getenv("AFD_LINK", "https://afdian.net/@BennyThink")
COFFEE_LINK = os.getenv("COFFEE_LINK", "https://www.buymeacoffee.com/bennythink")
COFFEE_TOKEN = os.getenv("COFFEE_TOKEN")
AFD_TOKEN = os.getenv("AFD_TOKEN")
AFD_USER_ID = os.getenv("AFD_USER_ID")
PROVIDER_TOKEN = os.getenv("PROVIDER_TOKEN") or "1234"
FREE_DOWNLOAD = os.getenv("FREE_DOWNLOAD", 20)
TOKEN_PRICE = os.getenv("BUY_UNIT", 20) # one USD=20 credits
TRONGRID_KEY = os.getenv("TRONGRID_KEY", "").split(",")
# the default mnemonic is for nile testnet
TRON_MNEMONIC = os.getenv("TRON_MNEMONIC", "cram floor today legend service drill pitch leaf car govern harvest soda")
TRX_SIGNAL = signal("trx_received")

View file

@ -26,59 +26,52 @@ class BotText:
help = f""" help = f"""
1. This bot should work at all times. If it doesn't, please wait for a few minutes and try sending the link again. 1. This bot should work at all times. If it doesn't, please wait for a few minutes and try sending the link again.
2. At the time of writing, this bot consumes more than 100GB of network traffic per day. 2. Source code is here: https://github.com/tgbot-collection/ytdlbot
To prevent abuse, each user is limited to 5 downloads per 24 hours.
3. You have the option to buy more tokens. Type /buy for more information.
4. The source code for this bot will always remain open and can be found here: https://github.com/tgbot-collection/ytdlbot
5. Need help with deployment or exclusive features? I offer paid service - contact me at @BennyThink
""" """
about = "YouTube Downloader by @BennyThink.\n\nOpen source on GitHub: https://github.com/tgbot-collection/ytdlbot" about = "YouTube Downloader by @BennyThink.\n\nOpen source on GitHub: https://github.com/tgbot-collection/ytdlbot"
buy = f""" buy = f"""
**Terms:** **Terms:**
1. You can use this service free of charge for up to {FREE_DOWNLOAD} downloads within a 24-hour period, regardless of whether the download is successful or not. 1. You can use this bot to download video for {FREE_DOWNLOAD} times within a 24-hour period.
2. You can purchase additional download tokens, which will be valid indefinitely. 2. You can purchase additional download tokens, which will be valid permanently.
3. I will not gather any personal information, so I won't know how many or which videos you have downloaded. 3. Refunds are possible, contact me if you need that @BennyThink
4. Refunds are possible, but you will be responsible for the processing fee charged by the payment provider (Stripe, Buy Me a Coffee, etc.). 4. Paid user can change default download mode to Local mode in settings, which is faster.
5. I will record your unique ID after a successful payment, which is usually your payment ID or email address.
6. Paid user can change default download mode to Local mode in settings, which is faster. If your used up all your tokens, you will be reset to default mode.
**Download token price:** **Download token price:**
1. Everyone: {FREE_DOWNLOAD} tokens per 24 hours, free of charge. valid permanently
2. 1 USD == {TOKEN_PRICE} tokens, valid indefinitely. 1. 1 USD == {TOKEN_PRICE} tokens
3. 7 CNY == {TOKEN_PRICE} tokens, valid indefinitely. 2. 7 CNY == {TOKEN_PRICE} tokens
3. 10 TRX == {TOKEN_PRICE} tokens
**Payment option:** **Payment options:**
Pay the amount you want. For example you can send 20 TRX for {TOKEN_PRICE * 2} tokens.
1. AFDIAN(AliPay, WeChat Pay and PayPal): {AFD_LINK} 1. AFDIAN(AliPay, WeChat Pay and PayPal): {AFD_LINK}
2. Buy me a coffee: {COFFEE_LINK} 2. Buy me a coffee: {COFFEE_LINK}
3. Telegram Payment(Stripe), see following invoice. 3. Telegram Payment(Stripe), see following invoice.
4. TRON(TRX), see following QR code.
**After payment:** **After payment:**
1. Afdian: Provide your order number with the /redeem command (e.g., `/redeem 123456`). 1. Afdian: Provide your order number with the /redeem command (e.g., `/redeem 123456`).
2. Buy Me a Coffee: Provide your email with the /redeem command (e.g., `/redeem some@one.com`). **Use different email each time.** 2. Buy Me a Coffee: Provide your email with the /redeem command (e.g., `/redeem some@one.com`). **Use different email each time.**
3. Telegram Payment: Your payment will be automatically activated. 3. Telegram Payment & Tron(TRX): Your payment will be automatically activated within 60s. Check /start to see your balance.
Want to buy more token at once? Let's say 100? Here you go! `/buy 123` Want to buy more token with Telegram payment? Let's say 100? Here you go! `/buy 123`
""" """
private = "This bot is for private use" private = "This bot is for private use"
membership_require = f"You need to join this group or channel to use this bot\n\nhttps://t.me/{REQUIRED_MEMBERSHIP}" membership_require = f"You need to join this group or channel to use this bot\n\nhttps://t.me/{REQUIRED_MEMBERSHIP}"
settings = """ settings = """
Please choose the desired format and video quality for your video. Note that these settings only **apply to YouTube videos**. Please choose the preferred format and video quality for your video. These settings only **apply to YouTube videos**.
High quality is recommended. Medium quality is 720P, while low quality is 480P. High quality is recommended. Medium quality aims to 720P, while low quality is 480P.
Please keep in mind that if you choose to send the video as a document, it will not be possible to stream it. If you choose to send the video as a document, it will not be possible to stream it.
Your current settings: Your current settings:
Video quality: **{0}** Video quality: **{0}**
@ -90,7 +83,7 @@ Sending format: **{1}**
def get_receive_link_text() -> str: def get_receive_link_text() -> str:
reserved = get_func_queue("reserved") reserved = get_func_queue("reserved")
if ENABLE_CELERY and reserved: if ENABLE_CELERY and reserved:
text = f"Too many tasks. Your tasks was added to the reserved queue {reserved}." text = f"Your tasks was added to the reserved queue {reserved}. Processing...\n\n"
else: else:
text = "Your task was added to active queue.\nProcessing...\n\n" text = "Your task was added to active queue.\nProcessing...\n\n"

View file

@ -26,7 +26,14 @@ import requests
import yt_dlp as ytdl import yt_dlp as ytdl
from tqdm import tqdm from tqdm import tqdm
from config import AUDIO_FORMAT, ENABLE_ARIA2, ENABLE_FFMPEG, TG_MAX_SIZE, IPv6, SS_YOUTUBE from config import (
AUDIO_FORMAT,
ENABLE_ARIA2,
ENABLE_FFMPEG,
SS_YOUTUBE,
TG_MAX_SIZE,
IPv6,
)
from limit import Payment from limit import Payment
from utils import adjust_formats, apply_log_formatter, current_time, sizeof_fmt from utils import adjust_formats, apply_log_formatter, current_time, sizeof_fmt

View file

@ -12,6 +12,11 @@ import logging
import time import time
import requests import requests
from tronpy import Tron
from tronpy.exceptions import TransactionError, ValidationError
from tronpy.hdwallet import key_from_seed, seed_from_mnemonic
from tronpy.keys import PrivateKey
from tronpy.providers import HTTPProvider
from config import ( from config import (
AFD_TOKEN, AFD_TOKEN,
@ -21,6 +26,9 @@ from config import (
FREE_DOWNLOAD, FREE_DOWNLOAD,
OWNER, OWNER,
TOKEN_PRICE, TOKEN_PRICE,
TRON_MNEMONIC,
TRONGRID_KEY,
TRX_SIGNAL,
) )
from database import MySQL, Redis from database import MySQL, Redis
from utils import apply_log_formatter, current_time from utils import apply_log_formatter, current_time
@ -95,6 +103,80 @@ class Afdian:
return amount / 7, trade_no return amount / 7, trade_no
class TronTrx:
def __init__(self):
if TRON_MNEMONIC == "cram floor today legend service drill pitch leaf car govern harvest soda":
logging.warning("Using nile testnet")
provider = HTTPProvider(endpoint_uri="https://nile.trongrid.io")
network = "nile"
else:
provider = HTTPProvider(api_key=TRONGRID_KEY)
network = "mainnet"
self.client = Tron(provider, network=network)
def central_transfer(self, from_, index, amount: int):
logging.info("Generated key with index %s", index)
seed = seed_from_mnemonic(TRON_MNEMONIC, passphrase="")
key = PrivateKey(key_from_seed(seed, account_path=f"m/44'/195'/1'/0/{index}"))
central = self.central_wallet()
logging.info("Transfer %s TRX from %s to %s", amount, from_, central)
try:
self.client.trx.transfer(from_, central, amount).build().sign(key).broadcast()
except (TransactionError, ValidationError):
logging.error("Failed to transfer %s TRX to %s. Lower and try again.", amount, from_)
if amount > 1_100_000:
# 1.1 trx transfer fee
self.client.trx.transfer(from_, central, amount - 1_100_000).build().sign(key).broadcast()
def central_wallet(self):
wallet = self.client.generate_address_from_mnemonic(TRON_MNEMONIC, account_path="m/44'/195'/0'/0/0")
return wallet["base58check_address"]
def get_payment_address(self, user_id):
# payment_id is like tron,0,TN8Mn9KKv3cSrKyrt6Xx5L18nmezbpiW31,index where 0 means unpaid
db = MySQL()
con = db.con
cur = db.cur
cur.execute("select user_id from payment where payment_id like 'tron,%'")
data = cur.fetchall()
index = len(data)
path = f"m/44'/195'/1'/0/{index}"
logging.info("Generating address for user %s with path %s", user_id, path)
addr = self.client.generate_address_from_mnemonic(TRON_MNEMONIC, account_path=path)["base58check_address"]
# add row in db, unpaid
cur.execute("insert into payment values (%s,%s,%s,%s,%s)", (user_id, 0, f"tron,0,{addr},{index}", 0, 0))
con.commit()
return addr
def check_payment(self):
db = MySQL()
con = db.con
cur = db.cur
cur.execute("select user_id, payment_id from payment where payment_id like 'tron,0,T%'")
data = cur.fetchall()
logging.info("Checking %s unpaid payment", len(data))
for row in data:
user_id = row[0]
addr, index = row[1].split(",")[2:]
try:
balance = self.client.get_account_balance(addr)
except:
balance = 0
if balance:
logging.info("User %s has %s TRX", user_id, balance)
# paid, calc token count
token_count = int(balance / 10 * TOKEN_PRICE)
cur.execute(
"update payment set token=%s,payment_id=%s where user_id=%s and payment_id like %s",
(token_count, f"tron,1,{addr},{index}", user_id, f"tron,%{addr}%"),
)
con.commit()
self.central_transfer(addr, index, int(balance * 1_000_000))
logging.debug("Dispatch signal now....")
TRX_SIGNAL.send("cron", user_id=user_id, text=f"{balance} TRX received, {token_count} tokens added.")
class Payment(Redis, MySQL): class Payment(Redis, MySQL):
def check_old_user(self, user_id: int) -> tuple: def check_old_user(self, user_id: int) -> tuple:
self.cur.execute("SELECT * FROM payment WHERE user_id=%s AND old_user=1", (user_id,)) self.cur.execute("SELECT * FROM payment WHERE user_id=%s AND old_user=1", (user_id,))
@ -168,3 +250,9 @@ class Payment(Redis, MySQL):
return "Payment not found. Please check your payment ID or email address" return "Payment not found. Please check your payment ID or email address"
self.add_pay_user([user_id, amount, pay_id, 0, amount * TOKEN_PRICE]) self.add_pay_user([user_id, amount, pay_id, 0, amount * TOKEN_PRICE])
return "Thanks! Your payment has been verified. /start to get your token details" return "Thanks! Your payment has been verified. /start to get your token details"
if __name__ == "__main__":
a = TronTrx()
# a.central_wallet()
a.check_payment()

View file

@ -43,10 +43,10 @@ from config import (
ENABLE_QUEUE, ENABLE_QUEUE,
ENABLE_VIP, ENABLE_VIP,
OWNER, OWNER,
RCLONE_PATH,
RATE_LIMIT, RATE_LIMIT,
WORKERS, RCLONE_PATH,
TMPFILE_PATH, TMPFILE_PATH,
WORKERS,
) )
from constant import BotText from constant import BotText
from database import Redis from database import Redis

View file

@ -20,6 +20,7 @@ from io import BytesIO
from pathlib import Path from pathlib import Path
import pyrogram.errors import pyrogram.errors
import qrcode
import requests import requests
import yt_dlp import yt_dlp
from apscheduler.schedulers.background import BackgroundScheduler from apscheduler.schedulers.background import BackgroundScheduler
@ -37,16 +38,17 @@ from config import (
ENABLE_CELERY, ENABLE_CELERY,
ENABLE_FFMPEG, ENABLE_FFMPEG,
ENABLE_VIP, ENABLE_VIP,
M3U8_SUPPORT,
OWNER, OWNER,
PLAYLIST_SUPPORT, PLAYLIST_SUPPORT,
M3U8_SUPPORT,
PROVIDER_TOKEN, PROVIDER_TOKEN,
REQUIRED_MEMBERSHIP, REQUIRED_MEMBERSHIP,
TOKEN_PRICE, TOKEN_PRICE,
TRX_SIGNAL,
) )
from constant import BotText from constant import BotText
from database import InfluxDB, MySQL, Redis from database import InfluxDB, MySQL, Redis
from limit import Payment from limit import Payment, TronTrx
from tasks import app as celery_app from tasks import app as celery_app
from tasks import ( from tasks import (
audio_entrance, audio_entrance,
@ -60,8 +62,7 @@ from utils import auto_restart, clean_tempfile, customize_logger, get_revision
customize_logger(["pyrogram.client", "pyrogram.session.session", "pyrogram.connection.connection"]) customize_logger(["pyrogram.client", "pyrogram.session.session", "pyrogram.connection.connection"])
logging.getLogger("apscheduler.executors.default").propagate = False logging.getLogger("apscheduler.executors.default").propagate = False
session = "ytdl-main" app = create_app(":memory:")
app = create_app(session)
logging.info("Authorized users are %s", AUTHORIZED_USER) logging.info("Authorized users are %s", AUTHORIZED_USER)
redis = Redis() redis = Redis()
@ -286,7 +287,6 @@ def settings_handler(client: Client, message: types.Message):
def buy_handler(client: Client, message: types.Message): def buy_handler(client: Client, message: types.Message):
# process as chat.id, not from_user.id # process as chat.id, not from_user.id
chat_id = message.chat.id chat_id = message.chat.id
text = message.text.strip()
client.send_chat_action(chat_id, "typing") client.send_chat_action(chat_id, "typing")
client.send_message(chat_id, BotText.buy, disable_web_page_preview=True) client.send_message(chat_id, BotText.buy, disable_web_page_preview=True)
# generate telegram invoice here # generate telegram invoice here
@ -309,7 +309,12 @@ def buy_handler(client: Client, message: types.Message):
message="Buy more download token", message="Buy more download token",
) )
) )
client.send_message(chat_id, "In /settings, change your download mode to Local will make the download faster!")
addr = TronTrx().get_payment_address(chat_id)
with BytesIO() as bio:
qr = qrcode.make(addr)
qr.save(bio)
client.send_photo(chat_id, bio, caption=f"Send TRX to `{addr}`")
@app.on_message(filters.command(["redeem"])) @app.on_message(filters.command(["redeem"]))
@ -517,13 +522,22 @@ def temp_fix_The_msg_id_is_too_low():
os.remove(s_file_path) os.remove(s_file_path)
def trx_notify(_, **kwargs):
user_id = kwargs.get("user_id")
text = kwargs.get("text")
logging.info("Sending trx notification to %s", user_id)
app.send_message(user_id, text)
if __name__ == "__main__": if __name__ == "__main__":
MySQL() MySQL()
TRX_SIGNAL.connect(trx_notify)
scheduler = BackgroundScheduler(timezone="Asia/Shanghai", job_defaults={"max_instances": 5}) scheduler = BackgroundScheduler(timezone="Asia/Shanghai", job_defaults={"max_instances": 5})
scheduler.add_job(redis.reset_today, "cron", hour=0, minute=0) scheduler.add_job(redis.reset_today, "cron", hour=0, minute=0)
scheduler.add_job(auto_restart, "interval", seconds=600) scheduler.add_job(auto_restart, "interval", seconds=600)
scheduler.add_job(clean_tempfile, "interval", seconds=60) scheduler.add_job(clean_tempfile, "interval", seconds=120)
scheduler.add_job(InfluxDB().collect_data, "interval", seconds=60) scheduler.add_job(InfluxDB().collect_data, "interval", seconds=120)
scheduler.add_job(TronTrx().check_payment, "interval", seconds=60)
# default quota allocation of 10,000 units per day # default quota allocation of 10,000 units per day
scheduler.add_job(periodic_sub_check, "interval", seconds=3600) scheduler.add_job(periodic_sub_check, "interval", seconds=3600)
scheduler.start() scheduler.start()