package telegram import ( "app/commons/core" "app/commons/i18n" "app/commons/services" "fmt" tgbotapi "github.com/go-telegram-bot-api/telegram-bot-api/v5" ) // sendTextMessage 发送文本消息 func sendTextMessage(chatID int64, text string) { if !IsEnabled() { return } msg := tgbotapi.NewMessage(chatID, text) msg.ParseMode = "Markdown" _, err := bot.Send(msg) if err != nil { core.Log.Errorf("发送消息失败: %v", err) } } // sendHTMLMessage 发送 HTML 格式的消息 func sendHTMLMessage(chatID int64, text string) { if !IsEnabled() { return } msg := tgbotapi.NewMessage(chatID, text) msg.ParseMode = "HTML" _, err := bot.Send(msg) if err != nil { core.Log.Errorf("发送消息失败: %v", err) } } // sendMessageWithKeyboard 发送带按钮的消息,返回 (messageID, error) func sendMessageWithKeyboard(chatID int64, text string, keyboard tgbotapi.InlineKeyboardMarkup) (int, error) { if !IsEnabled() { return 0, fmt.Errorf("bot未启用") } msg := tgbotapi.NewMessage(chatID, text) msg.ReplyMarkup = keyboard msg.ParseMode = "Markdown" result, err := bot.Send(msg) if err != nil { // 处理群组升级为超级群的情况 if tgErr, ok := err.(*tgbotapi.Error); ok && tgErr.Code == 400 && tgErr.ResponseParameters.MigrateToChatID != 0 { newChatID := tgErr.ResponseParameters.MigrateToChatID core.Log.Infof("群组已升级,自动重试: %d -> %d", chatID, newChatID) // 异步更新数据库中的群组ID go updateGroupChatID(chatID, newChatID) // 用新 ID 重发 msg.ChatID = newChatID result, err = bot.Send(msg) if err != nil { core.Log.Errorf("用新群组ID重发消息失败: %v", err) return 0, err } return result.MessageID, nil } core.Log.Errorf("发送消息失败: %v", err) return 0, err } return result.MessageID, nil } // editMessage 编辑消息(纯文本,避免用户名中 _ 等字符被 Markdown 解析出错) func editMessage(chatID int64, messageID int, text string) { if !IsEnabled() { return } edit := tgbotapi.NewEditMessageText(chatID, messageID, text) _, err := bot.Send(edit) if err != nil { core.Log.Errorf("编辑消息失败: %v", err) } } // editMessageWithKeyboard 编辑消息并保留按钮(纯文本) func editMessageWithKeyboard(chatID int64, messageID int, text string, keyboard tgbotapi.InlineKeyboardMarkup) { if !IsEnabled() { return } edit := tgbotapi.NewEditMessageTextAndMarkup(chatID, messageID, text, keyboard) _, err := bot.Send(edit) if err != nil { core.Log.Errorf("编辑消息失败: %v", err) } } // answerCallback 回复回调查询 func answerCallback(callbackID string, text string) { if !IsEnabled() { return } callback := tgbotapi.NewCallback(callbackID, text) callback.ShowAlert = false _, err := bot.Request(callback) if err != nil { core.Log.Errorf("回复回调失败: %v", err) } } // sendGroupWelcome 发送机器人加入群组欢迎消息(带按钮面板) func sendGroupWelcome(chatID int64) { text := "👋 大家好!我是红包机器人\n\n" + "🎉 功能介绍:\n" + "• 定期发放群组红包福利\n" + "• 支持普通红包和手气红包\n\n" + "📝 点击「一键注册」即可参与抢红包:" keyboard := buildWelcomeKeyboard() sendMessageWithKeyboard(chatID, text, keyboard) } // sendNewMemberWelcome 发送新成员欢迎消息(带按钮面板) func sendNewMemberWelcome(chatID int64, username, firstName string) { displayName := firstName if username != "" { displayName = "@" + username } text := fmt.Sprintf("👋 欢迎 %s 加入群组!\n\n"+ "🧧 本群定期发放红包福利!\n\n"+ "📝 点击下方「一键注册」即可参与抢红包:", displayName) keyboard := buildWelcomeKeyboard() sendMessageWithKeyboard(chatID, text, keyboard) } // SendRedPacketToGroup 发送红包消息到群组(供外部调用),返回 Telegram 消息ID func SendRedPacketToGroup(groupID string, packetNo string, senderName string, totalAmount float64, totalCount int, packetType int, blessingWords string, expireMinutes int, lang string, symbol string) int { if !IsEnabled() { core.Log.Warn("Telegram Bot 未启用,无法发送红包消息") return 0 } if symbol == "" { symbol = i18n.DefaultSymbol(lang) } m := i18n.GetLang(lang) packetTypeText := i18n.PacketTypeText(packetType, lang) expireText := i18n.FormatExpireTime(expireMinutes, lang) countStr := fmt.Sprintf("%d %s", totalCount, m.CountUnit) if m.CountUnit == "" { countStr = fmt.Sprintf("%d", totalCount) } text := fmt.Sprintf("%s\n💰 %s\n\n%s: %.2f %s\n%s: %s\n%s: %s\n⏰ %s: %s\n\n%s", fmt.Sprintf(m.SendRedPacket, senderName), blessingWords, m.TotalAmount, totalAmount, symbol, m.Count, countStr, m.Type, packetTypeText, m.ValidFor, expireText, m.ComeGrab) // 创建抢红包按钮 keyboard := tgbotapi.NewInlineKeyboardMarkup( tgbotapi.NewInlineKeyboardRow( tgbotapi.NewInlineKeyboardButtonData( m.GrabButton, fmt.Sprintf("grab_%s", packetNo), ), ), ) // 解析群组 ID(字符串转 int64) var chatID int64 fmt.Sscanf(groupID, "%d", &chatID) msgId, _ := sendMessageWithKeyboard(chatID, text, keyboard) return msgId } // PreviewRedPacketToGroup 发送红包预览消息到群组(供外部调用) func PreviewRedPacketToGroup(groupID string, senderName string, totalAmount float64, totalCount int, packetType int, blessingWords string, symbol string) { if !IsEnabled() { core.Log.Warn("Telegram Bot 未启用,无法发送预览消息") return } if symbol == "" { symbol = "VND" } var packetTypeText string if packetType == 1 { packetTypeText = "普通红包" } else { packetTypeText = "手气红包" } text := fmt.Sprintf(`🔍 【预览模式】红包预览 🧧 %s 发了一个红包 💰 %s 总金额: %.2f %s 个数: %d 个 类型: %s ⚠️ 这是预览消息,不是真实红包 实际发送时才能抢红包`, senderName, blessingWords, totalAmount, symbol, totalCount, packetTypeText) // 解析群组 ID(字符串转 int64) var chatID int64 fmt.Sscanf(groupID, "%d", &chatID) sendTextMessage(chatID, text) } // EditExpiredMessage 编辑过期红包消息(导出供 service 调用,移除按钮) func EditExpiredMessage(chatID int64, messageID int, text string) { editMessage(chatID, messageID, text) } // updateGroupChatID 群组升级后更新数据库中的 chat_id func updateGroupChatID(oldChatID, newChatID int64) { db := services.NewComService().DB() if db == nil { return } // 将旧群组记录标记为无效 db.Table("magic_tg_group"). Where("chat_id = ?", fmt.Sprintf("%d", oldChatID)). Updates(map[string]interface{}{"status": 0}) core.Log.Infof("群组升级: 旧ID %d 已标记无效, 新ID %d", oldChatID, newChatID) }