diff --git a/internal/wechat/voice.go b/internal/wechat/voice.go new file mode 100644 index 0000000..d3f6563 --- /dev/null +++ b/internal/wechat/voice.go @@ -0,0 +1,26 @@ +package wechat + +import "encoding/xml" + +// VoiceMessage +// @description: 语音消息 +type VoiceMessage struct { + XMLName xml.Name `xml:"msg"` + Text string `xml:",chardata"` + VoiceMsg struct { + Text string `xml:",chardata"` + Endflag string `xml:"endflag,attr"` + Cancelflag string `xml:"cancelflag,attr"` + Forwardflag string `xml:"forwardflag,attr"` + Voiceformat string `xml:"voiceformat,attr"` + Voicelength string `xml:"voicelength,attr"` + Length string `xml:"length,attr"` + Bufid string `xml:"bufid,attr"` + Aeskey string `xml:"aeskey,attr"` + VoiceUrl string `xml:"voiceurl,attr"` + Voicemd5 string `xml:"voicemd5,attr"` + Clientmsgid string `xml:"clientmsgid,attr"` + Fromusername string `xml:"fromusername,attr"` + } `xml:"voicemsg"` + //Extcommoninfo string `xml:"extcommoninfo"` +} diff --git a/pkg/message/handler.go b/pkg/message/handler.go index 623fa69..2cf58c7 100644 --- a/pkg/message/handler.go +++ b/pkg/message/handler.go @@ -18,6 +18,9 @@ func Handler(msg *model.Message, client *xybot.Client) { case types.MsgTypeEmoticon: // 表情包消息 handlerEmoticon(msg, client) + case types.MsgTypeVoice: + // 语音消息 + handlerVoice(msg, client) } } diff --git a/pkg/message/vioce.go b/pkg/message/vioce.go new file mode 100644 index 0000000..a743dd5 --- /dev/null +++ b/pkg/message/vioce.go @@ -0,0 +1,54 @@ +package message + +import ( + "encoding/xml" + "gitee.ltd/lxh/wechat-robot/internal/minio" + "gitee.ltd/lxh/wechat-robot/internal/model" + "gitee.ltd/lxh/wechat-robot/internal/wechat" + "gitee.ltd/lxh/xybot" + "github.com/gofiber/fiber/v2/log" + "strconv" +) + +// handlerVoice +// @description: 处理语音消息 +// @param msg +// @param client +func handlerVoice(msg *model.Message, client *xybot.Client) { + var err error + + // 解析消息xml + var voice wechat.VoiceMessage + if err = xml.Unmarshal([]byte(msg.Content), &voice); err != nil { + log.Errorf("%v解析消息失败: %v", msg.Type, err.Error()) + return + } + + // 将音频长度转换成数字类型 + length, _ := strconv.Atoi(voice.VoiceMsg.Length) + if length == 0 { + log.Debugf("音频长度为0,无法下载") + return + } + + // 取出关键数据,然后下载 + var voiceSilkStr string + if voiceSilkStr, err = client.Tool.DownloadVoice(msg.ClientMsgId, voice.VoiceMsg.VoiceUrl, length); err != nil { + log.Errorf("下载语音失败: %v", err.Error()) + return + } + + // TODO 将这个base64转换成wav + + // 保存文件到OSS,后缀为.aud,后续转换之后可以存wav之类的 + msg.FileUrl, err = minio.SaveBase64(voiceSilkStr, "", "aud") + if err != nil { + log.Errorf("文件保存到Minio失败: %s", err.Error()) + return + } + // 更新数据库 + if err = model.GetDB().Model(&msg).Where("id = ?", msg.ID).Update("file_url", msg.FileUrl).Error; err != nil { + log.Errorf("更新数据库失败: %s", err.Error()) + return + } +}