feat: init

This commit is contained in:
tiennm99 committed 2025-03-28 20:35:09 +07:00
1 parent e8e66272de
commit 871a31f564
8 files changed
+374 -2

No files matched your search

+3
View File
@@ -0,0 +1,3 @@
PHONE=+1234567890
API_ID=123456789
API_HASH=0123456789abcdef0123456789abcdef
+3
View File
@@ -0,0 +1,3 @@
.idea
.env
*.session
+108 -2
View File
@@ -1,2 +1,108 @@
# bulk-telegram-sticker
Create stickers automatically
# Bulk Telegram Sticker Pack Creator
This tool helps you create and upload sticker packs to Telegram using a two-step process:
1. Prepare and process your images
2. Create and upload the sticker pack
## Setup
1. Install the required dependencies:
```bash
pip install -r requirements.txt
```
2. Get your Telegram API credentials:
- Go to https://my.telegram.org/auth
- Log in with your phone number
- Go to 'API development tools'
- Create a new application
- Copy the `API_ID` and `API_HASH`
3. Create a `.env` file in the project root with your credentials:
```
API_ID=your_api_id
API_HASH=your_api_hash
PHONE=your_phone_number
```
## Usage
### Step 1: Prepare Images
1. Create an `input` directory in the project root
2. Place your sticker images in the `input` directory (supported formats: PNG, JPG, JPEG)
3. Run the preparation script:
```bash
python prepare.py
```
This will:
- Convert all images to WebP format (512x512 pixels)
- Create an `output` directory with the processed images
- Generate a `sticker_config.json` file in the `output` directory
4. Edit the `output/sticker_config.json` file to:
- Change the sticker pack title and short name
- Modify emojis for each sticker
- Add or remove stickers from the pack
Example configuration:
```json
{
"sticker_pack": {
"title": "My Awesome Stickers",
"short_name": "my_awesome_stickers",
"stickers": [
{
"original": "sticker1.png",
"webp": "sticker1.webp",
"emoji": "😀"
},
{
"original": "sticker2.png",
"webp": "sticker2.webp",
"emoji": "😎"
}
]
}
}
```
### Step 2: Create Sticker Pack
1. Run the main script to create and upload the sticker pack:
```bash
python main.py
```
2. The first time you run the script, you'll need to authenticate with your phone number
3. The script will create the sticker pack and upload all stickers according to the configuration
## Important Notes
- The `short_name` must be unique across all Telegram sticker packs
- Input images will be automatically resized to 512x512 pixels while maintaining aspect ratio
- Images are converted to WebP format with transparency support
- Make sure your input images are clear and of good quality
- The first time you run the script, you'll need to authenticate with your phone number
## Troubleshooting
Due to the nature of interacting with Telegram's Sticker bot, some issues may occur:
1. **Manual Intervention Required**: Sometimes the script may fail to complete the process automatically. In such cases:
- The script will indicate that manual completion is needed
- You can continue the process manually by messaging @Stickers
- Follow the bot's prompts to complete the sticker pack creation
2. **Common Issues**:
- Bot response delays: The script includes delays between actions, but sometimes the bot may need more time
- Network issues: Ensure you have a stable internet connection
- Rate limiting: If you create multiple packs, Telegram may temporarily limit your actions
3. **If the Script Fails**:
- Check the error message for specific details
- You can start a new conversation with @Stickers and complete the process manually
- The bot will guide you through the remaining steps
Remember that while the script automates most of the process, you may need to complete some steps manually if unexpected issues arise.
+2
View File
@@ -0,0 +1,2 @@
*
!.gitignore
+156
View File
@@ -0,0 +1,156 @@
import os
import asyncio
import json
from telethon import TelegramClient, events
from telethon.tl.types import InputPeerUser
from telethon.tl.functions.messages import SendMessageRequest
from pathlib import Path
from dotenv import load_dotenv
# Load environment variables from .env file
load_dotenv()
# Telegram API credentials
API_ID = os.getenv('API_ID')
API_HASH = os.getenv('API_HASH')
PHONE = os.getenv('PHONE')
# Sticker bot username
STICKER_BOT_USERNAME = "@Stickers"
print(f"API_ID: {API_ID}")
print(f"API_HASH: {API_HASH}")
print(f"PHONE: {PHONE}")
# Initialize the client
client = TelegramClient(PHONE, API_ID, API_HASH)
def load_config(config_path):
"""Load and validate configuration file"""
try:
with open(config_path, 'r', encoding='utf-8') as f:
config = json.load(f)
# Validate required fields
if not all(key in config for key in ['title', 'short_name', 'stickers']):
raise ValueError("Missing required fields in configuration")
return config
except Exception as e:
print(f"Error loading configuration: {str(e)}")
return None
async def create_sticker_pack(config):
"""
Create a new sticker pack by interacting with the Sticker bot
Args:
config (dict): Configuration dictionary containing sticker pack details
"""
try:
# Start the client
await client.start(phone=PHONE)
# Get the sticker bot entity
sticker_bot = await client.get_entity(STICKER_BOT_USERNAME)
# Start new sticker pack creation
await client(SendMessageRequest(
peer=sticker_bot,
message="/newpack"
))
# Wait for bot to ask for pack name
await asyncio.sleep(1)
# Send pack name
await client(SendMessageRequest(
peer=sticker_bot,
message=config['title']
))
# Wait for bot to ask for short name
await asyncio.sleep(1)
# Send short name
await client(SendMessageRequest(
peer=sticker_bot,
message=config['short_name']
))
# Wait for bot to ask for username
await asyncio.sleep(1)
# Send username (using short name)
await client(SendMessageRequest(
peer=sticker_bot,
message=config['short_name']
))
output_dir = "output"
# Upload stickers one by one
for sticker in config['stickers']:
sticker_path = os.path.join(output_dir, sticker['webp'])
if not os.path.exists(sticker_path):
print(f"Warning: Sticker file not found: {sticker_path}")
continue
# Send sticker file
await client.send_file(
sticker_bot,
sticker_path,
caption=sticker['emoji']
)
# Wait for bot to process the sticker
await asyncio.sleep(2)
# Skip any additional prompts
await asyncio.sleep(1)
await client(SendMessageRequest(
peer=sticker_bot,
message="/skip"
))
await asyncio.sleep(1)
# Send /publish command to finalize the pack
await client(SendMessageRequest(
peer=sticker_bot,
message="/publish"
))
# Wait for bot to ask for confirmation
await asyncio.sleep(1)
# Confirm publishing
await client(SendMessageRequest(
peer=sticker_bot,
message="Yes"
))
print(f"Sticker pack created successfully: {config['short_name']}")
return config['short_name']
except Exception as e:
print(f"Error creating sticker pack: {str(e)}")
print("Note: If the script fails, you may need to complete the process manually with the Sticker bot.")
return None
finally:
await client.disconnect()
async def main():
# Load configuration
config_path = os.path.join("output", "sticker_config.json")
if not os.path.exists(config_path):
print("Configuration file not found! Please run prepare.py first.")
return
config = load_config(config_path)
if not config:
return
await create_sticker_pack(config)
if __name__ == "__main__":
asyncio.run(main())
+2
View File
@@ -0,0 +1,2 @@
*
!.gitignore
+97
View File
@@ -0,0 +1,97 @@
import os
import json
from PIL import Image
import glob
from pathlib import Path
def convert_to_webp(input_path, output_path, size=(512, 512)):
"""Convert image to WebP format with specified size"""
try:
with Image.open(input_path) as img:
# Convert to RGBA if necessary
if img.mode != 'RGBA':
img = img.convert('RGBA')
# Resize image maintaining aspect ratio
img.thumbnail(size, Image.Resampling.LANCZOS)
# Create a new image with padding if necessary
new_img = Image.new('RGBA', size, (0, 0, 0, 0))
offset = ((size[0] - img.size[0]) // 2, (size[1] - img.size[1]) // 2)
new_img.paste(img, offset)
# Save as WebP
new_img.save(output_path, 'WEBP', quality=90)
return True
except Exception as e:
print(f"Error converting {input_path}: {str(e)}")
return False
def process_images(input_dir, output_dir):
"""Process all images in input directory and convert to WebP"""
# Create output directory if it doesn't exist
Path(output_dir).mkdir(parents=True, exist_ok=True)
# Supported input formats
input_formats = ['*.png', '*.jpg', '*.jpeg']
processed_files = []
# Process each image
for format in input_formats:
for input_path in glob.glob(os.path.join(input_dir, format)):
filename = os.path.basename(input_path)
name_without_ext = os.path.splitext(filename)[0]
output_path = os.path.join(output_dir, f"{name_without_ext}.webp")
if convert_to_webp(input_path, output_path):
processed_files.append({
"original": filename,
"webp": f"{name_without_ext}.webp",
"emoji": "😀" # Default emoji
})
return processed_files
def generate_config(processed_files, output_dir):
"""Generate configuration file"""
config = {
"title": "My Awesome Stickers",
"short_name": "my_awesome_stickers",
"stickers": processed_files
}
# Save config file
config_path = os.path.join(output_dir, "sticker_config.json")
with open(config_path, 'w', encoding='utf-8') as f:
json.dump(config, f, indent=4, ensure_ascii=False)
return config_path
def main():
# Setup directories
input_dir = "input"
output_dir = "output"
# Create input directory if it doesn't exist
Path(input_dir).mkdir(parents=True, exist_ok=True)
print("Processing images...")
processed_files = process_images(input_dir, output_dir)
if not processed_files:
print("No images found in input directory!")
return
print(f"Processed {len(processed_files)} images")
# Generate configuration file
config_path = generate_config(processed_files, output_dir)
print(f"\nConfiguration file generated: {config_path}")
print("\nYou can now edit the configuration file to:")
print("1. Change the sticker pack title and short name")
print("2. Modify emojis for each sticker")
print("3. Add or remove stickers from the pack")
print("\nAfter editing, run main.py to create the sticker pack")
if __name__ == "__main__":
main()
+3
View File
@@ -0,0 +1,3 @@
telethon>=1.28.5
python-dotenv>=0.19.0
Pillow>=10.0.0