refactor: чистка мёртвого кода, лимит ходов D3, HTML-экранирование и UTF-8 обрезка в Telegram
This commit is contained in:
@@ -16,6 +16,7 @@ import (
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
"unicode/utf8"
|
||||
|
||||
"github.com/kamelion/ratatoskr-go/internal/chat"
|
||||
)
|
||||
@@ -109,7 +110,7 @@ func (ch *Channel) handleUpdate(ctx context.Context, upd update) {
|
||||
func (ch *Channel) sendMsg(chatID, text string) error {
|
||||
body, _ := json.Marshal(map[string]string{
|
||||
"chat_id": chatID,
|
||||
"text": text[:min(len(text), 4000)],
|
||||
"text": truncateUTF8(text, 4000),
|
||||
"parse_mode": "HTML",
|
||||
})
|
||||
url := fmt.Sprintf(ch.apiURL+"sendMessage", ch.token)
|
||||
@@ -155,10 +156,10 @@ func (ch *Channel) getUpdates(ctx context.Context, offset int64, timeout int) ([
|
||||
// formatOutgoing собирает Message в HTML-строку: текст + нумерованные Options.
|
||||
func formatOutgoing(m chat.Message) string {
|
||||
if len(m.Options) == 0 {
|
||||
return m.Text
|
||||
return escapeHTML(m.Text)
|
||||
}
|
||||
var buf bytes.Buffer
|
||||
buf.WriteString(m.Text)
|
||||
buf.WriteString(escapeHTML(m.Text))
|
||||
buf.WriteString("\n\n")
|
||||
for i, opt := range m.Options {
|
||||
buf.WriteString(fmt.Sprintf("<b>%d.</b> %s\n", i+1, escapeHTML(opt.Label)))
|
||||
@@ -183,6 +184,18 @@ func escapeHTML(s string) string {
|
||||
return buf.String()
|
||||
}
|
||||
|
||||
// truncateUTF8 обрезает s до max байт, не разрывая UTF-8 последовательности.
|
||||
func truncateUTF8(s string, max int) string {
|
||||
if len(s) <= max {
|
||||
return s
|
||||
}
|
||||
s = s[:max]
|
||||
for len(s) > 0 && !utf8.ValidString(s) {
|
||||
s = s[:len(s)-1]
|
||||
}
|
||||
return s
|
||||
}
|
||||
|
||||
// ---- Telegram API types ----
|
||||
|
||||
type tgResponse struct {
|
||||
@@ -202,4 +215,4 @@ type message struct {
|
||||
Chat struct {
|
||||
ID int64 `json:"id"`
|
||||
} `json:"chat"`
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user