mirror of
https://github.com/tiennm99/miti99bot.git
synced 2026-10-04 00:13:30 +00:00
Replying to another bot's message and running /alias answered with the list of kinds that can be saved, which blames the format of a message the bot was never shown — it may well have been a photo. Telegram strips the content of another bot's message, and the sender is not always marked as a bot: an anonymous or service-posted message arrives equally empty, so the existing bot check missed it. Judge on whether any content arrived instead. A reply with no content field at all, and a command that arrives with no reply attached, now both say what happened and end with the one action that works: forward the message into the chat and reply to your own copy. A reply that did arrive with content of a refused kind — a poll, a location — still gets the list of supported kinds. One contentFields table backs both the check and the alias_capture debug line, so the log line always explains the refusal the caller was given.
77 lines
2.5 KiB
Go
77 lines
2.5 KiB
Go
package alias
|
|
|
|
import (
|
|
"strings"
|
|
|
|
"github.com/go-telegram/bot/models"
|
|
)
|
|
|
|
// replyShape describes what /alias was handed, for the debug log.
|
|
//
|
|
// Enable with LOG_LEVEL=debug; silent otherwise. It exists because the failures
|
|
// worth debugging here are all about what Telegram *did not* deliver: a reply
|
|
// stripped of its content (another bot's message), a caption where text was
|
|
// expected, or a kind that falls through capture's switch. Those are invisible
|
|
// from the user-facing refusal, which only says the message was unsupported.
|
|
//
|
|
// Deliberately reports shape, never content. Lengths and field names are
|
|
// enough to explain a capture failure, and message text in a log line would
|
|
// mean every aliased message ending up in stdout and whatever ships it.
|
|
func replyShape(replied *models.Message, entry Alias, ok bool) []any {
|
|
if replied == nil {
|
|
// The case that motivated this: Telegram can deliver /alias with no
|
|
// reply attached at all, which is indistinguishable from the caller
|
|
// forgetting to reply.
|
|
return []any{"reply", "absent"}
|
|
}
|
|
|
|
attrs := []any{
|
|
"reply", "present",
|
|
"reply_id", replied.ID,
|
|
"fields", strings.Join(populatedFields(replied), ","),
|
|
"text_len", len(replied.Text),
|
|
"caption_len", len(replied.Caption),
|
|
"entities", len(replied.Entities) + len(replied.CaptionEntities),
|
|
"captured", ok,
|
|
}
|
|
if ok {
|
|
attrs = append(attrs, "kind", entry.Kind)
|
|
}
|
|
if replied.From != nil {
|
|
attrs = append(attrs, "from_id", replied.From.ID, "from_bot", replied.From.IsBot)
|
|
} else {
|
|
// No sender at all — an anonymous channel post or a stripped reply.
|
|
attrs = append(attrs, "from", "absent")
|
|
}
|
|
if replied.SenderChat != nil {
|
|
attrs = append(attrs, "sender_chat", replied.SenderChat.ID)
|
|
}
|
|
return attrs
|
|
}
|
|
|
|
// populatedFields names the content fields the replied message actually has.
|
|
//
|
|
// Reads the same contentFields table hasContent tests, so the line always
|
|
// explains the refusal the caller was given. The two provenance markers are
|
|
// appended separately: they say where a message came from, not what it holds,
|
|
// and a reply carrying only those is still empty.
|
|
func populatedFields(m *models.Message) []string {
|
|
var out []string
|
|
for _, f := range contentFields {
|
|
if f.present(m) {
|
|
out = append(out, f.name)
|
|
}
|
|
}
|
|
if len(out) == 0 {
|
|
// The signature of a reply Telegram delivered but emptied.
|
|
out = append(out, "none")
|
|
}
|
|
if m.ViaBot != nil {
|
|
out = append(out, "via_bot")
|
|
}
|
|
if m.ForwardOrigin != nil {
|
|
out = append(out, "forward_origin")
|
|
}
|
|
return out
|
|
}
|