Загрузка...

Script
Bot for giving hidden gifts TG

Thread in Python created by s1z_shit Jan 17, 2026. (bumped Jan 26, 2026) 905 views

  1. s1z_shit
    Приветствую! На Новый Год в TG была возможность дарить подарки
    [IMG] [IMG]

    Недавно возможность их покупки убрали, но не совсем, разработчики решили просто скрыть визуальную возможность их покупки, но не удалять их. Этим мы и воспользуемся через бота, его принцип работы - покупка подарка себе/по юзернейму с помощью pyrogram-сессии, все интуитивно понятно, код полностью написан через ИИ, поэтому просьба особо умным людям не писать ничего про правильность написания)
    Python
    import asyncio
    import logging
    import os
    import sys
    from pyrogram import Client as PyroClient
    from aiogram import Bot, Dispatcher, Router, F
    from aiogram.types import Message, CallbackQuery, InlineKeyboardMarkup, InlineKeyboardButton
    from aiogram.filters import CommandStart
    from aiogram.fsm.context import FSMContext
    from aiogram.fsm.state import State, StatesGroup
    from aiogram.fsm.storage.memory import MemoryStorage
    from aiogram.enums import ParseMode
    from dotenv import load_dotenv

    # Загружаем переменные из .env файла
    load_dotenv()

    # ====== ЗАГРУЗКА ПЕРЕМЕННЫХ ИЗ .env ======
    PYRO_API_ID = int(os.getenv('PYRO_API_ID', '0'))
    PYRO_API_HASH = os.getenv('PYRO_API_HASH', '')
    PYRO_SESSION_NAME = os.getenv('PYRO_SESSION_NAME', 'gift')
    BOT_TOKEN = os.getenv('BOT_TOKEN', '')

    # Загружаем подарки из строки .env
    GIFTS_STR = os.getenv('GIFTS', '')
    GIFTS = {}
    if GIFTS_STR:
    for gift in GIFTS_STR.split(','):
    if '=' in gift:
    name, gift_id = gift.split('=', 1)
    GIFTS[name.strip()] = int(gift_id.strip())

    # Проверка загруженных данных
    print(f" API ID: {'Установлен' if PYRO_API_ID else 'Не установлен'}")
    print(f" API Hash: {'Установлен' if PYRO_API_HASH else 'Не установлен'}")
    print(f" Session Name: {PYRO_SESSION_NAME}")
    print(f" Bot Token: {'Установлен' if BOT_TOKEN else 'Не установлен'}")
    print(f" Подарков загружено: {len(GIFTS)}")

    if not all([PYRO_API_ID, PYRO_API_HASH, BOT_TOKEN, GIFTS]):
    print(" Ошибка: Не все необходимые переменные установлены в .env файле!")
    print("Проверьте наличие файла .env со всеми переменными")
    sys.exit(1)

    # Глобальная переменная для pyro клиента
    pyro_app = None

    # Инициализация Aiogram
    bot = Bot(token=BOT_TOKEN)
    storage = MemoryStorage()
    dp = Dispatcher(storage=storage)
    router = Router()
    dp.include_router(router)


    # FSM состояния
    class GiftStates(StatesGroup):
    waiting_for_username = State()
    choosing_gift_for_friend = State()


    # Функция для экранирования Markdown
    def escape_markdown(text: str) -> str:
    """Экранирует специальные символы Markdown"""
    if not text:
    return ""
    escape_chars = r'_*[]()~`>#+-=|{}.!'
    for char in escape_chars:
    text = text.replace(char, f'\\{char}')
    return text


    # Клавиатуры
    def main_keyboard():
    return InlineKeyboardMarkup(
    inline_keyboard=[
    [
    InlineKeyboardButton(text=" Отправить себе", callback_data="send_to_self"),
    InlineKeyboardButton(text=" Отправить другу", callback_data="send_to_friend")
    ],
    [
    InlineKeyboardButton(text=" Список подарков", callback_data="list_gifts")
    ]
    ]
    )


    def gifts_keyboard(prefix="gift_"):
    keyboard = []
    row = []
    for i, gift_name in enumerate(GIFTS.keys()):
    row.append(InlineKeyboardButton(text=gift_name, callback_data=f"{prefix}{gift_name}"))
    if (i + 1) % 2 == 0:
    keyboard.append(row)
    row = []
    if row:
    keyboard.append(row)
    keyboard.append([InlineKeyboardButton(text=" Назад", callback_data="back")])
    return InlineKeyboardMarkup(inline_keyboard=keyboard)


    @router.message(CommandStart())
    async def cmd_start(message: Message):
    await message.answer(
    " <b>Бот для отправки подарков Telegram</b>\n\n"
    "Я управляю вашей сессией для отправки подарков.\n"
    "Выберите действие:",
    reply_markup=main_keyboard(),
    parse_mode=ParseMode.HTML
    )


    @router.callback_query(F.data == "back")
    async def back_to_main(callback: CallbackQuery, state: FSMContext):
    await state.clear()
    await callback.message.edit_text(
    " <b>Главное меню</b>\n\nВыберите действие:",
    reply_markup=main_keyboard(),
    parse_mode=ParseMode.HTML
    )
    await callback.answer()


    @router.callback_query(F.data == "list_gifts")
    async def list_gifts(callback: CallbackQuery):
    gifts_text = "\n".join([f"• {escape_markdown(name)}" for name in GIFTS.keys()])
    await callback.message.edit_text(
    f" <b>Доступные подарки:</b>\n\n{gifts_text}\n\n"
    f"Выберите действие:",
    reply_markup=main_keyboard(),
    parse_mode=ParseMode.HTML
    )
    await callback.answer()


    @router.callback_query(F.data == "send_to_self")
    async def send_to_self_start(callback: CallbackQuery):
    await callback.message.edit_text(
    " <b>Отправка подарка себе</b>\n\nВыберите подарок:",
    reply_markup=gifts_keyboard(prefix="self_gift_"),
    parse_mode=ParseMode.HTML
    )
    await callback.answer()


    @router.callback_query(F.data == "send_to_friend")
    async def send_to_friend_start(callback: CallbackQuery, state: FSMContext):
    await state.set_state(GiftStates.waiting_for_username)
    await callback.message.edit_text(
    " <b>Отправка подарка другу</b>\n\n"
    "Введите username пользователя (например: username или @username):",
    reply_markup=InlineKeyboardMarkup(
    inline_keyboard=[[InlineKeyboardButton(text=" Отмена", callback_data="back")]]
    ),
    parse_mode=ParseMode.HTML
    )
    await callback.answer()


    @router.message(GiftStates.waiting_for_username)
    async def process_username(message: Message, state: FSMContext):
    username = message.text.strip()
    if username.startswith("@"):
    username = username[1:]

    if not username:
    await message.answer(" Username не может быть пустым. Попробуйте снова:")
    return

    try:
    if pyro_app and pyro_app.is_connected:
    chat = await pyro_app.get_chat(username)

    await state.update_data(username=username, chat_id=chat.id)
    await state.set_state(GiftStates.choosing_gift_for_friend)

    first_name = escape_markdown(chat.first_name or "")
    safe_username = escape_markdown(username)

    await message.answer(
    f" Пользователь найден: <b>{first_name}</b>\n"
    f" @{safe_username}\n\n"
    f"Теперь выберите подарок:",
    reply_markup=gifts_keyboard(prefix="friend_gift_"),
    parse_mode=ParseMode.HTML
    )
    else:
    await message.answer(" Ошибка подключения к сессии. Попробуйте позже.")

    except Exception as e:
    await state.clear()
    error_msg = escape_markdown(str(e))
    await message.answer(
    f" Ошибка: {error_msg}\n\n"
    f"Вернитесь в главное меню:",
    reply_markup=main_keyboard(),
    parse_mode=ParseMode.HTML
    )


    @router.callback_query(F.data.startswith("self_gift_"))
    async def send_gift_to_self(callback: CallbackQuery):
    gift_name = callback.data.replace("self_gift_", "")
    gift_id = GIFTS.get(gift_name)

    if not gift_id:
    await callback.answer(" Подарок не найден", show_alert=True)
    return

    safe_gift_name = escape_markdown(gift_name)

    await callback.message.edit_text(
    f" Отправляю подарок <b>{safe_gift_name}</b> себе...",
    parse_mode=ParseMode.HTML
    )

    try:
    if pyro_app and pyro_app.is_connected:
    await pyro_app.send_gift(
    chat_id="me",
    gift_id=gift_id
    )

    await callback.message.edit_text(
    f" <b>Подарок отправлен!</b>\n\n"
    f" Подарок: {safe_gift_name}\n"
    f" Получатель: Вы\n"
    f" ID: <code>{gift_id}</code>",
    reply_markup=main_keyboard(),
    parse_mode=ParseMode.HTML
    )
    else:
    await callback.message.edit_text(
    " Ошибка подключения к сессии",
    reply_markup=main_keyboard(),
    parse_mode=ParseMode.HTML
    )

    except Exception as e:
    error_msg = escape_markdown(str(e))
    await callback.message.edit_text(
    f" <b>Ошибка отправки:</b>\n\n{error_msg}",
    reply_markup=main_keyboard(),
    parse_mode=ParseMode.HTML
    )

    await callback.answer()


    @router.callback_query(F.data.startswith("friend_gift_"))
    async def send_gift_to_friend(callback: CallbackQuery, state: FSMContext):
    gift_name = callback.data.replace("friend_gift_", "")
    gift_id = GIFTS.get(gift_name)

    if not gift_id:
    await callback.answer(" Подарок не найден", show_alert=True)
    return

    data = await state.get_data()
    username = data.get("username")
    chat_id = data.get("chat_id")

    safe_gift_name = escape_markdown(gift_name)
    safe_username = escape_markdown(username) if username else "неизвестно"

    await callback.message.edit_text(
    f" Отправляю подарок <b>{safe_gift_name}</b> пользователю @{safe_username}...",
    parse_mode=ParseMode.HTML
    )

    try:
    if pyro_app and pyro_app.is_connected:
    await pyro_app.send_gift(
    chat_id=chat_id,
    gift_id=gift_id,
    hide_my_name=False
    )

    await callback.message.edit_text(
    f" <b>Подарок отправлен!</b>\n\n"
    f" Подарок: {safe_gift_name}\n"
    f" Получатель: @{safe_username}\n"
    f" ID: <code>{gift_id}</code>",
    reply_markup=main_keyboard(),
    parse_mode=ParseMode.HTML
    )
    else:
    await callback.message.edit_text(
    " Ошибка подключения к сессии",
    reply_markup=main_keyboard(),
    parse_mode=ParseMode.HTML
    )

    except Exception as e:
    error_msg = str(e)
    safe_error = escape_markdown(error_msg)

    if "USER_NOT_PREMIUM" in error_msg:
    await callback.message.edit_text(
    f" <b>Ошибка:</b> Пользователь @{safe_username} должен иметь Telegram Premium",
    reply_markup=main_keyboard(),
    parse_mode=ParseMode.HTML
    )
    else:
    await callback.message.edit_text(
    f" <b>Ошибка отправки:</b>\n\n{safe_error}",
    reply_markup=main_keyboard(),
    parse_mode=ParseMode.HTML
    )

    await state.clear()
    await callback.answer()


    async def create_and_start_pyro_client():
    """Создает и запускает Pyrogram клиента"""
    global pyro_app

    try:
    pyro_app = PyroClient(
    name=PYRO_SESSION_NAME,
    api_id=PYRO_API_ID,
    api_hash=PYRO_API_HASH,
    in_memory=False
    )

    await pyro_app.start()

    me = await pyro_app.get_me()
    print(f" Pyrogram подключен как: @{me.username} (ID: {me.id})")

    return True
    except Exception as e:
    print(f" Ошибка подключения Pyrogram: {e}")
    return False


    async def auth_pyrogram():
    """Авторизация Pyrogram (только если сессии нет)"""
    print(" Запуск авторизации Pyrogram...")

    async with PyroClient(
    name=PYRO_SESSION_NAME,
    api_id=PYRO_API_ID,
    api_hash=PYRO_API_HASH
    ) as app:
    await app.start()
    me = await app.get_me()
    print(f" Авторизован как: @{me.username} (ID: {me.id})")

    session_file = f"{PYRO_SESSION_NAME}.session"
    if os.path.exists(session_file):
    print(f" Сессия сохранена в файл: {session_file}")
    else:
    print(" Сессия не сохранена в файл!")


    def check_session_exists():
    """Проверяет существование файла сессии"""
    session_file = f"{PYRO_SESSION_NAME}.session"
    if os.path.exists(session_file):
    print(f" Найдена сессия: {session_file}")
    return True
    else:
    print(f" Сессия не найдена: {session_file}")
    return False


    async def main():
    # Настройка логирования
    logging.basicConfig(
    level=logging.INFO,
    format="%(asctime)s - %(name)s - %(levelname)s - %(message)s"
    )
    logging.getLogger("pyrogram").setLevel(logging.WARNING)

    print(" Инициализация бота...")
    print(f" Загружено подарков: {len(GIFTS)}")

    if not check_session_exists():
    print(" Файл сессии не найден.")
    print("Хотите создать новую сессию? (y/n)")
    choice = input().strip().lower()
    if choice == 'y':
    await auth_pyrogram()
    else:
    print("Бот не может работать без сессии.")
    return

    print(" Подключение к Pyrogram...")
    if not await create_and_start_pyro_client():
    print(" Не удалось подключиться к Pyrogram.")
    print("Возможно, сессия устарела или невалидна.")
    print("Попробуйте удалить файл test.session и запустить авторизацию заново.")
    return

    print(" Запуск Telegram бота...")

    try:
    await dp.start_polling(bot)
    except Exception as e:
    print(f" Ошибка при работе бота: {e}")
    finally:
    if pyro_app and pyro_app.is_connected:
    print(" Остановка Pyrogram...")
    await pyro_app.stop()
    print(" Pyrogram остановлен")


    if __name__ == "__main__":
    import sys

    if len(sys.argv) > 1 and sys.argv[1] == "auth":
    print(" Авторизация Pyrogram...")
    try:
    asyncio.run(auth_pyrogram())
    except KeyboardInterrupt:
    print("\nАвторизация прервана")
    elif len(sys.argv) > 1 and sys.argv[1] == "check":
    print(" Проверка сессии...")
    if check_session_exists():
    print(" Сессия существует")
    else:
    print(" Сессия не найдена")
    elif len(sys.argv) > 1 and sys.argv[1] == "test":
    print(" Тест конфигурации...")
    print(f"API ID: {PYRO_API_ID}")
    print(f"API Hash: {'Установлен' if PYRO_API_HASH else 'Нет'}")
    print(f"Bot Token: {'Установлен' if BOT_TOKEN else 'Нет'}")
    print(f"Подарки: {GIFTS}")
    else:
    try:
    asyncio.run(main())
    except KeyboardInterrupt:
    print("\n\n Бот остановлен пользователем")
    Code
    # Pyrogram настройки
    PYRO_API_ID=ваш_api_id_TG
    PYRO_API_HASH=ваш_api_hash_TG
    PYRO_SESSION_NAME=gift

    # Bot настройки
    BOT_TOKEN=ваш_токен_бота

    # Подарки (формат: название=ID через запятую)
    GIFTS=Елочка=5922558454332916696,Мишка=5956217000635139069


    Бот исправно работал на Python 3.10.4, на других версиях не проверял.
    pip install aiogram pyrogram python-dotenv pyrofork tgcrypto

    Так же оставлю ID подарков, если вдруг кому-то нужно -
    "Елочка": 5922558454332916696
    "Мишка": 5956217000635139069
    Используйте на свой страх и риск, за использование уязвимости вполне можно получить блокировку аккаунта!
     
  2. cbIrnbIuWarik
    Ну ты крутой
     
    1. s1z_shit Topic starter
      avatarcbIrnbIuWarik, к чему ты это написал?) дети на ФП и в ботах своих продают эти подарки за x3 прайса, может кому-то интересно будет как они это делают
    2. cbIrnbIuWarik
      avatars1z_shit, Я тебя просто похвалил <3
  3. loosle
    думаю мне это пригодится, сяб
     
  4. Jjlogger23
    Jjlogger23 Jan 18, 2026 13 Jun 23, 2025
    Годно
     
  5. chr3ter
    chr3ter Jan 18, 2026 10 Jul 26, 2024
    блять акк заморозило итог звезды проебаны
     
  6. детектив
    детектив Jan 18, 2026 elvis has left the building 288 Nov 19, 2019
    архитектурно можно спорить (глобальный pyro_app зачем-то + смешение UI и логики, избыточный маркдаун эскейп при html), но для утилитарного бота под конкретную задачу это вообще не минус
     
    1. s1z_shit Topic starter
      avatarдетектив,
      не видел и до сих пор не вижу смысла стараться писать именно такого бота самому, это было сделано за 2 запроса в гптшку
    2. детектив
      avatars1z_shit, тогда понял, не обратил внимание что это результат работ ИИ
  7. Seyran
    Seyran Feb 15, 2026 0 Feb 4, 2026
    бля не ворк, мб тутор сделаешь на ютубе что как управлять
     
    1. s1z_shit Topic starter
      avatarSeyran, что не ворк? ошибка вылазит или что? уже так-то и пофиксить могли, много времени прошло
    2. CreveexShop
      avatars1z_shit, вылазит ошибка по поводу отсутствия атрибута send gift, только это и все, да и боты которые отправляют подарки до сих пор существуют
  8. Imammmm
    Здравствуйте, все id рабочие а можно спросить где взять еще id мишек которые вышли на сегодняшний день например на святого Патрика или 8 марта
     
    1. catupires
      avatarImammmm, 5801108895304779062 сердце 14 февраля

      5800655655995968830 мишаня 14 февраля

      5893356958802511476 мишаня ирландский (святой патрик)
  9. natureles
    А может дарить НЕ анонимно?
     
Loading...