├── README.md ├── config.py ├── main.py └── requirements.txt /README.md: -------------------------------------------------------------------------------- 1 | # 🤖 Telegram File Forwarder Bot 2 | 3 | [![Python](https://img.shields.io/badge/Python-3.6+-blue.svg)](https://python.org) 4 | [![Telegram Bot](https://img.shields.io/badge/Telegram%20Bot-API-green.svg)](https://core.telegram.org/bots) 5 | [![License](https://img.shields.io/badge/License-MIT-yellow.svg)](LICENSE) 6 | [![File Types](https://img.shields.io/badge/Files-All%20Types-red.svg)](#supported-file-types) 7 | 8 | A sophisticated Telegram bot that allows users to upload files, add custom names as hashtags, and automatically forwards them to your designated group with professional formatting. 9 | 10 | ## ✨ Features 11 | 12 | - 📁 **Universal File Support**: Handles all file types including PDF, ZIP, RAR, PSD, TIF, photos, videos, and audio 13 | - 🏷️ **Smart Hashtags**: Automatically adds # to user names if forgotten 14 | - 💬 **Group Integration**: Seamlessly forwards files to your Telegram group 15 | - 🔄 **Interactive Flow**: Guided conversation for file naming 16 | - 🚫 **Cancel Operation**: Users can abort at any time with /cancel 17 | - 🛡️ **Error Handling**: Comprehensive error messages and validation 18 | - 📊 **Detailed Logging**: Complete activity logging for monitoring 19 | - 🎨 **Rich Captions**: Includes file type icons and names in captions 20 | 21 | ## 🚀 Setup Instructions 22 | 23 | ### 1. Create Telegram Bot 24 | 1. Open Telegram and search for **🤖 @BotFather** 25 | 2. Create a new bot using `/newbot` command 26 | 3. Follow the prompts to set bot name and username 27 | 4. Copy the **🔑 BOT TOKEN** provided by BotFather 28 | 29 | ### 2. Add Bot to Your Group 30 | 1. Create a new group or use an existing group 31 | 2. Add your bot as a **👥 member** of the group 32 | 3. Grant the bot permission to **📤 Send Messages** 33 | 34 | ### 3. Get Group ID 35 | 1. Add `@JsonDumpBot` to your group 36 | 2. Post any message in the group 37 | 3. The bot will reply with the group ID (format: `-100xxxxxxxxxx`) 38 | 4. Copy this numeric ID (it will be a negative number) 39 | 40 | ### 4. Configure the Bot 41 | 1. Clone this repository: 42 | ```bash 43 | git clone https://github.com/xPOURY4/telegram-file-forwarder.git 44 | cd telegram-file-forwarder 45 | ``` 46 | 47 | 2. Install dependencies: 48 | ```bash 49 | pip install -r requirements.txt 50 | ``` 51 | 52 | 3. Edit `config.py`: 53 | ```python 54 | BOT_TOKEN = "YOUR_BOT_TOKEN_HERE" # 🔑 From BotFather 55 | GROUP_ID = -1001234567890 # 👥 Your group ID 56 | ``` 57 | 58 | ### 5. Run the Bot 59 | ```bash 60 | python main.py 61 | ``` 62 | 63 | ## 📖 How to Use 64 | 65 | 1. **📤 Send File**: Upload any file to the bot 66 | 2. **✏️ Name File**: When prompted, enter a name for the file 67 | 3. **🏷️ Smart Hashtag**: Bot automatically adds # if you forget 68 | 4. **📤 Forward**: File appears in your group with rich caption 69 | 5. **🚫 Cancel**: Use /cancel to abort at any time 70 | 71 | ## 🎮 Supported Commands 72 | 73 | | Command | Description | Example | 74 | |---------|-------------|---------| 75 | | `/start` | Welcome message and instructions | `/start` | 76 | | `/help` | Usage instructions | `/help` | 77 | | `/cancel` | Abort current operation | `/cancel` | 78 | 79 | ## 📁 Supported File Types 80 | 81 | | Category | Formats | Icon | 82 | |----------|---------|------| 83 | | **Documents** | PDF, DOC, DOCX, TXT, RTF, ODT, etc. | 📄 | 84 | | **Archives** | ZIP, RAR, 7Z, TAR, GZ, etc. | 📦 | 85 | | **Design** | PSD, AI, SVG, EPS, etc. | 🎨 | 86 | | **Images** | JPG, PNG, GIF, BMP, TIF, WEBP, etc. | 🖼️ | 87 | | **Videos** | MP4, MOV, AVI, MKV, FLV, etc. | 🎬 | 88 | | **Audio** | MP3, WAV, FLAC, AAC, OGG, etc. | 🎵 | 89 | 90 | ## 🛠️ Troubleshooting 91 | 92 | | Issue | Solution | Emoji | 93 | |-------|----------|-------| 94 | | **"Failed to send file"** | Verify bot is group member with send permissions | 🔍 | 95 | | **Bot not responding** | Check BOT_TOKEN and internet connection | 🌐 | 96 | | **Invalid Group ID** | Use @JsonDumpBot to get correct ID | 🆔 | 97 | | **Name not accepted** | Enter text after sending file | ✏️ | 98 | | **Unsupported file type** | Try sending as document if not recognized | 📁 | 99 | | **Double hashtags** | Bot automatically handles hashtag formatting | 🏷️ | 100 | 101 | ## 🔒 Security Notes 102 | 103 | - 🔑 Never share your BOT_TOKEN publicly 104 | - 🔐 Use environment variables for sensitive data in production 105 | - 🔄 Regularly update dependencies: `pip install --upgrade -r requirements.txt` 106 | - 📝 Monitor bot usage and logs for suspicious activity 107 | - 🛡️ Keep your bot code private and secure 108 | - 👥 Only add bot to trusted groups 109 | 110 | ## 📄 License 111 | 112 | This project is licensed under the MIT License 113 | 114 | ## 🤝 Contributing 115 | 116 | Contributions are welcome! Please feel free to submit a Pull Request. 117 | 118 | 1. Fork the repository 119 | 2. Create your feature branch (`git checkout -b feature/AmazingFeature`) 120 | 3. Commit your changes (`git commit -m 'Add some AmazingFeature'`) 121 | 4. Push to the branch (`git push origin feature/AmazingFeature`) 122 | 5. Open a Pull Request 123 | 124 | ## 📞 Support 125 | 126 | If you encounter any issues or have questions: 127 | 128 | 1. Check the troubleshooting section above 129 | 2. Open an issue on GitHub 130 | 3. Contact the developer 131 | 132 | --- 133 | 134 | Made with ❤️ by [xPOURY4](https://github.com/xPOURY4) 135 | 136 | -------------------------------------------------------------------------------- /config.py: -------------------------------------------------------------------------------- 1 | BOT_TOKEN = "YOUR_BOT_TOKEN_HERE" # Get from BotFather 2 | GROUP_ID = -1001234567890 # Use numeric ID (negative for groups) 3 | -------------------------------------------------------------------------------- /main.py: -------------------------------------------------------------------------------- 1 | import logging 2 | from telegram import Update 3 | from telegram.ext import Updater, CommandHandler, MessageHandler, Filters, CallbackContext, ConversationHandler 4 | from config import BOT_TOKEN, GROUP_ID 5 | 6 | logging.basicConfig( 7 | format='%(asctime)s - %(name)s - %(levelname)s - %(message)s', 8 | level=logging.INFO 9 | ) 10 | logger = logging.getLogger(__name__) 11 | 12 | WAITING_FOR_NAME = 1 13 | 14 | def start(update: Update, context: CallbackContext) -> None: 15 | """Send a message when the command /start is issued.""" 16 | update.message.reply_text( 17 | "👋 Welcome! Send me any file and I'll ask for a name to add as a hashtag.\n\n" 18 | "📁 Supported formats: All documents (PDF, ZIP, RAR, PSD, TIF, etc.), photos, videos, audio files\n\n" 19 | "💡 I'll automatically add # to your name if you forget!\n\n" 20 | "Files will be forwarded to our group with your custom hashtag.\n\n" 21 | "Use /help for more information." 22 | ) 23 | 24 | def help_command(update: Update, context: CallbackContext) -> None: 25 | """Send a message when the command /help is issued.""" 26 | update.message.reply_text( 27 | "📖 Help:\n" 28 | "1. 📤 Send any file to this bot\n" 29 | "2. ✏️ I'll ask you to enter a name for the file\n" 30 | "3. 🏷️ The file will be sent to the group with #YourName as caption\n" 31 | "4. 💡 I'll automatically add # if you forget!\n" 32 | "5. 📁 Supported: All documents, images, videos, audio\n" 33 | "6. 🚫 Use /cancel to abort the operation" 34 | ) 35 | 36 | def cancel(update: Update, context: CallbackContext) -> int: 37 | """Cancel the conversation.""" 38 | update.message.reply_text("❌ Operation cancelled. Send a new file to start again.") 39 | return ConversationHandler.END 40 | 41 | def receive_file(update: Update, context: CallbackContext) -> int: 42 | """Handle file uploads and ask for a name.""" 43 | # Store file information 44 | if update.message.document: 45 | context.user_data['file_id'] = update.message.document.file_id 46 | context.user_data['file_type'] = 'document' 47 | context.user_data['file_name'] = update.message.document.file_name 48 | elif update.message.photo: 49 | context.user_data['file_id'] = update.message.photo[-1].file_id 50 | context.user_data['file_type'] = 'photo' 51 | context.user_data['file_name'] = 'photo.jpg' 52 | elif update.message.video: 53 | context.user_data['file_id'] = update.message.video.file_id 54 | context.user_data['file_type'] = 'video' 55 | context.user_data['file_name'] = update.message.video.file_name or 'video.mp4' 56 | elif update.message.audio: 57 | context.user_data['file_id'] = update.message.audio.file_id 58 | context.user_data['file_type'] = 'audio' 59 | context.user_data['file_name'] = update.message.audio.file_name or 'audio.mp3' 60 | else: 61 | update.message.reply_text("❌ Unsupported file type. Please send a document, photo, video or audio.") 62 | return ConversationHandler.END 63 | 64 | file_name = context.user_data.get('file_name', 'unknown') 65 | update.message.reply_text( 66 | f"📝 Please enter a name for this file ({file_name}).\n\n" 67 | "💡 I'll automatically add # to your name if you forget!\n\n" 68 | "Example: 'ProjectX' becomes #ProjectX\n\n" 69 | "Use /cancel to abort." 70 | ) 71 | return WAITING_FOR_NAME 72 | 73 | def receive_name(update: Update, context: CallbackContext) -> int: 74 | """Handle the name input and send file to group.""" 75 | name = update.message.text.strip() 76 | if not name: 77 | update.message.reply_text("❌ Name cannot be empty. Please enter a valid name.") 78 | return WAITING_FOR_NAME 79 | clean_name = name.replace('#', '').strip() 80 | if not clean_name: 81 | update.message.reply_text("❌ Name cannot be empty or just '#'. Please enter a valid name.") 82 | return WAITING_FOR_NAME 83 | hashtag = f"#{clean_name.replace(' ', '_')}" 84 | 85 | try: 86 | file_id = context.user_data.get('file_id') 87 | file_type = context.user_data.get('file_type') 88 | file_name = context.user_data.get('file_name', 'unknown') 89 | 90 | if not file_id or not file_type: 91 | update.message.reply_text("❌ Error: File information lost. Please try again.") 92 | return ConversationHandler.END 93 | if file_type == 'document': 94 | context.bot.send_document( 95 | chat_id=GROUP_ID, 96 | document=file_id, 97 | caption=f"{hashtag}\n📁 {file_name}" 98 | ) 99 | elif file_type == 'photo': 100 | context.bot.send_photo( 101 | chat_id=GROUP_ID, 102 | photo=file_id, 103 | caption=f"{hashtag}\n🖼️ Photo" 104 | ) 105 | elif file_type == 'video': 106 | context.bot.send_video( 107 | chat_id=GROUP_ID, 108 | video=file_id, 109 | caption=f"{hashtag}\n🎬 {file_name}" 110 | ) 111 | elif file_type == 'audio': 112 | context.bot.send_audio( 113 | chat_id=GROUP_ID, 114 | audio=file_id, 115 | caption=f"{hashtag}\n🎵 {file_name}" 116 | ) 117 | 118 | update.message.reply_text( 119 | f"✅ Success! File sent to the group with caption:\n" 120 | f"{hashtag}\n\n" 121 | f"📁 File: {file_name}" 122 | ) 123 | logger.info(f"File sent to group with caption: {hashtag} | File: {file_name}") 124 | 125 | except Exception as e: 126 | logger.error(f"Error sending file: {e}") 127 | update.message.reply_text("❌ Failed to send file. Please make sure the bot is a member of the group.") 128 | context.user_data.clear() 129 | return ConversationHandler.END 130 | 131 | def main() -> None: 132 | """Start the bot.""" 133 | updater = Updater(BOT_TOKEN) 134 | dispatcher = updater.dispatcher 135 | 136 | # Create conversation handler 137 | conv_handler = ConversationHandler( 138 | entry_points=[MessageHandler( 139 | Filters.document | Filters.photo | Filters.video | Filters.audio, 140 | receive_file 141 | )], 142 | states={ 143 | WAITING_FOR_NAME: [MessageHandler(Filters.text & ~Filters.command, receive_name)] 144 | }, 145 | fallbacks=[CommandHandler('cancel', cancel)], 146 | per_message=False 147 | ) 148 | dispatcher.add_handler(CommandHandler("start", start)) 149 | dispatcher.add_handler(CommandHandler("help", help_command)) 150 | dispatcher.add_handler(conv_handler) 151 | updater.start_polling() 152 | logger.info("Bot started successfully!") 153 | updater.idle() 154 | 155 | if __name__ == '__main__': 156 | main() 157 | -------------------------------------------------------------------------------- /requirements.txt: -------------------------------------------------------------------------------- 1 | python-telegram-bot==13.15 2 | --------------------------------------------------------------------------------