message.go 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159
  1. package tg
  2. import (
  3. tgbotapi "github.com/go-telegram-bot-api/telegram-bot-api/v5"
  4. //"strings"
  5. re "regexp"
  6. "fmt"
  7. )
  8. type Message = tgbotapi.Message
  9. // Simple text message component type.
  10. type MessageCompo struct {
  11. // Low level Message represents
  12. // the already sent to the client message.
  13. // Will be nil if the message is not rendered to the client.
  14. Message *Message
  15. // Parsing mode for the text: HTML, MD, MD2...
  16. ParseMode string
  17. // The text to display.
  18. Text string
  19. }
  20. var (
  21. escapeRe = re.MustCompile(`([_*\[\]()~`+"`"+`>#+-=|{}.!])`)
  22. NewRawMessage = tgbotapi.NewMessage
  23. )
  24. // Escape special characters in Markdown 2 and return the
  25. // resulting string.
  26. func Escape2(str string) string {
  27. return string(escapeRe.ReplaceAll([]byte(str), []byte("\\$1")))
  28. }
  29. // Call the function after the message was sent.
  30. func (compo *MessageCompo) Update(c Context) error {
  31. edit := tgbotapi.NewEditMessageText(
  32. c.Session().ID.ToAPI(),
  33. compo.Message.MessageID,
  34. compo.Text,
  35. )
  36. msg, err := c.Bot().API().Send(edit)
  37. if err != nil {
  38. return err
  39. }
  40. compo.Message = &msg
  41. return nil
  42. }
  43. // Calling the method removes the message on the client side
  44. // and sets the Message in the component to nil.
  45. func (compo *MessageCompo) Delete(c Context) error {
  46. cfg := tgbotapi.NewDeleteMessage(c.session.ID.ToAPI(), compo.Message.MessageID)
  47. _, err := c.Bot().API().Send(cfg)
  48. if err != nil {
  49. return err
  50. }
  51. // Empty the message if success.
  52. compo.Message = nil
  53. return nil
  54. }
  55. // Return new message with the specified text
  56. // formatted with the fmt.Sprintf function.
  57. func Messagef(format string, v ...any) *MessageCompo {
  58. ret := &MessageCompo{}
  59. ret.Text = fmt.Sprintf(format, v...)
  60. ret.ParseMode = tgbotapi.ModeMarkdown
  61. return ret
  62. }
  63. // Return message with the specified parse mode.
  64. func (compo *MessageCompo) setParseMode(mode string) *MessageCompo {
  65. compo.ParseMode = mode
  66. return compo
  67. }
  68. // Set the default Markdown parsing mode.
  69. func (compo *MessageCompo) MD() *MessageCompo {
  70. return compo.setParseMode(tgbotapi.ModeMarkdown)
  71. }
  72. // Set the Markdown 2 parsing mode.
  73. func (compo *MessageCompo) MD2() *MessageCompo {
  74. return compo.setParseMode(tgbotapi.ModeMarkdownV2)
  75. }
  76. // Set the HTML parsing mode.
  77. func (compo *MessageCompo) HTML() *MessageCompo {
  78. return compo.setParseMode(tgbotapi.ModeHTML)
  79. }
  80. // Transform the message component into one with reply keyboard.
  81. func (compo *MessageCompo) Inline(inline Inline) *InlineCompo {
  82. return &InlineCompo{
  83. Inline: inline,
  84. MessageCompo: *compo,
  85. }
  86. }
  87. // Transform the message component into one with reply keyboard.
  88. func (msg *MessageCompo) Reply(reply Reply) *ReplyCompo {
  89. return &ReplyCompo{
  90. Reply: reply,
  91. MessageCompo: *msg,
  92. }
  93. }
  94. // Transform the message component into the location one.
  95. func (msg *MessageCompo) Location(
  96. lat, long float64,
  97. ) *LocationCompo {
  98. ret := &LocationCompo{}
  99. ret.MessageCompo = *msg
  100. ret.Latitude = lat
  101. ret.Longitude = long
  102. return ret
  103. }
  104. // Implementing the Sendable interface.
  105. func (compo *MessageCompo) SendConfig(
  106. sid SessionID, bot *Bot,
  107. ) (SendConfig) {
  108. var (
  109. ret SendConfig
  110. text string
  111. )
  112. // Protection against empty text,
  113. // since it breaks the Telegram bot API.
  114. if compo.Text == "" {
  115. text = ">"
  116. } else {
  117. text = compo.Text
  118. }
  119. msg := tgbotapi.NewMessage(sid.ToAPI(), text)
  120. msg.ParseMode = compo.ParseMode
  121. ret.Chattable = msg
  122. return ret
  123. }
  124. // Implementing the Sendable interface.
  125. // Also used for embedding for things like InlineCompo etc.
  126. func (compo *MessageCompo) SetMessage(msg *Message) {
  127. compo.Message = msg
  128. }
  129. // Empty serving to use messages in rendering.
  130. func (compo *MessageCompo) Serve(c Context) {}
  131. // Filter that skips everything. Messages cannot do anything with updates.
  132. func (compo *MessageCompo) Filter(_ Update) bool {
  133. // Skip everything
  134. return true
  135. }