mirror of
https://github.com/tgbot-collection/ytdlbot.git
synced 2024-09-20 06:55:55 +08:00
Tron (#318)
* add tron support * update README * update README * add notification
This commit is contained in:
parent
37f1d4c2ba
commit
a09cce4856
25
FAQ.md
25
FAQ.md
|
@ -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)
|
|
81
README.md
81
README.md
|
@ -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
|
||||||
|
@ -105,14 +99,15 @@ 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
|
||||||
|
|
||||||
|
|
BIN
assets/SEK.png
BIN
assets/SEK.png
Binary file not shown.
Before Width: | Height: | Size: 57 KiB |
BIN
assets/tron.png
Normal file
BIN
assets/tron.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 15 KiB |
|
@ -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
28
scripts/transfer.py
Normal 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())
|
|
@ -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")
|
||||||
|
|
|
@ -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:**
|
||||||
1. AFDIAN(AliPay, WeChat Pay and PayPal): {AFD_LINK}
|
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}
|
||||||
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"
|
||||||
|
|
||||||
|
|
|
@ -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
|
||||||
|
|
||||||
|
|
|
@ -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()
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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()
|
||||||
|
|
Loading…
Reference in a new issue