создание креатива постом

This commit is contained in:
Artem Tsyrulnikov
2026-01-06 17:47:31 +03:00
parent 52e65dff05
commit 61f7ed093c
6 changed files with 366 additions and 93 deletions

View File

@@ -28,9 +28,6 @@ type CreativeEditorFields struct {
MediaFileID string // File ID из Telegram
MediaChanged bool
// Навигация (хлебные крошки)
Navigation string
// Состояние для добавления кнопки
WaitingForButtonText bool
WaitingForButtonURL bool
@@ -50,11 +47,6 @@ type CreativeEditorFields struct {
func (e *CreativeEditorFields) GetCreativeText() string {
var result string
// Добавляем навигацию если она есть
if e.Navigation != "" {
result = fmt.Sprintf("<i>%s</i>\n\n", e.Navigation)
}
if e.Text != nil && *e.Text != "" {
// Проверяем что текст не является "визуально пустым" HTML
// Например: "<a class=\"tg-link\"></a>" - пустая ссылка
@@ -364,13 +356,25 @@ func (e *CreativeEditorFields) ShowControlPanel(b *bot.Bot, text string, buttons
// GetFormattedText извлекает форматированный текст из сообщения с entities
func (e *CreativeEditorFields) GetFormattedText(message *echotron.Message) string {
if message.Text == "" {
// Определяем откуда брать текст и entities
var text string
var entities []*echotron.MessageEntity
if message.Text != "" {
text = message.Text
entities = message.Entities
} else if message.Caption != "" {
text = message.Caption
entities = message.CaptionEntities
}
if text == "" {
return ""
}
// Если нет entities - возвращаем текст как есть
if len(message.Entities) == 0 {
return message.Text
if len(entities) == 0 {
return text
}
type tagSpan struct {
@@ -382,10 +386,10 @@ func (e *CreativeEditorFields) GetFormattedText(message *echotron.Message) strin
}
// Преобразуем текст в руны для правильной работы с UTF-8
runes := []rune(message.Text)
runes := []rune(text)
var spans []tagSpan
for _, entity := range message.Entities {
for _, entity := range entities {
// URL уже присутствует в сыром тексте, чтобы не дублировать - пропускаем entity.
if entity.Type == "url" {
continue
@@ -438,6 +442,7 @@ func (e *CreativeEditorFields) GetFormattedText(message *echotron.Message) strin
}
// Пишем текст один раз, вставляя HTML-теги по позициям
// и экранируя HTML-спецсимволы
var result strings.Builder
for i := 0; i <= len(runes); i++ {
if closing, ok := closes[i]; ok {
@@ -453,7 +458,17 @@ func (e *CreativeEditorFields) GetFormattedText(message *echotron.Message) strin
}
}
if i < len(runes) {
result.WriteRune(runes[i])
// Экранируем HTML-спецсимволы
switch runes[i] {
case '<':
result.WriteString("&lt;")
case '>':
result.WriteString("&gt;")
case '&':
result.WriteString("&amp;")
default:
result.WriteRune(runes[i])
}
}
}