package tg import ( tgbotapi "github.com/go-telegram-bot-api/telegram-bot-api/v5" //"strings" re "regexp" "fmt" ) type Message = tgbotapi.Message // Simple text message component type. type MessageCompo struct { // Low level Message represents // the already sent to the client message. // Will be nil if the message is not rendered to the client. Message *Message // Parsing mode for the text: HTML, MD, MD2... ParseMode string // The text to display. Text string } var ( escapeRe = re.MustCompile(`([_*\[\]()~`+"`"+`>#+-=|{}.!])`) NewRawMessage = tgbotapi.NewMessage ) // Escape special characters in Markdown 2 and return the // resulting string. func Escape2(str string) string { return string(escapeRe.ReplaceAll([]byte(str), []byte("\\$1"))) } // Call the function after the message was sent. func (compo *MessageCompo) Update(c Context) error { edit := tgbotapi.NewEditMessageText( c.Session().ID.ToAPI(), compo.Message.MessageID, compo.Text, ) msg, err := c.Bot().API().Send(edit) if err != nil { return err } compo.Message = &msg return nil } // Calling the method removes the message on the client side // and sets the Message in the component to nil. func (compo *MessageCompo) Delete(c Context) error { cfg := tgbotapi.NewDeleteMessage(c.session.ID.ToAPI(), compo.Message.MessageID) _, err := c.Bot().API().Send(cfg) if err != nil { return err } // Empty the message if success. compo.Message = nil return nil } // Return new message with the specified text // formatted with the fmt.Sprintf function. func Messagef(format string, v ...any) *MessageCompo { ret := &MessageCompo{} ret.Text = fmt.Sprintf(format, v...) ret.ParseMode = tgbotapi.ModeMarkdown return ret } // Return message with the specified parse mode. func (compo *MessageCompo) setParseMode(mode string) *MessageCompo { compo.ParseMode = mode return compo } // Set the default Markdown parsing mode. func (compo *MessageCompo) MD() *MessageCompo { return compo.setParseMode(tgbotapi.ModeMarkdown) } // Set the Markdown 2 parsing mode. func (compo *MessageCompo) MD2() *MessageCompo { return compo.setParseMode(tgbotapi.ModeMarkdownV2) } // Set the HTML parsing mode. func (compo *MessageCompo) HTML() *MessageCompo { return compo.setParseMode(tgbotapi.ModeHTML) } // Transform the message component into one with reply keyboard. func (compo *MessageCompo) Inline(inline Inline) *InlineCompo { return &InlineCompo{ Inline: inline, MessageCompo: *compo, } } // Transform the message component into one with reply keyboard. func (msg *MessageCompo) Reply(reply Reply) *ReplyCompo { return &ReplyCompo{ Reply: reply, MessageCompo: *msg, } } // Transform the message component into the location one. func (msg *MessageCompo) Location( lat, long float64, ) *LocationCompo { ret := &LocationCompo{} ret.MessageCompo = *msg ret.Latitude = lat ret.Longitude = long return ret } // Implementing the Sendable interface. func (compo *MessageCompo) SendConfig( sid SessionID, bot *Bot, ) (SendConfig) { var ( ret SendConfig text string ) // Protection against empty text, // since it breaks the Telegram bot API. if compo.Text == "" { text = ">" } else { text = compo.Text } msg := tgbotapi.NewMessage(sid.ToAPI(), text) msg.ParseMode = compo.ParseMode ret.Chattable = msg return ret } // Implementing the Sendable interface. // Also used for embedding for things like InlineCompo etc. func (compo *MessageCompo) SetMessage(msg *Message) { compo.Message = msg } // Empty serving to use messages in rendering. func (compo *MessageCompo) Serve(c Context) {} // Filter that skips everything. Messages cannot do anything with updates. func (compo *MessageCompo) Filter(_ Update) bool { // Skip everything return true }