Как создать бота для добавления водяных знаков?

Здравствуйте! 

Я разрабатываю Telegram-бота, который автоматически добавляет текстовый водяной знак в конце каждого нового поста на канале. Основной функционал уже реализован, но я хотел бы расширить его возможностью добавления кастомных эмодзи в водяной знак. 

К сожалению, я не понимаю, как внедрить эту функциональность. Можете, пожалуйста, подсказать, как это лучше сделать? Буду признателен за любые советы и помощь. 

Спасибо! 

Вот часть кода, реализующего основной функционал, если кому-то интересно: 
<pre><code class="python">import logging
from telegram import Update, MessageEntity
from telegram.ext import (
    ApplicationBuilder,
    CommandHandler,
    MessageHandler,
    filters,
    ContextTypes,
)

# Токен бота
TOKEN = "ваш_токен"

# Логирование
logging.basicConfig(level=logging.INFO)
logger = logging.getLogger(__name__)

# Корректировка смещения для entities
def adjust_entities_offset(entities, offset):
    """Корректирует смещение entities."""
    if not entities:
        return []
    return [
        MessageEntity(
            type=entity.type,
            offset=entity.offset + offset,
            length=entity.length,
        )
        for entity in entities
    ]

# Обработчик новых сообщений в канале
async def handle_channel_post(update: Update, context: ContextTypes.DEFAULT_TYPE):
    """Добавляет водяной знак к новым сообщениям в канале."""
    post = update.channel_post
    if not post:
        return

    watermark = "© Ваш водяной знак"
    separator = "\n\n"

    try:
        if post.text:
            original_entities = list(post.entities or [])
            updated_text = f"{post.text}{separator}{watermark}"
           
  • 24 ноября 2024 г. 19:43
Ответы на вопрос 2
Чтобы расширить функционал вашего Telegram-бота и добавить возможность вставки кастомных эмодзи в водяной знак, вам нужно сделать несколько вещей. Во-первых, вы должны предоставить команду или функцию, которая будет позволять пользователю задавать кастомный водяной знак с эмодзи. Во-вторых, вам необходимо обновить обработчик новых сообщений, чтобы учесть пользовательские настройки при добавлении водяного знака.

Вот базовый пример, как это можно реализовать.

1. Разработайте команду для установки кастомного водяного знака с эмодзи.
2. Измените обработчик нового поста, чтобы использовать заданный водяной знак.

### Новый код

Добавьте следующий код для реализации этой функциональности:

```python
# Словарь для хранения пользовательских водяных знаков по ID пользователя
user_watermarks = {}

# Команда для установки кастомного водяного знака
async def set_watermark(update: Update, context: ContextTypes.DEFAULT_TYPE):
    """Устанавливает кастомный водяной знак для пользователя."""
    user_id = update.effective_user.id
    if context.args:
        # Объединяем все аргументы и формируем один водяной знак
        custom_watermark = ' '.join(context.args)
        user_watermarks[user_id] = custom_watermark
        await update.message.reply_text(f"Ваш водяной знак установлен: {custom_watermark}")
    else:
        await update.message.reply_text("Пожалуйста, введите текст водяного знака после команды.")

# Обработчик новых сообщений в канале с учетом пользовательского водяного знака
async def handle_channel_post(update: Update, context: ContextTypes.DEFAULT_TYPE):
    """Добавляет водяной знак к новым сообщениям в канале."""
    post = update.channel_post
    if not post:
        return

    user_id = post.from_user.id
    default_watermark = "© Ваш водяной знак"
    # Получаем пользовательский водяной знак, если он установлен
    watermark = user_watermarks.get(user_id, default_watermark)
    separator = "\n\n"

    try:
        if post.text:
            original_entities = list(post.entities or [])
            updated_text = f"{post.text}{separator}{watermark}"
            # Корректируем smeshenie entities для нового текста
            new_entities = adjust_entities_offset(original_entities, len(updated_text) - len(post.text))
            await context.bot.send_message(chat_id=post.chat.id, text=updated_text, entities=new_entities)
            await context.bot.delete_message(chat_id=post.chat.id, message_id=post.message_id)
    except Exception as e:
        logger.error(f"Ошибка при обработке поста: {e}")

def main():
    """Запуск бота."""
    application = ApplicationBuilder().token(TOKEN).build()
    
    application.add_handler(CommandHandler("set_watermark", set_watermark))
    application.add_handler(MessageHandler(filters.Channel, handle_channel_post))
    
    application.run_polling()

if __name__ == "__main__":
    main()
```

### Объяснение кода:

1. **Словарь для водяных знаков**: Мы используем словарь `user_watermarks`, чтобы хранить индивидуальные водяные знаки для каждого пользователя, который взаимодействует с ботом.

2. **Команда `/set_watermark`**: Вы добавили команду, которая позволяет пользователю установить свой собственный водяной знак. Пользователь вводит эту команду с текстом знака, и он сохраняется в `user_watermarks`.

3. **Обновленный обработчик сообщений**: Теперь в обработчике `handle_channel_post` мы проверяем наличие пользовательского водяного знака для пользователя или используем стандартный, если его нет.

Теперь ваш Telegram-бот будет добавлять кастомные водяные знаки с эмодзи в уведомления по мере их поступления!
Из документации ( <a href="https://core.telegram.org/bots/api#markdownv2-style" rel="nofollow">один</a> , <a href="https://fragment.com/about" rel="nofollow">два</a> ): <br/> <br/> <blockquote>Custom emoji entities can only be used by bots that purchased additional usernames on Fragment</blockquote> <br/> <blockquote>You can also upgrade collectible usernames to assign them to Telegram bots. To upgrade, assign the username to a bot and pay a one-time fee.</blockquote> <br/> <br/> Если коротко: это будет очень дорогая задача (найти точную цифру не получилось, оценка снизу — 600 000 ₽). Не уверен, что вам это нужно. Если нужно — информация по покупке коллекционного имени для бота есть по второй ссылке, а непосредственно по вставке кастомных эмодзи — по первой.
Похожие вопросы