messages.go 6.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249
  1. package telegram
  2. import (
  3. "app/commons/core"
  4. "app/commons/services"
  5. "fmt"
  6. tgbotapi "github.com/go-telegram-bot-api/telegram-bot-api/v5"
  7. )
  8. // sendTextMessage 发送文本消息
  9. func sendTextMessage(chatID int64, text string) {
  10. if !IsEnabled() {
  11. return
  12. }
  13. msg := tgbotapi.NewMessage(chatID, text)
  14. msg.ParseMode = "Markdown"
  15. _, err := bot.Send(msg)
  16. if err != nil {
  17. core.Log.Errorf("发送消息失败: %v", err)
  18. }
  19. }
  20. // sendHTMLMessage 发送 HTML 格式的消息
  21. func sendHTMLMessage(chatID int64, text string) {
  22. if !IsEnabled() {
  23. return
  24. }
  25. msg := tgbotapi.NewMessage(chatID, text)
  26. msg.ParseMode = "HTML"
  27. _, err := bot.Send(msg)
  28. if err != nil {
  29. core.Log.Errorf("发送消息失败: %v", err)
  30. }
  31. }
  32. // sendMessageWithKeyboard 发送带按钮的消息
  33. func sendMessageWithKeyboard(chatID int64, text string, keyboard tgbotapi.InlineKeyboardMarkup) error {
  34. if !IsEnabled() {
  35. return fmt.Errorf("bot未启用")
  36. }
  37. msg := tgbotapi.NewMessage(chatID, text)
  38. msg.ReplyMarkup = keyboard
  39. msg.ParseMode = "Markdown"
  40. _, err := bot.Send(msg)
  41. if err != nil {
  42. // 处理群组升级为超级群的情况
  43. if tgErr, ok := err.(*tgbotapi.Error); ok && tgErr.Code == 400 && tgErr.ResponseParameters.MigrateToChatID != 0 {
  44. newChatID := tgErr.ResponseParameters.MigrateToChatID
  45. core.Log.Infof("群组已升级,自动重试: %d -> %d", chatID, newChatID)
  46. // 异步更新数据库中的群组ID
  47. go updateGroupChatID(chatID, newChatID)
  48. // 用新 ID 重发
  49. msg.ChatID = newChatID
  50. _, err = bot.Send(msg)
  51. if err != nil {
  52. core.Log.Errorf("用新群组ID重发消息失败: %v", err)
  53. }
  54. return err
  55. }
  56. core.Log.Errorf("发送消息失败: %v", err)
  57. }
  58. return err
  59. }
  60. // editMessage 编辑消息(纯文本,避免用户名中 _ 等字符被 Markdown 解析出错)
  61. func editMessage(chatID int64, messageID int, text string) {
  62. if !IsEnabled() {
  63. return
  64. }
  65. edit := tgbotapi.NewEditMessageText(chatID, messageID, text)
  66. _, err := bot.Send(edit)
  67. if err != nil {
  68. core.Log.Errorf("编辑消息失败: %v", err)
  69. }
  70. }
  71. // editMessageWithKeyboard 编辑消息并保留按钮(纯文本)
  72. func editMessageWithKeyboard(chatID int64, messageID int, text string, keyboard tgbotapi.InlineKeyboardMarkup) {
  73. if !IsEnabled() {
  74. return
  75. }
  76. edit := tgbotapi.NewEditMessageTextAndMarkup(chatID, messageID, text, keyboard)
  77. _, err := bot.Send(edit)
  78. if err != nil {
  79. core.Log.Errorf("编辑消息失败: %v", err)
  80. }
  81. }
  82. // answerCallback 回复回调查询
  83. func answerCallback(callbackID string, text string) {
  84. if !IsEnabled() {
  85. return
  86. }
  87. callback := tgbotapi.NewCallback(callbackID, text)
  88. callback.ShowAlert = false
  89. _, err := bot.Request(callback)
  90. if err != nil {
  91. core.Log.Errorf("回复回调失败: %v", err)
  92. }
  93. }
  94. // sendGroupWelcome 发送机器人加入群组欢迎消息
  95. func sendGroupWelcome(chatID int64) {
  96. text := `👋 大家好!我是红包机器人
  97. 🎉 功能介绍:
  98. • 定期发放群组红包福利
  99. • 支持普通红包和手气红包
  100. 📝 使用方法:
  101. 1. 前往平台注册账户
  102. 2. 私聊我发送 /bind 绑定账户
  103. 3. 绑定后即可抢群内红包
  104. ⚠️ 未绑定账户无法抢红包
  105. 💡 使用 /help 查看详细帮助`
  106. sendTextMessage(chatID, text)
  107. }
  108. // sendNewMemberWelcome 发送新成员欢迎消息
  109. func sendNewMemberWelcome(chatID int64, username, firstName string) {
  110. displayName := firstName
  111. if username != "" {
  112. displayName = "@" + username
  113. }
  114. text := fmt.Sprintf(`👋 欢迎 %s 加入群组!
  115. 🧧 本群定期发放红包福利!
  116. 📝 快速开始:
  117. 1. 前往平台注册账户
  118. 2. 私聊我发送 /bind 绑定账户
  119. 3. 绑定后即可抢红包
  120. ⚠️ 未绑定账户无法抢红包`, displayName)
  121. sendTextMessage(chatID, text)
  122. }
  123. // SendRedPacketToGroup 发送红包消息到群组(供外部调用)
  124. func SendRedPacketToGroup(groupID string, packetNo string, senderName string, totalAmount float64, totalCount int, packetType int, blessingWords string) {
  125. if !IsEnabled() {
  126. core.Log.Warn("Telegram Bot 未启用,无法发送红包消息")
  127. return
  128. }
  129. var packetTypeText string
  130. if packetType == 1 {
  131. packetTypeText = "普通红包"
  132. } else {
  133. packetTypeText = "手气红包"
  134. }
  135. text := fmt.Sprintf(`🧧 %s 发了一个红包
  136. 💰 %s
  137. 总金额: %.2f VND
  138. 个数: %d 个
  139. 类型: %s
  140. 快来抢红包吧!`,
  141. senderName,
  142. blessingWords,
  143. totalAmount,
  144. totalCount,
  145. packetTypeText)
  146. // 创建抢红包按钮
  147. keyboard := tgbotapi.NewInlineKeyboardMarkup(
  148. tgbotapi.NewInlineKeyboardRow(
  149. tgbotapi.NewInlineKeyboardButtonData(
  150. "🎁 抢红包",
  151. fmt.Sprintf("grab_%s", packetNo),
  152. ),
  153. ),
  154. )
  155. // 解析群组 ID(字符串转 int64)
  156. var chatID int64
  157. fmt.Sscanf(groupID, "%d", &chatID)
  158. sendMessageWithKeyboard(chatID, text, keyboard)
  159. }
  160. // PreviewRedPacketToGroup 发送红包预览消息到群组(供外部调用)
  161. func PreviewRedPacketToGroup(groupID string, senderName string, totalAmount float64, totalCount int, packetType int, blessingWords string) {
  162. if !IsEnabled() {
  163. core.Log.Warn("Telegram Bot 未启用,无法发送预览消息")
  164. return
  165. }
  166. var packetTypeText string
  167. if packetType == 1 {
  168. packetTypeText = "普通红包"
  169. } else {
  170. packetTypeText = "手气红包"
  171. }
  172. text := fmt.Sprintf(`🔍 【预览模式】红包预览
  173. 🧧 %s 发了一个红包
  174. 💰 %s
  175. 总金额: %.2f VND
  176. 个数: %d 个
  177. 类型: %s
  178. ⚠️ 这是预览消息,不是真实红包
  179. 实际发送时才能抢红包`,
  180. senderName,
  181. blessingWords,
  182. totalAmount,
  183. totalCount,
  184. packetTypeText)
  185. // 解析群组 ID(字符串转 int64)
  186. var chatID int64
  187. fmt.Sscanf(groupID, "%d", &chatID)
  188. sendTextMessage(chatID, text)
  189. }
  190. // updateGroupChatID 群组升级后更新数据库中的 chat_id
  191. func updateGroupChatID(oldChatID, newChatID int64) {
  192. db := services.NewComService().DB()
  193. if db == nil {
  194. return
  195. }
  196. // 将旧群组记录标记为无效
  197. db.Table("magic_tg_group").
  198. Where("chat_id = ?", fmt.Sprintf("%d", oldChatID)).
  199. Updates(map[string]interface{}{"status": 0})
  200. core.Log.Infof("群组升级: 旧ID %d 已标记无效, 新ID %d", oldChatID, newChatID)
  201. }