rename bot and improve forwarding logic

This commit is contained in:
2026-07-02 21:07:36 +03:00
parent c5d096b19b
commit f397916816
8 changed files with 65 additions and 20 deletions
+1
View File
@@ -3,3 +3,4 @@
BOT_TOKEN=123456789:ABCdefGhIJKlmNoPQRsTUVwxyZ
GROUP_CHAT_ID=-100123456789
ADMIN_IDS=123456789,987654321
DISABLE_CAPTCHA=False
+2 -1
View File
@@ -16,7 +16,7 @@ A Telegram bot designed for secure message forwarding with captcha verification.
1. **Clone the repository**:
```bash
git clone <repository_url>
cd Frankenstein-bot
cd AWB
```
2. **Install dependencies**:
@@ -38,6 +38,7 @@ A Telegram bot designed for secure message forwarding with captcha verification.
- `BOT_TOKEN`: Your Telegram Bot token from @BotFather.
- `GROUP_CHAT_ID`: The ID of the group where messages should be redirected.
- `ADMIN_IDS`: A comma-separated list of Telegram User IDs who can access admin commands.
- `DISABLE_CAPTCHA`: Set to `True` to disable the captcha verification step (optional, defaults to `False`).
## Usage
+1
View File
@@ -9,6 +9,7 @@ class Settings(BaseSettings):
bot_token: SecretStr
group_chat_id: int
admin_ids: str
disable_captcha: bool = False
@property
def admins(self) -> list[int]:
+48 -10
View File
@@ -1,4 +1,4 @@
from aiogram import Router, F, Bot
from aiogram import Router, F, Bot, html
from aiogram.filters import CommandStart
from aiogram.types import Message, BufferedInputFile
from aiogram.fsm.context import FSMContext
@@ -34,20 +34,21 @@ async def process_captcha(message: Message, state: FSMContext, bot: Bot, locale:
target_chat_id = settings.group_chat_id
if data.get('has_media'):
new_caption = prefix
new_caption = html.quote(prefix)
if data.get('original_caption'):
new_caption += f"\n{data.get('original_caption')}"
new_caption += f"\n{html.quote(data.get('original_caption'))}"
await bot.copy_message(
chat_id=target_chat_id,
from_chat_id=message.chat.id,
message_id=original_msg_id,
caption=new_caption
caption=new_caption,
parse_mode=None # Use default or specific? Default is HTML.
)
elif data.get('is_text'):
await bot.send_message(
chat_id=target_chat_id,
text=f"{prefix}\n{data.get('original_text')}"
text=f"{html.quote(prefix)}\n{html.quote(data.get('original_text'))}"
)
else:
# Other types (stickers, etc.)
@@ -56,7 +57,7 @@ async def process_captcha(message: Message, state: FSMContext, bot: Bot, locale:
from_chat_id=message.chat.id,
message_id=original_msg_id
)
await bot.send_message(chat_id=target_chat_id, text=prefix)
await bot.send_message(chat_id=target_chat_id, text=html.quote(prefix))
await message.answer(_("captcha_solved", locale=locale))
@@ -73,16 +74,53 @@ async def process_captcha(message: Message, state: FSMContext, bot: Bot, locale:
)
@router.message(F.chat.type == "private")
async def handle_any_message(message: Message, state: FSMContext, locale: str):
async def handle_any_message(message: Message, state: FSMContext, bot: Bot, locale: str):
# Log everything
db_msg_id = db.log_message(message)
# Generate captcha
captcha_text, captcha_img = generate_captcha()
has_media = bool(message.photo or message.video or message.document or message.audio or message.voice)
is_text = bool(message.text)
if settings.disable_captcha:
try:
wait_message = await message.answer(_("processing_message", locale=locale))
prefix = f"Forwarding, ID [{db_msg_id}]:"
target_chat_id = settings.group_chat_id
if has_media:
new_caption = html.quote(prefix)
if message.caption:
new_caption += f"\n{html.quote(message.caption)}"
await bot.copy_message(
chat_id=target_chat_id,
from_chat_id=message.chat.id,
message_id=message.message_id,
caption=new_caption
)
elif is_text:
await bot.send_message(
chat_id=target_chat_id,
text=f"{html.quote(prefix)}\n{html.quote(message.text)}"
)
else:
await bot.copy_message(
chat_id=target_chat_id,
from_chat_id=message.chat.id,
message_id=message.message_id
)
await bot.send_message(chat_id=target_chat_id, text=html.quote(prefix))
await wait_message.edit_text(_("message_processed", locale=locale))
return
except Exception as e:
print(f"Error forwarding without captcha: {e}")
# Fallback to captcha if something goes wrong?
# Or just ignore. Usually, we want to proceed.
pass
# Generate captcha
captcha_text, captcha_img = generate_captcha()
await state.set_state(CaptchaStates.waiting_for_captcha)
await state.update_data(
captcha_text=captcha_text,
+3 -1
View File
@@ -11,5 +11,7 @@
"recent_messages": "Recent messages:",
"msg_not_found": "Message with ID {id} not found.",
"msg_details": "Message ID: {id}\nUser: {full_name} (@{username}) [ID: {user_id}]\nType: {content_type}\nTimestamp: {timestamp}\n\nContent:\n{text}",
"id_command": "Current Chat ID: <code>{id}</code>"
"id_command": "Current Chat ID: <code>{id}</code>",
"processing_message": "Forwarding your message...",
"message_processed": "Forwarded!"
}
+3 -1
View File
@@ -11,5 +11,7 @@
"recent_messages": "Останні повідомлення:",
"msg_not_found": "Повідомлення з ID {id} не знайдено.",
"msg_details": "ID повідомлення: {id}\nКористувач: {full_name} (@{username}) [ID: {user_id}]\nТип: {content_type}\nЧас: {timestamp}\n\nВміст:\n{text}",
"id_command": "Поточний ID чату: <code>{id}</code>"
"id_command": "Поточний ID чату: <code>{id}</code>",
"processing_message": "Відправляємо ваше повідомлення...",
"message_processed": "Відправлено!"
}
+2 -2
View File
@@ -24,7 +24,7 @@ logger = logging.getLogger(__name__)
async def main():
logger.info("Initializing Frankenstein Bot...")
logger.info("Initializing AWB...")
# Initialize Bot instance with default HTML parsing mode
bot = Bot(
@@ -75,4 +75,4 @@ if __name__ == "__main__":
try:
asyncio.run(main())
except (KeyboardInterrupt, SystemExit):
logger.info("Frankenstein Bot execution stopped.")
logger.info("AWB execution stopped.")
+5 -5
View File
@@ -7,7 +7,7 @@ aiofiles==25.1.0 \
aiogram==3.29.1 \
--hash=sha256:63cd0123e8ab065f78974ad58ff57c1a5c8c35aac1055761859c4a5ad27eaf04 \
--hash=sha256:7ac92c64b71d33eb8e3656de4517a1533a88b61728e5dd00b1e11393b669b521
# via frankenstein-bot
# via awb
aiohappyeyeballs==2.7.1 \
--hash=sha256:065665c041c42a5938ed220bdcd7230f22527fbec085e1853d2402c8a3615d9d \
--hash=sha256:9243213661e29250eb41368e5daa826fc017156c3b8a11440826b2e3ed376472
@@ -63,7 +63,7 @@ aiosignal==1.4.0 \
aiosqlite==0.22.1 \
--hash=sha256:043e0bd78d32888c0a9ca90fc788b38796843360c855a7262a532813133a0650 \
--hash=sha256:21c002eb13823fad740196c5a2e9d8e62f6243bd9e7e4a1f87fb5e44ecb4fceb
# via frankenstein-bot
# via awb
annotated-types==0.7.0 \
--hash=sha256:1f02e8b43a8fbbc3f3e0d4f0f4bfc8131bcb4eebe8849b8e5c773f3a1c582a53 \
--hash=sha256:aff07c09a53a08bc8cfccb9c85b05f1aa9a2a6f23728d790723543408344ce89
@@ -75,7 +75,7 @@ attrs==26.1.0 \
captcha==0.7.1 \
--hash=sha256:8b73b5aba841ad1e5bdb856205bf5f09560b728ee890eb9dae42901219c8c599 \
--hash=sha256:a1b462bcc633a64d8db5efa7754548a877c698d98f87716c620a707364cabd6b
# via frankenstein-bot
# via awb
certifi==2026.6.17 \
--hash=sha256:024c88eeec92ca068db80f02b8b07c9cef7b9fe261d1d535abfd5abd6f6af432 \
--hash=sha256:2227dcbaafe0d2f59279d1762ddddc37783ed4354594f194ffc31d20f41fc3db
@@ -258,7 +258,7 @@ pydantic==2.13.4 \
--hash=sha256:c40756b57adaa8b1efeeced5c196f3f3b7c435f90e84ea7f443901bec8099ef6
# via
# aiogram
# frankenstein-bot
# awb
# pydantic-settings
pydantic-core==2.46.4 \
--hash=sha256:0cbe8b01f948de4286c74cdd6c667aceb38f5c1e26f0693b3983d9d74887c65e \
@@ -296,7 +296,7 @@ pydantic-core==2.46.4 \
pydantic-settings==2.14.2 \
--hash=sha256:a20c97b37910b6550d5ea50fbcc2d4187defe58cd57070b73863d069419c9440 \
--hash=sha256:c19dd64b19097f1de80184f0cc7b0272a13ae6e170cbf240a3e27e381ed14a5f
# via frankenstein-bot
# via awb
python-dotenv==1.2.2 \
--hash=sha256:1d8214789a24de455a8b8bd8ae6fe3c6b69a5e3d64aa8a8e5d68e694bbcb285a \
--hash=sha256:2c371a91fbd7ba082c2c1dc1f8bf89ca22564a087c2c287cd9b662adde799cf3