Files
social-post-writer-bot/help_message.py
T

106 lines
8.4 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
from __future__ import annotations
import html
WELCOME_RICH_HTML = """<h1>Привет! Я — бот для написания постов</h1>
<p>Помогаю писать и редактировать посты для соцсетей. Расскажи, о чём нужен пост, а я верну три варианта: короткий, развёрнутый и с призывом к действию.</p>
<h2>Примеры запросов</h2>
<ul>
<li>«Напиши пост про запуск нового продукта»</li>
<li>«Сделай пост-напоминание о вебинаре в официальном тоне»</li>
<li>«Обнови этот вариант, добавь эмодзи» — реплаем на мой текст</li>
</ul>
<p>Выбери режим в нижнем меню: «Обучение», «Генерация», «Подписка» или «Помощь». Внутри режима кнопка «Главное меню» возвращает сюда. Команда /start тоже открывает главное меню.</p>
<p>В режиме «Обучение» пришли скриншоты своих постов; в режиме «Генерация» попроси идею или пост.</p>
"""
HELP_MENU_TITLE = "Помощь по боту"
HELP_MENU_INTRO = "Выбери раздел — откроется только он. Из любого раздела можно перейти в любой."
HELP_SECTIONS: dict[str, tuple[str, str]] = {
"posts": (
"✍️ Написать пост",
"""<ol>
<li>В режиме «Генерация» напиши сообщение или отправь голосовое с прямой просьбой, например: «Придумай пост для Telegram про запуск нового продукта».</li>
<li>Можешь указать площадку, аудиторию, факты, длину, цель и другие требования. Можно надиктовать подробное ТЗ или просто тему.</li>
<li>Я распознаю речь, проверю, просишь ли ты именно написать пост, и верну три варианта отдельными сообщениями.</li>
</ol>
<p>В сообщениях с вариантами будет только текст поста: без нумерации и вступлений, с абзацами, переносами строк и уместными эмодзи.</p>""",
),
"tone": (
"🎨 Tone of Voice",
"""<p>Пришли скриншоты постов, текстовые примеры или просто расскажи об аккаунте. Можно отправить голосовое или аудиофайл. Я буду постепенно накапливать и обновлять профиль аккаунта и Tone of Voice; новые сведения дополняют прежние.</p>
<p>Чтобы начать обучение заново и удалить накопленное, нажми «Сбросить данные» и подтверди действие.</p>""",
),
"edit": (
"✏️ Правка поста",
"""<p>Ответь реплаем на сообщение с вариантом и укажи, что изменить. Например: «Сделай короче и добавь призыв». Я учту оригинальный текст и верну три новых варианта отдельными сообщениями.</p>""",
),
"idea": (
"💡 Идея для поста",
"""<p>Напиши «предложи идею для поста», «о чём написать?» или «накидай тему» — верну одну идею. Команда <code>/idea</code> работает так же.</p>
<p>Идеи сохраняются, чтобы не повторяться: каждая новая идея отличается от предыдущих.</p>""",
),
"subscription": (
"💳 Подписка",
"""<p>У тебя есть пробный период — 3 дня бесплатно. Дальше — подписка на 30 дней за 100 звёзд.</p>
<ul>
<li><code>/balance</code> — узнать статус: сколько осталось дней триала или подписки.</li>
<li><code>/subscribe</code> — оплатить подписку на 30 дней.</li>
</ul>
<p>При входе в режим «Подписка» бот сразу показывает активный период и сколько дней осталось. Нажми «Продлить подписку», чтобы сразу открыть счёт в звёздах. Когда период закончится, генерация постов и идей станет недоступна.</p>""",
),
"commands": (
"⌨️ Команды",
"""<p>Команды-переключатели доступны в любом режиме: <code>/start</code> — главное меню; <code>/training</code> — обучение; <code>/generate</code> — генерация; <code>/subscription</code> — подписка; <code>/help</code> — помощь.</p>
<p>Действия доступны только в своём режиме: <code>/style</code> и <code>/clear</code> — обучение; <code>/post</code> и <code>/idea</code> — генерация; <code>/balance</code> и <code>/subscribe</code> — подписка. <code>/clear</code> и кнопка «Сбросить данные» сначала запрашивают подтверждение; подписка и триал не меняются.</p>
<p>В режиме «Генерация» можно попросить идею обычными словами: «предложи идею для поста», «о чём написать?», «накидай тему».</p>""",
),
"support": (
"🆘 Поддержка",
"""<p>В режиме «Помощь» нажми «🆘 Поддержка» или отправь <code>/support</code>. В ответ придёт приветствие оператора — напиши текстом, чем помочь; можно приложить фото, документ или голосовое.</p>
<p>Оператор видит твоё сообщение и отвечает прямо в этом чате. Переписка продолжается в том же обращении: можно отвлечься на другие режимы, вернуться и дописать.</p>
<p>Кнопка «Главное меню» завершает обращение. Оно не удаляется: при следующем нажатии «Поддержка» оператор увидит всю историю.</p>""",
),
}
HELP_SECTION_ORDER: tuple[str, ...] = tuple(HELP_SECTIONS)
def help_menu_html(current: str | None = None) -> str:
return (
f"<h1>{HELP_MENU_TITLE}</h1>"
f"<p>{HELP_MENU_INTRO}</p>"
f"<p>Я помогаю писать и редактировать посты для соцсетей. "
f"Генерирую посты только по явной просьбе.</p>"
)
def help_section_html(section: str) -> str:
title, body = HELP_SECTIONS[section]
return f"<h1>{title}</h1>{body}"
def help_view(section: str | None = None) -> str:
if section and section in HELP_SECTIONS:
return help_section_html(section)
return help_menu_html(section)
def help_plain_view(section: str | None = None) -> str:
if section and section in HELP_SECTIONS:
title, body = HELP_SECTIONS[section]
return f"{HELP_MENU_TITLE} — {title}\n\n{rich_to_plain(body)}"
lines = [HELP_MENU_TITLE, HELP_MENU_INTRO]
lines += [f"• {HELP_SECTIONS[name][0]}" for name in HELP_SECTION_ORDER]
return "\n".join(lines)
def rich_to_plain(rich_html: str) -> str:
import re
text = re.sub(r"<li(?:\s[^>]*)?>", "• ", rich_html, flags=re.IGNORECASE)
text = re.sub(r"</?(?:h[1-6]|p|ul|ol|li|hr|table|tr|td|th|input)(?:\s[^>]*)?/?>", "\n", text, flags=re.IGNORECASE)
text = re.sub(r"<[^>]+>", "", text)
text = html.unescape(text)
return "\n".join(line.strip() for line in text.splitlines() if line.strip())