fix(model): enhanced message parsing and display (#223)
This commit is contained in:
@@ -148,6 +148,7 @@ func (a *App) refresh() {
|
||||
a.infoBar.UpdateBasicInfo(a.ctx.PID, a.ctx.FullVersion, a.ctx.ExePath)
|
||||
a.infoBar.UpdateStatus(a.ctx.Status)
|
||||
a.infoBar.UpdateDataKey(a.ctx.DataKey)
|
||||
a.infoBar.UpdateImageKey(a.ctx.ImgKey)
|
||||
a.infoBar.UpdatePlatform(a.ctx.Platform)
|
||||
a.infoBar.UpdateDataUsageDir(a.ctx.DataUsage, a.ctx.DataDir)
|
||||
a.infoBar.UpdateWorkUsageDir(a.ctx.WorkUsage, a.ctx.WorkDir)
|
||||
@@ -201,14 +202,14 @@ func (a *App) inputCapture(event *tcell.EventKey) *tcell.EventKey {
|
||||
func (a *App) initMenu() {
|
||||
getDataKey := &menu.Item{
|
||||
Index: 2,
|
||||
Name: "获取数据密钥",
|
||||
Description: "从进程获取数据密钥",
|
||||
Name: "获取密钥",
|
||||
Description: "从进程获取数据密钥 & 图片密钥",
|
||||
Selected: func(i *menu.Item) {
|
||||
modal := tview.NewModal()
|
||||
if runtime.GOOS == "darwin" {
|
||||
modal.SetText("获取数据密钥中...\n预计需要 20 秒左右的时间,期间微信会卡住,请耐心等待")
|
||||
modal.SetText("获取密钥中...\n预计需要 20 秒左右的时间,期间微信会卡住,请耐心等待")
|
||||
} else {
|
||||
modal.SetText("获取数据密钥中...")
|
||||
modal.SetText("获取密钥中...")
|
||||
}
|
||||
a.mainPages.AddPage("modal", modal, true, true)
|
||||
a.SetFocus(modal)
|
||||
@@ -220,10 +221,10 @@ func (a *App) initMenu() {
|
||||
a.QueueUpdateDraw(func() {
|
||||
if err != nil {
|
||||
// 解密失败
|
||||
modal.SetText("获取数据密钥失败: " + err.Error())
|
||||
modal.SetText("获取密钥失败: " + err.Error())
|
||||
} else {
|
||||
// 解密成功
|
||||
modal.SetText("获取数据密钥成功")
|
||||
modal.SetText("获取密钥成功")
|
||||
}
|
||||
|
||||
// 添加确认按钮
|
||||
|
||||
+176
-10
@@ -8,10 +8,12 @@ import (
|
||||
)
|
||||
|
||||
type MediaMsg struct {
|
||||
XMLName xml.Name `xml:"msg"`
|
||||
Image Image `xml:"img,omitempty"`
|
||||
Video Video `xml:"videomsg,omitempty"`
|
||||
App App `xml:"appmsg,omitempty"`
|
||||
XMLName xml.Name `xml:"msg"`
|
||||
Image Image `xml:"img,omitempty"`
|
||||
Video Video `xml:"videomsg,omitempty"`
|
||||
App App `xml:"appmsg,omitempty"`
|
||||
Emoji Emoji `xml:"emoji,omitempty"`
|
||||
Location Location `xml:"location,omitempty"`
|
||||
}
|
||||
|
||||
type Image struct {
|
||||
@@ -70,9 +72,63 @@ type App struct {
|
||||
FinderFeed *FinderFeed `xml:"finderFeed,omitempty"` // type 51 视频号
|
||||
ReferMsg *ReferMsg `xml:"refermsg,omitempty"` // type 57 引用
|
||||
PatMsg *PatMsg `xml:"patMsg,omitempty"` // type 62 拍一拍
|
||||
PatInfo *PatInfo `xml:"patinfo,omitempty"` // type 62 拍一拍 v2
|
||||
FinderLive *FinderLive `xml:"finderLive,omitempty"` // type 63 视频号直播
|
||||
WCPayInfo *WCPayInfo `xml:"wcpayinfo,omitempty"` // type 2000 微信转账
|
||||
}
|
||||
|
||||
type Emoji struct {
|
||||
FromUsername string `xml:"fromusername,attr"`
|
||||
ToUsername string `xml:"tousername,attr"`
|
||||
Type string `xml:"type,attr"`
|
||||
IdBuffer string `xml:"idbuffer,attr"`
|
||||
Md5 string `xml:"md5,attr"`
|
||||
Len string `xml:"len,attr"`
|
||||
CdnURL string `xml:"cdnurl,attr"`
|
||||
AesKey string `xml:"aeskey,attr"`
|
||||
Width string `xml:"width,attr"`
|
||||
Height string `xml:"height,attr"`
|
||||
// ProductId string `xml:"productid,attr"`
|
||||
// AndroidMd5 string `xml:"androidmd5,attr"`
|
||||
// AndroidLen string `xml:"androidlen,attr"`
|
||||
// S60v3Md5 string `xml:"s60v3md5,attr"`
|
||||
// S60v3Len string `xml:"s60v3len,attr"`
|
||||
// S60v5Md5 string `xml:"s60v5md5,attr"`
|
||||
// S60v5Len string `xml:"s60v5len,attr"`
|
||||
// DesignerId string `xml:"designerid,attr"`
|
||||
// ThumbUrl string `xml:"thumburl,attr"`
|
||||
// EncryptUrl string `xml:"encrypturl,attr"`
|
||||
// ExternUrl string `xml:"externurl,attr"`
|
||||
// ExternMd5 string `xml:"externmd5,attr"`
|
||||
// TpUrl string `xml:"tpurl,attr"`
|
||||
// TpAuthKey string `xml:"tpauthkey,attr"`
|
||||
// AttachedText string `xml:"attachedtext,attr"`
|
||||
// AttachedTextColor string `xml:"attachedtextcolor,attr"`
|
||||
// LensId string `xml:"lensid,attr"`
|
||||
// EmojiAttr string `xml:"emojiattr,attr"`
|
||||
// LinkId string `xml:"linkid,attr"`
|
||||
// Desc string `xml:"desc,attr"`
|
||||
}
|
||||
|
||||
type Location struct {
|
||||
X string `xml:"x,attr"`
|
||||
Y string `xml:"y,attr"`
|
||||
Scale string `xml:"scale,attr"`
|
||||
Label string `xml:"label,attr"`
|
||||
MapType string `xml:"maptype,attr"`
|
||||
Adcode string `xml:"adcode,attr"`
|
||||
CityName string `xml:"cityname,attr"`
|
||||
// PoiName string `xml:"poiname,attr"`
|
||||
// PoiId string `xml:"poiid,attr"`
|
||||
// BuildingId string `xml:"buildingId,attr"`
|
||||
// FloorName string `xml:"floorName,attr"`
|
||||
// PoiCategoryTips string `xml:"poiCategoryTips,attr"`
|
||||
// PoiBusinessHour string `xml:"poiBusinessHour,attr"`
|
||||
// PoiPhone string `xml:"poiPhone,attr"`
|
||||
// PoiPriceTips string `xml:"poiPriceTips,attr"`
|
||||
// IsFromPoiList string `xml:"isFromPoiList,attr"`
|
||||
}
|
||||
|
||||
// ReferMsg 表示引用消息
|
||||
type ReferMsg struct {
|
||||
Type int64 `xml:"type"`
|
||||
@@ -153,27 +209,50 @@ type DataItem struct {
|
||||
MessageUUID string `xml:"messageuuid,omitempty"`
|
||||
FromNewMsgID string `xml:"fromnewmsgid,omitempty"`
|
||||
|
||||
// 链接
|
||||
Link string `xml:"link,omitempty"`
|
||||
|
||||
// 音乐
|
||||
StreamWebURL string `xml:"streamweburl,omitempty"`
|
||||
|
||||
// 位置
|
||||
Location DataItemLocation `xml:"location,omitempty"`
|
||||
|
||||
// 套娃合并转发
|
||||
DataTitle string `xml:"datatitle,omitempty"`
|
||||
RecordXML *RecordXML `xml:"recordxml,omitempty"`
|
||||
}
|
||||
|
||||
type DataItemLocation struct {
|
||||
Lat string `xml:"lat,attr"`
|
||||
Lng string `xml:"lng,attr"`
|
||||
Scale string `xml:"scale,attr"`
|
||||
Label string `xml:"label,attr"`
|
||||
PoiName string `xml:"poiname,attr"`
|
||||
}
|
||||
|
||||
type RecordXML struct {
|
||||
RecordInfo RecordInfo `xml:"recordinfo,omitempty"`
|
||||
}
|
||||
|
||||
func (r *RecordInfo) String(title, host string) string {
|
||||
func (r *RecordInfo) String(_type, title, host string) string {
|
||||
buf := strings.Builder{}
|
||||
if title == "" {
|
||||
title = r.Title
|
||||
}
|
||||
buf.WriteString(fmt.Sprintf("[合并转发|%s]\n", title))
|
||||
if title == "" {
|
||||
title = strings.TrimSpace(strings.ReplaceAll(r.Desc, "\n", " "))
|
||||
if len(title) > 80 {
|
||||
title = title[:80] + "..."
|
||||
}
|
||||
}
|
||||
buf.WriteString(fmt.Sprintf("[%s|%s]\n", _type, title))
|
||||
for _, item := range r.DataList.DataItems {
|
||||
buf.WriteString(fmt.Sprintf(" %s %s\n", item.SourceName, item.SourceTime))
|
||||
|
||||
// 套娃合并转发
|
||||
if item.DataType == "17" && item.RecordXML != nil {
|
||||
content := item.RecordXML.RecordInfo.String(item.DataTitle, host)
|
||||
content := item.RecordXML.RecordInfo.String(_type, item.DataTitle, host)
|
||||
if content != "" {
|
||||
for _, line := range strings.Split(content, "\n") {
|
||||
buf.WriteString(fmt.Sprintf(" %s\n", line))
|
||||
@@ -182,14 +261,44 @@ func (r *RecordInfo) String(title, host string) string {
|
||||
continue
|
||||
}
|
||||
|
||||
switch item.DataFmt {
|
||||
case "pic", "jpg":
|
||||
switch item.DataType {
|
||||
case "2":
|
||||
// 图片
|
||||
buf.WriteString(fmt.Sprintf(" \n", host, item.FullMD5))
|
||||
case "4":
|
||||
//视频
|
||||
buf.WriteString(fmt.Sprintf(" \n", host, item.FullMD5))
|
||||
case "8":
|
||||
// 文件
|
||||
// FIXME 笔记的第一条是 htm 数据,暂时跳过处理
|
||||
if item.DataFmt == ".htm" {
|
||||
continue
|
||||
}
|
||||
buf.WriteString(fmt.Sprintf(" [文件|%s](http://%s/file/%s)\n", item.DataTitle, host, item.FullMD5))
|
||||
case "5":
|
||||
// Link
|
||||
buf.WriteString(fmt.Sprintf(" [链接|%s](%s)\n", item.DataTitle, item.Link))
|
||||
case "6":
|
||||
// Location
|
||||
buf.WriteString(fmt.Sprintf(" [位置|%s]\n", item.Location.PoiName))
|
||||
case "22":
|
||||
// 视频号
|
||||
buf.WriteString(fmt.Sprintf(" [视频号|%s]\n", strings.TrimSpace(strings.ReplaceAll(item.DataDesc, "\n", " "))))
|
||||
case "23":
|
||||
// 视频号直播
|
||||
buf.WriteString(fmt.Sprintf(" [视频号直播|%s]\n", strings.TrimSpace(strings.ReplaceAll(item.DataDesc, "\n", " "))))
|
||||
case "32":
|
||||
// 音乐
|
||||
buf.WriteString(fmt.Sprintf(" [音乐|%s](%s)\n", item.DataTitle, item.StreamWebURL))
|
||||
case "37":
|
||||
// 动画表情
|
||||
buf.WriteString(" [动画表情]\n")
|
||||
default:
|
||||
for _, line := range strings.Split(item.DataDesc, "\n") {
|
||||
buf.WriteString(fmt.Sprintf(" %s\n", line))
|
||||
}
|
||||
}
|
||||
|
||||
buf.WriteString("\n")
|
||||
}
|
||||
return buf.String()
|
||||
@@ -202,6 +311,16 @@ type PatMsg struct {
|
||||
Records Records `xml:"records"` // 拍一拍记录
|
||||
}
|
||||
|
||||
// PatInfo 拍一拍 v2
|
||||
type PatInfo struct {
|
||||
FromUsername string `xml:"fromusername"`
|
||||
ChatUsername string `xml:"chatusername"`
|
||||
PattedUsername string `xml:"pattedusername"`
|
||||
PatSuffix string `xml:"patsuffix"`
|
||||
PatSuffixVersion int `xml:"patsuffixversion"`
|
||||
Template string `xml:"template"`
|
||||
}
|
||||
|
||||
// Records 拍一拍记录集合
|
||||
type Records struct {
|
||||
Record []PatRecord `xml:"record"` // 拍一拍记录列表
|
||||
@@ -283,10 +402,49 @@ type FinderMegaVideo struct {
|
||||
ObjectNonceID string `xml:"objectNonceId"`
|
||||
}
|
||||
|
||||
type FinderLive struct {
|
||||
FinderLiveID string `xml:"finderLiveID"`
|
||||
FinderUsername string `xml:"finderUsername"`
|
||||
FinderObjectID string `xml:"finderObjectID"`
|
||||
FinderNonceID string `xml:"finderNonceID"`
|
||||
Nickname string `xml:"nickname"`
|
||||
HeadURL string `xml:"headUrl"`
|
||||
Desc string `xml:"desc"`
|
||||
LiveStatus int `xml:"liveStatus"`
|
||||
LiveSourceTypeStr string `xml:"liveSourceTypeStr"`
|
||||
ExtFlag int `xml:"extFlag"`
|
||||
LiveSecondaryDeviceFlagStr string `xml:"liveSecondaryDeviceFlagStr"`
|
||||
LiveFlag int `xml:"liveFlag"`
|
||||
AuthIconURL string `xml:"authIconUrl"`
|
||||
AuthIconTypeStr string `xml:"authIconTypeStr"`
|
||||
BindType int `xml:"bindType"`
|
||||
BizUsername string `xml:"bizUsername"`
|
||||
BizNickname string `xml:"bizNickname"`
|
||||
ChargeFlag int `xml:"chargeFlag"`
|
||||
ReplayStatus int `xml:"replayStatus"`
|
||||
SpamLiveExtFlagString string `xml:"spamLiveExtFlagString"`
|
||||
EnterSessionID string `xml:"enterSessionId"`
|
||||
LiveMode int `xml:"liveMode"`
|
||||
LiveSubMode int `xml:"liveSubMode"`
|
||||
Media FinderLiveMedia `xml:"media"`
|
||||
ShareScene int `xml:"shareScene"`
|
||||
}
|
||||
|
||||
type FinderLiveMedia struct {
|
||||
CoverURL FinderLiveMediaCoverURL `xml:"coverUrl"`
|
||||
Height int `xml:"height"`
|
||||
Width int `xml:"width"`
|
||||
}
|
||||
|
||||
type FinderLiveMediaCoverURL struct {
|
||||
Text string `xml:",cdata"`
|
||||
}
|
||||
|
||||
type SysMsg struct {
|
||||
Type string `xml:"type,attr"`
|
||||
DelChatRoomMember *DelChatRoomMember `xml:"delchatroommember,omitempty"`
|
||||
SysMsgTemplate *SysMsgTemplate `xml:"sysmsgtemplate,omitempty"`
|
||||
RevokeMsg *RevokeMsg `xml:"revokemsg,omitempty"`
|
||||
}
|
||||
|
||||
// 第一种消息类型:删除群成员/二维码邀请
|
||||
@@ -296,6 +454,11 @@ type DelChatRoomMember struct {
|
||||
Link QRLink `xml:"link"`
|
||||
}
|
||||
|
||||
type RevokeMsg struct {
|
||||
Content string `xml:"content"`
|
||||
RevokeTime int `xml:"revoketime"`
|
||||
}
|
||||
|
||||
type QRLink struct {
|
||||
Scene string `xml:"scene"`
|
||||
Text string `xml:"text"`
|
||||
@@ -345,8 +508,11 @@ type Member struct {
|
||||
}
|
||||
|
||||
func (s *SysMsg) String() string {
|
||||
if s.Type == "delchatroommember" {
|
||||
switch s.Type {
|
||||
case "delchatroommember":
|
||||
return s.DelChatRoomMemberString()
|
||||
case "revokemsg":
|
||||
return s.RevokeMsg.Content
|
||||
}
|
||||
return s.SysMsgTemplateString()
|
||||
}
|
||||
|
||||
+203
-47
@@ -17,6 +17,94 @@ const (
|
||||
WeChatDarwinV3 = "wechatdarwinv3"
|
||||
)
|
||||
|
||||
const (
|
||||
// MessageTypeText 文本
|
||||
MessageTypeText = 1
|
||||
|
||||
// MessageTypeImage 图片
|
||||
MessageTypeImage = 3
|
||||
|
||||
// MessageTypeVoice 语音
|
||||
MessageTypeVoice = 34
|
||||
|
||||
// MessageTypeCard 名片
|
||||
MessageTypeCard = 42
|
||||
|
||||
// MessageTypeVideo 视频
|
||||
MessageTypeVideo = 43
|
||||
|
||||
// MessageTypeAnimation 动画表情
|
||||
MessageTypeAnimation = 47
|
||||
|
||||
// MessageTypeLocation 位置
|
||||
MessageTypeLocation = 48
|
||||
|
||||
// MessageTypeShare 分享
|
||||
MessageTypeShare = 49
|
||||
|
||||
// MessageTypeVOIP 语音通话
|
||||
MessageTypeVOIP = 50
|
||||
|
||||
// MessageTypeSystem 系统
|
||||
MessageTypeSystem = 10000
|
||||
)
|
||||
|
||||
const (
|
||||
// MessageSubTypeText 文本
|
||||
MessageSubTypeText = 1
|
||||
|
||||
// MessageSubTypeLink 链接分享
|
||||
MessageSubTypeLink = 4
|
||||
|
||||
// MessageSubTypeLink2 链接分享
|
||||
MessageSubTypeLink2 = 5
|
||||
|
||||
// MessageSubTypeFile 文件
|
||||
MessageSubTypeFile = 6
|
||||
|
||||
// MessageSubTypeGIF 动图
|
||||
MessageSubTypeGIF = 8
|
||||
|
||||
// MessageSubTypeMergeForward 合并转发
|
||||
MessageSubTypeMergeForward = 19
|
||||
|
||||
// MessageSubTypeNote 笔记
|
||||
MessageSubTypeNote = 24
|
||||
|
||||
// MessageSubTypeMiniProgram 小程序
|
||||
MessageSubTypeMiniProgram = 33
|
||||
|
||||
// MessageSubTypeMiniProgram2 小程序
|
||||
MessageSubTypeMiniProgram2 = 36
|
||||
|
||||
// MessageSubTypeChannel 视频号
|
||||
MessageSubTypeChannel = 51
|
||||
|
||||
// MessageSubTypeQuote 引用
|
||||
MessageSubTypeQuote = 57
|
||||
|
||||
// MessageSubTypePat 拍一拍
|
||||
MessageSubTypePat = 62
|
||||
|
||||
// MessageSubTypeChannelLive 视频号直播
|
||||
MessageSubTypeChannelLive = 63
|
||||
|
||||
// MessageSubTypeChatRoomNotice 群公告
|
||||
MessageSubTypeChatRoomNotice = 87
|
||||
|
||||
// MessageSubTypeMusic 音乐
|
||||
MessageSubTypeMusic = 92
|
||||
|
||||
// MessageSubTypePay 转账
|
||||
MessageSubTypePay = 2000
|
||||
|
||||
// MessageSubTypeRedEnvelope 红包
|
||||
MessageSubTypeRedEnvelope = 2001
|
||||
|
||||
// MessageSubTypeRedEnvelopeCover 红包封面
|
||||
MessageSubTypeRedEnvelopeCover = 2003
|
||||
)
|
||||
|
||||
type Message struct {
|
||||
Version string `json:"-"` // 消息版本,内部判断
|
||||
Seq int64 `json:"seq"` // 消息序号,10位时间戳 + 3位序号
|
||||
@@ -46,7 +134,9 @@ func (m *Message) ParseMediaInfo(data string) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
if m.Type == 10000 {
|
||||
if m.Type == MessageTypeSystem {
|
||||
m.Sender = "系统消息"
|
||||
m.SenderName = ""
|
||||
var sysMsg SysMsg
|
||||
if err := xml.Unmarshal([]byte(data), &sysMsg); err != nil {
|
||||
m.Content = data
|
||||
@@ -55,8 +145,6 @@ func (m *Message) ParseMediaInfo(data string) error {
|
||||
if Debug {
|
||||
m.SysMsg = &sysMsg
|
||||
}
|
||||
m.Sender = "系统消息"
|
||||
m.SenderName = ""
|
||||
m.Content = sysMsg.String()
|
||||
return nil
|
||||
}
|
||||
@@ -76,28 +164,36 @@ func (m *Message) ParseMediaInfo(data string) error {
|
||||
}
|
||||
|
||||
switch m.Type {
|
||||
case 3:
|
||||
case MessageTypeImage:
|
||||
m.Contents["md5"] = msg.Image.MD5
|
||||
case 43:
|
||||
case MessageTypeVideo:
|
||||
if msg.Video.Md5 != "" {
|
||||
m.Contents["md5"] = msg.Video.Md5
|
||||
}
|
||||
if msg.Video.RawMd5 != "" {
|
||||
m.Contents["rawmd5"] = msg.Video.RawMd5
|
||||
}
|
||||
case 49:
|
||||
case MessageTypeAnimation:
|
||||
m.Contents["cdnurl"] = msg.Emoji.CdnURL
|
||||
case MessageTypeLocation:
|
||||
m.Contents["x"] = msg.Location.X
|
||||
m.Contents["y"] = msg.Location.Y
|
||||
m.Contents["label"] = msg.Location.Label
|
||||
m.Contents["cityname"] = msg.Location.CityName
|
||||
case MessageTypeShare:
|
||||
m.SubType = int64(msg.App.Type)
|
||||
switch m.SubType {
|
||||
case 5:
|
||||
case MessageSubTypeText, MessageSubTypeLink, MessageSubTypeLink2:
|
||||
// 链接
|
||||
m.Contents["title"] = msg.App.Title
|
||||
m.Contents["desc"] = msg.App.Des
|
||||
m.Contents["url"] = msg.App.URL
|
||||
case 6:
|
||||
case MessageSubTypeFile:
|
||||
// 文件
|
||||
m.Contents["title"] = msg.App.Title
|
||||
m.Contents["md5"] = msg.App.MD5
|
||||
case 19:
|
||||
// 合并转发
|
||||
case MessageSubTypeMergeForward, MessageSubTypeNote, MessageSubTypeChatRoomNotice:
|
||||
// 合并转发 & 笔记
|
||||
m.Contents["title"] = msg.App.Title
|
||||
m.Contents["desc"] = msg.App.Des
|
||||
if msg.App.RecordItem == nil {
|
||||
@@ -109,20 +205,20 @@ func (m *Message) ParseMediaInfo(data string) error {
|
||||
return err
|
||||
}
|
||||
m.Contents["recordInfo"] = recordInfo
|
||||
case 33, 36:
|
||||
case MessageSubTypeMiniProgram, MessageSubTypeMiniProgram2:
|
||||
// 小程序
|
||||
m.Contents["title"] = msg.App.SourceDisplayName
|
||||
m.Contents["url"] = msg.App.URL
|
||||
case 51:
|
||||
case MessageSubTypeChannel:
|
||||
// 视频号
|
||||
if msg.App.FinderFeed == nil {
|
||||
break
|
||||
}
|
||||
m.Contents["title"] = msg.App.FinderFeed.Desc
|
||||
m.Contents["title"] = strings.TrimSpace(strings.ReplaceAll(msg.App.FinderFeed.Desc, "\n", " "))
|
||||
if len(msg.App.FinderFeed.MediaList.Media) > 0 {
|
||||
m.Contents["url"] = msg.App.FinderFeed.MediaList.Media[0].URL
|
||||
}
|
||||
case 57:
|
||||
case MessageSubTypeQuote:
|
||||
// 引用
|
||||
m.Content = msg.App.Title
|
||||
if msg.App.ReferMsg == nil {
|
||||
@@ -141,17 +237,29 @@ func (m *Message) ParseMediaInfo(data string) error {
|
||||
break
|
||||
}
|
||||
m.Contents["refer"] = subMsg
|
||||
case 62:
|
||||
case MessageSubTypePat:
|
||||
// 拍一拍
|
||||
if msg.App.PatMsg == nil {
|
||||
if msg.App.PatMsg != nil {
|
||||
if len(msg.App.PatMsg.Records.Record) != 0 {
|
||||
m.Sender = msg.App.PatMsg.Records.Record[0].FromUser
|
||||
m.Content = msg.App.PatMsg.Records.Record[0].Templete
|
||||
}
|
||||
}
|
||||
if msg.App.PatInfo != nil {
|
||||
m.Content = msg.App.Title
|
||||
}
|
||||
case MessageSubTypeChannelLive:
|
||||
// 视频号直播
|
||||
if msg.App.FinderLive == nil {
|
||||
break
|
||||
}
|
||||
if len(msg.App.PatMsg.Records.Record) == 0 {
|
||||
break
|
||||
}
|
||||
m.Sender = msg.App.PatMsg.Records.Record[0].FromUser
|
||||
m.Content = msg.App.PatMsg.Records.Record[0].Templete
|
||||
case 2000:
|
||||
m.Contents["title"] = msg.App.FinderLive.Desc
|
||||
case MessageSubTypeMusic:
|
||||
// 音乐
|
||||
m.Contents["title"] = msg.App.Title
|
||||
m.Contents["desc"] = msg.App.Des
|
||||
m.Contents["url"] = msg.App.URL
|
||||
case MessageSubTypePay:
|
||||
// 微信转账
|
||||
if msg.App.WCPayInfo == nil {
|
||||
break
|
||||
@@ -236,9 +344,9 @@ func (m *Message) PlainText(showChatRoom bool, timeFormat string, host string) s
|
||||
|
||||
func (m *Message) PlainTextContent() string {
|
||||
switch m.Type {
|
||||
case 1:
|
||||
case MessageTypeText:
|
||||
return m.Content
|
||||
case 3:
|
||||
case MessageTypeImage:
|
||||
keylist := make([]string, 0)
|
||||
if m.Contents["md5"] != nil {
|
||||
if md5, ok := m.Contents["md5"].(string); ok {
|
||||
@@ -251,14 +359,14 @@ func (m *Message) PlainTextContent() string {
|
||||
}
|
||||
}
|
||||
return fmt.Sprintf("", m.Contents["host"], strings.Join(keylist, ","))
|
||||
case 34:
|
||||
case MessageTypeVoice:
|
||||
if voice, ok := m.Contents["voice"]; ok {
|
||||
return fmt.Sprintf("[语音](http://%s/voice/%s)", m.Contents["host"], voice)
|
||||
}
|
||||
return "[语音]"
|
||||
case 42:
|
||||
case MessageTypeCard:
|
||||
return "[名片]"
|
||||
case 43:
|
||||
case MessageTypeVideo:
|
||||
keylist := make([]string, 0)
|
||||
if m.Contents["md5"] != nil {
|
||||
if md5, ok := m.Contents["md5"].(string); ok {
|
||||
@@ -276,17 +384,34 @@ func (m *Message) PlainTextContent() string {
|
||||
}
|
||||
}
|
||||
return fmt.Sprintf("", m.Contents["host"], strings.Join(keylist, ","))
|
||||
case 47:
|
||||
case MessageTypeAnimation:
|
||||
if m.Contents["cdnurl"] != nil {
|
||||
if cdnURL, ok := m.Contents["cdnurl"].(string); ok {
|
||||
return fmt.Sprintf("", cdnURL)
|
||||
}
|
||||
}
|
||||
return "[动画表情]"
|
||||
case 49:
|
||||
case MessageTypeLocation:
|
||||
keylist := make([]string, 0)
|
||||
for _, key := range []string{"label", "cityname", "x", "y"} {
|
||||
if m.Contents[key] != nil {
|
||||
if value, ok := m.Contents[key].(string); ok {
|
||||
keylist = append(keylist, value)
|
||||
}
|
||||
}
|
||||
}
|
||||
return fmt.Sprintf("[位置|%s]", strings.Join(keylist, "|"))
|
||||
case MessageTypeShare:
|
||||
switch m.SubType {
|
||||
case 5:
|
||||
case MessageSubTypeText:
|
||||
return fmt.Sprintf("[链接|%s](%s)", m.Contents["title"], m.Contents["desc"])
|
||||
case MessageSubTypeLink, MessageSubTypeLink2:
|
||||
return fmt.Sprintf("[链接|%s](%s)", m.Contents["title"], m.Contents["url"])
|
||||
case 6:
|
||||
case MessageSubTypeFile:
|
||||
return fmt.Sprintf("[文件|%s](http://%s/file/%s)", m.Contents["title"], m.Contents["host"], m.Contents["md5"])
|
||||
case 8:
|
||||
case MessageSubTypeGIF:
|
||||
return "[GIF表情]"
|
||||
case 19:
|
||||
case MessageSubTypeMergeForward:
|
||||
_recordInfo, ok := m.Contents["recordInfo"]
|
||||
if !ok {
|
||||
return "[合并转发]"
|
||||
@@ -299,19 +424,33 @@ func (m *Message) PlainTextContent() string {
|
||||
if m.Contents["host"] != nil {
|
||||
host = m.Contents["host"].(string)
|
||||
}
|
||||
return recordInfo.String("", host)
|
||||
case 33, 36:
|
||||
return recordInfo.String("合并转发", "", host)
|
||||
case MessageSubTypeNote:
|
||||
_recordInfo, ok := m.Contents["recordInfo"]
|
||||
if !ok {
|
||||
return "[笔记]"
|
||||
}
|
||||
recordInfo, ok := _recordInfo.(*RecordInfo)
|
||||
if !ok {
|
||||
return "[笔记]"
|
||||
}
|
||||
host := ""
|
||||
if m.Contents["host"] != nil {
|
||||
host = m.Contents["host"].(string)
|
||||
}
|
||||
return recordInfo.String("笔记", "", host)
|
||||
case MessageSubTypeMiniProgram, MessageSubTypeMiniProgram2:
|
||||
if m.Contents["title"] == "" {
|
||||
return "[小程序]"
|
||||
}
|
||||
return fmt.Sprintf("[小程序|%s](%s)", m.Contents["title"], m.Contents["url"])
|
||||
case 51:
|
||||
case MessageSubTypeChannel:
|
||||
if m.Contents["title"] == "" {
|
||||
return "[视频号]"
|
||||
} else {
|
||||
return fmt.Sprintf("[视频号|%s](%s)", m.Contents["title"], m.Contents["url"])
|
||||
}
|
||||
case 57:
|
||||
case MessageSubTypeQuote:
|
||||
_refer, ok := m.Contents["refer"]
|
||||
if !ok {
|
||||
if m.Content == "" {
|
||||
@@ -342,24 +481,41 @@ func (m *Message) PlainTextContent() string {
|
||||
}
|
||||
buf.WriteString(m.Content)
|
||||
return buf.String()
|
||||
case 62:
|
||||
case MessageSubTypePat:
|
||||
return m.Content
|
||||
case 63:
|
||||
return "[视频号]"
|
||||
case 87:
|
||||
return "[群公告]"
|
||||
case 2000:
|
||||
case MessageSubTypeChannelLive:
|
||||
if m.Contents["title"] != nil {
|
||||
return fmt.Sprintf("[视频号直播|%s]", m.Contents["title"])
|
||||
}
|
||||
return "[视频号直播]"
|
||||
case MessageSubTypeChatRoomNotice:
|
||||
_recordInfo, ok := m.Contents["recordInfo"]
|
||||
if !ok {
|
||||
return "[群公告]"
|
||||
}
|
||||
recordInfo, ok := _recordInfo.(*RecordInfo)
|
||||
if !ok {
|
||||
return "[群公告]"
|
||||
}
|
||||
host := ""
|
||||
if m.Contents["host"] != nil {
|
||||
host = m.Contents["host"].(string)
|
||||
}
|
||||
return recordInfo.String("群公告", "", host)
|
||||
case MessageSubTypeMusic:
|
||||
return fmt.Sprintf("[音乐|%s](%s)", m.Contents["title"], m.Contents["url"])
|
||||
case MessageSubTypePay:
|
||||
return m.Content
|
||||
case 2001:
|
||||
case MessageSubTypeRedEnvelope:
|
||||
return "[红包]"
|
||||
case 2003:
|
||||
case MessageSubTypeRedEnvelopeCover:
|
||||
return "[红包封面]"
|
||||
default:
|
||||
return "[分享]"
|
||||
}
|
||||
case 50:
|
||||
case MessageTypeVOIP:
|
||||
return "[语音通话]"
|
||||
case 10000:
|
||||
case MessageTypeSystem:
|
||||
return m.Content
|
||||
default:
|
||||
content := m.Content
|
||||
|
||||
@@ -15,7 +15,7 @@ const (
|
||||
|
||||
// InfoBarViewHeight info bar height.
|
||||
const (
|
||||
InfoBarViewHeight = 7
|
||||
InfoBarViewHeight = 8
|
||||
accountRow = 0
|
||||
statusRow = 1
|
||||
platformRow = 2
|
||||
@@ -23,6 +23,7 @@ const (
|
||||
dataUsageRow = 4
|
||||
workUsageRow = 5
|
||||
httpServerRow = 6
|
||||
autoDecryptRow = 7
|
||||
|
||||
// 列索引
|
||||
labelCol1 = 0 // 第一列标签
|
||||
@@ -145,10 +146,17 @@ func New() *InfoBar {
|
||||
table.SetCell(
|
||||
httpServerRow,
|
||||
labelCol2,
|
||||
tview.NewTableCell(fmt.Sprintf(" [%s::]%s", headerColor, "Auto Decrypt:")),
|
||||
tview.NewTableCell(fmt.Sprintf(" [%s::]%s", headerColor, "Image Key:")),
|
||||
)
|
||||
table.SetCell(httpServerRow, valueCol2, tview.NewTableCell(""))
|
||||
|
||||
table.SetCell(
|
||||
autoDecryptRow,
|
||||
labelCol1,
|
||||
tview.NewTableCell(fmt.Sprintf(" [%s::]%s", headerColor, "Auto Decrypt:")),
|
||||
)
|
||||
table.SetCell(autoDecryptRow, valueCol1, tview.NewTableCell(""))
|
||||
|
||||
// infobar
|
||||
infoBar := &InfoBar{
|
||||
Box: tview.NewBox(),
|
||||
@@ -200,9 +208,13 @@ func (info *InfoBar) UpdateHTTPServer(server string) {
|
||||
info.table.GetCell(httpServerRow, valueCol1).SetText(server)
|
||||
}
|
||||
|
||||
func (info *InfoBar) UpdateImageKey(key string) {
|
||||
info.table.GetCell(httpServerRow, valueCol2).SetText(key)
|
||||
}
|
||||
|
||||
// UpdateAutoDecrypt updates Auto Decrypt value.
|
||||
func (info *InfoBar) UpdateAutoDecrypt(text string) {
|
||||
info.table.GetCell(httpServerRow, valueCol2).SetText(text)
|
||||
info.table.GetCell(autoDecryptRow, valueCol1).SetText(text)
|
||||
}
|
||||
|
||||
// Draw draws this primitive onto the screen.
|
||||
|
||||
Reference in New Issue
Block a user