The Discord bot integration allows users to download manga directly through Discord commands with live progress updates and automatic file delivery.
Overview
The bot (bot.py) provides:
Command-based manga downloads (!descargar <url>)
Real-time progress updates via Discord embeds
Automatic file uploads (direct for files under 8MB, GoFile for larger files)
Live-updating log messages
Prerequisites
Create a Discord bot
Go to Discord Developer Portal
Click “New Application” and give it a name
Navigate to the “Bot” tab
Click “Add Bot”
Under “Token”, click “Copy” to get your bot token
Enable privileged intents
In the Bot settings, enable:
Message Content Intent (required to read command messages)
Without the Message Content Intent, the bot cannot process commands.
Invite the bot to your server
Go to the “OAuth2” → “URL Generator” tab
Select scopes: bot
Select permissions: Send Messages, Attach Files, Embed Links
Copy the generated URL and open it in your browser
Select your server and authorize
Configuration
Environment setup
Create a .env file in the project root:
DISCORD_TOKEN = your_bot_token_here
You can use .env.example as a template:
Loading the token
The bot loads the token using python-dotenv:
load_dotenv()
TOKEN = os.getenv( 'DISCORD_TOKEN' )
Installation
Install dependencies
pip install -r requirements.txt
Key dependencies:
discord.py - Discord API wrapper
aiohttp - Async HTTP client (for GoFile uploads)
python-dotenv - Environment variable management
Verify Playwright installation
playwright install chromium
playwright install-deps
Test configuration
You should see: Bot connected as YourBotName#1234
Running the bot
Development mode
Production mode
For production, use a process manager like systemd or supervisord:
systemd service
Start service
[Unit]
Description =Manga Downloader Discord Bot
After =network.target
[Service]
Type =simple
User =youruser
WorkingDirectory =/path/to/project
Environment = "PATH=/path/to/venv/bin"
ExecStart =/path/to/venv/bin/python bot.py
Restart =always
RestartSec =10
[Install]
WantedBy =multi-user.target
Use a virtual environment in production to isolate dependencies: python -m venv venv
source venv/bin/activate # Linux/Mac
venv\Scripts\activate # Windows
Commands
!descargar
Download a manga from a supported URL.
Usage:
Example:
!descargar https://tmohentai.com/manga/example
@bot.command ( name = 'descargar' )
async def descargar ( ctx , url : str ):
"""
Downloads a manga from a supported URL.
Usage: !descargar <url>
"""
Features
Live-updating embeds
The bot creates a Discord embed that updates in real-time with download progress:
async def initialize ( self ):
embed = discord.Embed( title = "[+] Starting download..." , color = discord.Color.blue())
self .message = await self .ctx.send( embed = embed)
async def update_discord_message ( self ):
if not self .message: return
log_text = " \n " .join( self .logs)
log_text = f "``` \n { log_text } \n ```"
embed = self .message.embeds[ 0 ]
embed.description = log_text
try :
await self .message.edit( embed = embed)
except discord.errors.HTTPException:
pass
The embed updates every 2 seconds or immediately when important events occur (completion/errors).
Automatic file uploads
The bot intelligently handles file uploads based on size:
if size_mb > 7.9 :
await ctx.send( f "[WARN] ` { filename } ` ( { size_mb :.2f} MB) exceeds limit. Uploading to GoFile..." )
link = await upload_to_gofile(file_path)
if link:
await ctx.send( f "[SUCCESS] ** { filename } **: { link } " )
else :
await ctx.send( f "[ERROR] Failed to upload ` { filename } ` to GoFile." )
else :
await ctx.send( file = discord.File(file_path))
Discord has an 8MB file size limit for non-Nitro users. Files exceeding this limit are automatically uploaded to GoFile.
GoFile integration
For large files, the bot uploads to GoFile and provides a download link:
async def upload_to_gofile ( file_path : str ) -> Optional[ str ]:
"""Uploads a file to GoFile and returns the download link."""
try :
async with aiohttp.ClientSession() as session:
# Get available server
async with session.get( 'https://api.gofile.io/servers' ) as resp:
if resp.status != 200 : return None
data = await resp.json()
if data[ 'status' ] != 'ok' : return None
server = data[ 'data' ][ 'servers' ][ 0 ][ 'name' ]
upload_url = f 'https:// { server } .gofile.io/uploadFile'
# Upload file
filename = os.path.basename(file_path)
with open (file_path, 'rb' ) as f:
form_data = aiohttp.FormData()
form_data.add_field( 'file' , f, filename = filename,
content_type = 'application/pdf' )
async with session.post(upload_url, data = form_data) as upload_resp:
if upload_resp.status == 200 :
res = await upload_resp.json()
if res[ 'status' ] == 'ok' :
return res[ 'data' ][ 'downloadPage' ]
GoFile provides free file hosting with no registration required. Links expire after 30 days of inactivity.
File detection
The bot automatically detects generated PDFs from core logs:
# Detect generated PDF from core logs
# Format: [SUCCESS] PDF Generated: file.pdf
match = re.search( r " \[ SUCCESS \] PDF Generated: ( . * ) " , text)
if match:
filename = match.group( 1 ).strip()
current_dir = os.getcwd()
if os.path.isabs(filename) and os.path.exists(filename):
self .generated_files.append(filename)
print ( f "[BOT FILE DETECTED ABS] { filename } " )
else :
pdf_root = os.path.join(current_dir, core.config. PDF_FOLDER_NAME )
found = False
# Try direct path
direct_path = os.path.join(pdf_root, filename)
if os.path.exists(direct_path):
self .generated_files.append(direct_path)
found = True
# Recursive search as fallback
if not found:
for root, dirs, files in os.walk(pdf_root):
if filename in files:
full_path = os.path.join(root, filename)
self .generated_files.append(full_path)
found = True
Bot configuration
Command prefix
bot = commands.Bot( command_prefix = '!' , intents = intents)
Change the prefix by modifying command_prefix='!' to your preferred character.
Intents
intents = discord.Intents.default()
intents.message_content = True
The message_content intent is required for reading command messages. Ensure it’s enabled in the Discord Developer Portal.
Silent mode
The bot disables automatic file opening:
core.config. OPEN_RESULT_ON_FINISH = False
Example workflow
Here’s what happens when a user runs !descargar https://example.com/manga:
Command received
The bot receives the message and validates the URL.
Embed created
An embed message is posted: “Starting download…”
Download begins
Core processing starts with logging callbacks: [INFO] Fetching manga metadata...
[INFO] Found 30 pages
[INFO] Downloading page 1/30...
[INFO] Downloading page 2/30...
...
Embed updates
The embed updates every 2 seconds with the latest logs.
PDF generated
[SUCCESS] PDF Generated: manga_chapter.pdf
The embed turns green: “Download Finished”
File uploaded
If under 8MB : File is attached directly to a new message
If over 8MB : File is uploaded to GoFile and a link is provided
Troubleshooting
Bot doesn’t respond to commands
Issue : Message Content Intent not enabled
Solution :
Go to Discord Developer Portal
Select your application → Bot tab
Enable “Message Content Intent”
Restart the bot
”DISCORD_TOKEN not found” error
Issue : .env file missing or incorrect
Solution :
echo "DISCORD_TOKEN=your_actual_token" > .env
Downloads work but files aren’t uploaded
Issue : PDF detection failing
Solution : Check that:
The PDF/ directory exists and is writable
Core logs include [SUCCESS] PDF Generated: filename.pdf
File paths are correct (check console output for [BOT FILE DETECTED] messages)
GoFile uploads fail
Issue : Network error or API change
Solution :
Check console for [ERROR GOFILE] messages
Verify internet connectivity
Test GoFile API manually: https://api.gofile.io/servers
Bot disconnects randomly
Issue : Unstable connection or rate limiting
Solution :
Use a process manager with auto-restart (systemd, PM2)
Check Discord API status: https://discordstatus.com
Implement reconnection logic (already built into discord.py)
Security considerations
Keep your bot token secret! Never commit .env files to version control.
Token protection
Permission restrictions
Grant only necessary permissions:
✅ Send Messages
✅ Attach Files
✅ Embed Links
❌ Administrator
❌ Manage Server
Rate limiting
Discord enforces rate limits on bot actions. The bot includes built-in rate limit handling via discord.py.
Memory usage
The bot loads entire PDFs into memory for uploading
For large files (>50MB), consider streaming uploads
Monitor memory usage: htop or ps aux | grep python
Concurrent downloads
The bot processes one download per command invocation. Multiple users can trigger downloads simultaneously, but each is independent.
Implement a queue system if you need to limit concurrent downloads: from asyncio import Semaphore
download_semaphore = Semaphore( 3 ) # Max 3 concurrent downloads
async with download_semaphore:
await core.process_entry( ... )
Advanced customization
Custom embed colors
# Success
embed.color = discord.Color.green() # bot.py:176
# Error
embed.color = discord.Color.red() # bot.py:200
# In progress
embed.color = discord.Color.blue() # bot.py:47
Update interval
self .update_interval = 2.0 # seconds
Reduce for more frequent updates (higher API usage) or increase to reduce rate limit risk.
Log buffer size
if len ( self .logs) > 10 :
self .logs.pop( 0 )
Increase the limit to show more log lines in the embed.
Comparison with other deployment methods
Feature Discord Bot Web App Desktop App Platform Discord Browser Native Windows Multi-user Yes Yes No File delivery Automatic Manual download Auto-open Progress updates Embed WebSocket GUI Large files GoFile upload Direct download Direct save Setup complexity Moderate High Low Remote access Yes Yes No