Answering
Answer
msg.Answer is the one you want almost always:
return msg.Answer("🌤 <b>Sunny</b>, 22°C")It edits your own message when the command was yours, and replies when someone else invoked it. That is the userbot convention — your .weather turns into the result rather than adding a second message.
Reply and Edit
When you need the specific behaviour:
return msg.Reply("a new message in the chat")
return msg.Edit("replace this message's text")Formatting
Text is parsed as Telegram HTML:
msg.Answer("<b>bold</b> <i>italic</i> <code>mono</code>")
msg.Answer("<a href=\"https://goroku.dev\">link</a>")
msg.Answer("<blockquote>quoted</blockquote>")Supported tags: b, strong, i, em, u, s, del, code, pre, a, blockquote, tg-spoiler, and tg-emoji for premium emoji.
Escape anything from a user
Interpolating user text straight into HTML breaks the message when it contains < or &.
import "goroku/goroku/utils"
return msg.Answer("You said: <code>" + utils.EscapeHTML(input) + "</code>")Options
msg.Answer("no link preview", goroku.WithNoWebpage(true))
msg.Answer("in a forum topic", goroku.WithReplyTo(topicID))| Option | Effect |
|---|---|
WithNoWebpage(bool) | Suppress the link preview |
WithReplyTo(int64) | Reply to a message, or post into a forum topic |
WithInvertMedia(bool) | Put the preview above the text |
WithWebPageMedia(url, optional, forceLarge) | Force a specific preview |
Long output
Telegram caps a message around 4096 characters. Send long results as a file:
import (
"bytes"
"goroku/goroku"
)
func (m *Mod) DumpCmd(msg *goroku.Message) error {
report := m.buildLongReport()
if len(report) < 3500 {
return msg.Answer("<pre>" + report + "</pre>")
}
_, err := m.Client.SendFile(
goroku.ChatRefID(msg.ChatID),
bytes.NewReader([]byte(report)),
"📄 Full report",
)
return err
}Progress on slow work
Answer immediately, then edit as you go:
func (m *Mod) SlowCmd(msg *goroku.Message) error {
if err := msg.Answer("⏳ <b>Working…</b>"); err != nil {
return err
}
result, err := m.doSlowThing(msg.Context())
if err != nil {
return err
}
return msg.Answer(result)
}Auto-answer
If a handler changes msg.Text and never calls Answer, the dispatcher sends the new text for you. Explicit is clearer, but this is why some built-in modules end by assigning to msg.Text.