tg/message.go

160 lines
3.7 KiB
Go
Raw Normal View History

package tg
import (
tgbotapi "github.com/go-telegram-bot-api/telegram-bot-api/v5"
2023-10-02 21:45:21 +03:00
//"strings"
re "regexp"
2023-12-12 19:32:30 +03:00
"fmt"
)
2023-09-30 09:55:45 +03:00
type Message = tgbotapi.Message
// Simple text message component type.
type MessageCompo struct {
2024-03-29 14:30:48 +03:00
// 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
2024-03-29 14:30:48 +03:00
// 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
}
2024-03-29 14:30:48 +03:00
compo.Message = &msg
return nil
}
2024-03-29 14:30:48 +03:00
// 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)
2024-03-29 14:30:48 +03:00
if err != nil {
return err
}
2023-12-12 23:47:32 +03:00
2024-03-29 14:30:48 +03:00
// Empty the message if success.
compo.Message = nil
return nil
}
2024-03-29 14:30:48 +03:00
// Return new message with the specified text
// formatted with the fmt.Sprintf function.
func Messagef(format string, v ...any) *MessageCompo {
ret := &MessageCompo{}
2023-12-12 19:32:30 +03:00
ret.Text = fmt.Sprintf(format, v...)
ret.ParseMode = tgbotapi.ModeMarkdown
return ret
}
// Return message with the specified parse mode.
2024-03-29 14:30:48 +03:00
func (compo *MessageCompo) setParseMode(mode string) *MessageCompo {
compo.ParseMode = mode
return compo
}
// Set the default Markdown parsing mode.
2024-03-29 14:30:48 +03:00
func (compo *MessageCompo) MD() *MessageCompo {
return compo.setParseMode(tgbotapi.ModeMarkdown)
}
// Set the Markdown 2 parsing mode.
2024-03-29 14:30:48 +03:00
func (compo *MessageCompo) MD2() *MessageCompo {
return compo.setParseMode(tgbotapi.ModeMarkdownV2)
}
// Set the HTML parsing mode.
2024-03-29 14:30:48 +03:00
func (compo *MessageCompo) HTML() *MessageCompo {
return compo.setParseMode(tgbotapi.ModeHTML)
}
// Transform the message component into one with reply keyboard.
2024-03-29 14:30:48 +03:00
func (compo *MessageCompo) Inline(inline Inline) *InlineCompo {
return &InlineCompo{
Inline: inline,
2024-03-29 14:30:48 +03:00
MessageCompo: *compo,
}
}
// Transform the message component into one with reply keyboard.
2024-03-29 14:30:48 +03:00
func (msg *MessageCompo) Reply(reply Reply) *ReplyCompo {
return &ReplyCompo{
Reply: reply,
2024-03-29 14:30:48 +03:00
MessageCompo: *msg,
}
}
// Transform the message component into the location one.
2024-03-29 14:30:48 +03:00
func (msg *MessageCompo) Location(
lat, long float64,
2024-03-29 14:30:48 +03:00
) *LocationCompo {
ret := &LocationCompo{}
ret.MessageCompo = *msg
ret.Latitude = lat
ret.Longitude = long
return ret
}
// Implementing the Sendable interface.
2024-03-29 14:30:48 +03:00
func (compo *MessageCompo) SendConfig(
sid SessionID, bot *Bot,
) (SendConfig) {
var (
ret SendConfig
text string
)
2024-03-29 14:30:48 +03:00
// Protection against empty text,
// since it breaks the Telegram bot API.
if compo.Text == "" {
text = ">"
} else {
2024-03-29 14:30:48 +03:00
text = compo.Text
}
msg := tgbotapi.NewMessage(sid.ToAPI(), text)
2024-03-29 14:30:48 +03:00
msg.ParseMode = compo.ParseMode
ret.Chattable = msg
return ret
}
2024-03-29 14:30:48 +03:00
// 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
}