2023-09-08 17:37:32 +03:00
|
|
|
package tg
|
|
|
|
|
|
|
|
import (
|
|
|
|
tgbotapi "github.com/go-telegram-bot-api/telegram-bot-api/v5"
|
2023-10-02 21:45:21 +03:00
|
|
|
//"strings"
|
2023-10-05 17:51:24 +03:00
|
|
|
re "regexp"
|
2023-12-12 19:32:30 +03:00
|
|
|
"fmt"
|
2023-09-08 17:37:32 +03:00
|
|
|
)
|
2023-09-30 09:55:45 +03:00
|
|
|
type Message = tgbotapi.Message
|
2023-09-08 17:37:32 +03:00
|
|
|
|
2023-10-07 13:20:49 +03:00
|
|
|
// Simple text message component type.
|
2023-09-29 13:36:37 +03:00
|
|
|
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...
|
2023-09-20 22:48:35 +03:00
|
|
|
ParseMode string
|
2024-03-29 14:30:48 +03:00
|
|
|
// The text to display.
|
2023-09-08 17:37:32 +03:00
|
|
|
Text string
|
|
|
|
}
|
|
|
|
|
2023-10-05 17:51:24 +03:00
|
|
|
var (
|
|
|
|
escapeRe = re.MustCompile(`([_*\[\]()~`+"`"+`>#+-=|{}.!])`)
|
2023-10-07 13:20:49 +03:00
|
|
|
NewRawMessage = tgbotapi.NewMessage
|
2023-10-05 17:51:24 +03:00
|
|
|
)
|
|
|
|
|
|
|
|
// Escape special characters in Markdown 2 and return the
|
|
|
|
// resulting string.
|
|
|
|
func Escape2(str string) string {
|
|
|
|
return string(escapeRe.ReplaceAll([]byte(str), []byte("\\$1")))
|
|
|
|
}
|
|
|
|
|
2024-03-28 10:41:09 +03:00
|
|
|
// Call the function after the message was sent.
|
|
|
|
func (compo *MessageCompo) Update(c Context) error {
|
2023-10-13 23:27:20 +03:00
|
|
|
edit := tgbotapi.NewEditMessageText(
|
2024-03-29 14:30:48 +03:00
|
|
|
c.Session().Id.ToApi(),
|
2023-10-13 23:27:20 +03:00
|
|
|
compo.Message.MessageID,
|
|
|
|
compo.Text,
|
|
|
|
)
|
2024-03-29 14:30:48 +03:00
|
|
|
msg, err := c.Bot().Api().Send(edit)
|
2024-03-28 10:41:09 +03:00
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
2024-03-29 14:30:48 +03:00
|
|
|
compo.Message = &msg
|
2024-03-28 10:41:09 +03:00
|
|
|
return nil
|
2023-10-13 23:27:20 +03:00
|
|
|
}
|
|
|
|
|
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)
|
|
|
|
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
|
2023-09-29 13:36:37 +03:00
|
|
|
}
|
|
|
|
|
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...)
|
2023-09-20 22:48:35 +03:00
|
|
|
ret.ParseMode = tgbotapi.ModeMarkdown
|
2023-09-08 17:37:32 +03:00
|
|
|
return ret
|
|
|
|
}
|
|
|
|
|
2023-10-07 13:20:49 +03:00
|
|
|
// 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
|
2023-09-20 22:48:35 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
// Set the default Markdown parsing mode.
|
2024-03-29 14:30:48 +03:00
|
|
|
func (compo *MessageCompo) MD() *MessageCompo {
|
|
|
|
return compo.setParseMode(tgbotapi.ModeMarkdown)
|
2023-09-20 22:48:35 +03:00
|
|
|
}
|
|
|
|
|
2023-09-29 13:36:37 +03:00
|
|
|
// Set the Markdown 2 parsing mode.
|
2024-03-29 14:30:48 +03:00
|
|
|
func (compo *MessageCompo) MD2() *MessageCompo {
|
|
|
|
return compo.setParseMode(tgbotapi.ModeMarkdownV2)
|
2023-09-20 22:48:35 +03:00
|
|
|
}
|
|
|
|
|
2023-09-29 13:36:37 +03:00
|
|
|
// Set the HTML parsing mode.
|
2024-03-29 14:30:48 +03:00
|
|
|
func (compo *MessageCompo) HTML() *MessageCompo {
|
|
|
|
return compo.setParseMode(tgbotapi.ModeHTML)
|
2023-09-20 22:48:35 +03:00
|
|
|
}
|
|
|
|
|
2023-09-29 13:36:37 +03:00
|
|
|
// 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{
|
2023-09-29 13:36:37 +03:00
|
|
|
Inline: inline,
|
2024-03-29 14:30:48 +03:00
|
|
|
MessageCompo: *compo,
|
2023-09-29 13:36:37 +03:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// 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{
|
2023-09-29 13:36:37 +03:00
|
|
|
Reply: reply,
|
2024-03-29 14:30:48 +03:00
|
|
|
MessageCompo: *msg,
|
2023-09-29 13:36:37 +03:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-10-11 14:20:25 +03:00
|
|
|
// Transform the message component into the location one.
|
2024-03-29 14:30:48 +03:00
|
|
|
func (msg *MessageCompo) Location(
|
2023-10-11 14:20:25 +03:00
|
|
|
lat, long float64,
|
2024-03-29 14:30:48 +03:00
|
|
|
) *LocationCompo {
|
|
|
|
ret := &LocationCompo{}
|
|
|
|
ret.MessageCompo = *msg
|
|
|
|
ret.Latitude = lat
|
|
|
|
ret.Longitude = long
|
|
|
|
|
2023-10-11 14:20:25 +03:00
|
|
|
return ret
|
|
|
|
}
|
|
|
|
|
|
|
|
// Implementing the Sendable interface.
|
2024-03-29 14:30:48 +03:00
|
|
|
func (compo *MessageCompo) SendConfig(
|
2023-10-10 12:42:05 +03:00
|
|
|
sid SessionId, bot *Bot,
|
2024-03-28 10:41:09 +03:00
|
|
|
) (SendConfig) {
|
2023-09-29 13:36:37 +03:00
|
|
|
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 == "" {
|
2023-09-29 13:36:37 +03:00
|
|
|
text = ">"
|
|
|
|
} else {
|
2024-03-29 14:30:48 +03:00
|
|
|
text = compo.Text
|
2023-09-29 13:36:37 +03:00
|
|
|
}
|
|
|
|
|
2023-10-10 12:42:05 +03:00
|
|
|
msg := tgbotapi.NewMessage(sid.ToApi(), text)
|
2024-03-29 14:30:48 +03:00
|
|
|
msg.ParseMode = compo.ParseMode
|
2024-03-28 10:41:09 +03:00
|
|
|
ret.Chattable = msg
|
2023-09-29 13:36:37 +03:00
|
|
|
|
2024-03-28 10:41:09 +03:00
|
|
|
return ret
|
2023-09-08 17:37:32 +03:00
|
|
|
}
|
2023-09-29 13:36:37 +03:00
|
|
|
|
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
|
|
|
|
}
|
|
|
|
|
2023-09-29 13:36:37 +03:00
|
|
|
// Empty serving to use messages in rendering.
|
2024-03-28 10:41:09 +03:00
|
|
|
func (compo *MessageCompo) Serve(c Context) {}
|
2023-09-29 13:36:37 +03:00
|
|
|
|
2023-10-07 13:20:49 +03:00
|
|
|
// Filter that skips everything. Messages cannot do anything with updates.
|
2024-03-28 10:41:09 +03:00
|
|
|
func (compo *MessageCompo) Filter(_ Update) bool {
|
2023-09-29 13:36:37 +03:00
|
|
|
// Skip everything
|
|
|
|
return true
|
|
|
|
}
|