| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249 |
- 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)
- }
|