Skip to content

Commit cad198d

Browse files
authored
fix(model): enhanced message parsing and display (#223)
1 parent 9c221e6 commit cad198d

File tree

4 files changed

+400
-65
lines changed

4 files changed

+400
-65
lines changed

internal/chatlog/app.go

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -148,6 +148,7 @@ func (a *App) refresh() {
148148
a.infoBar.UpdateBasicInfo(a.ctx.PID, a.ctx.FullVersion, a.ctx.ExePath)
149149
a.infoBar.UpdateStatus(a.ctx.Status)
150150
a.infoBar.UpdateDataKey(a.ctx.DataKey)
151+
a.infoBar.UpdateImageKey(a.ctx.ImgKey)
151152
a.infoBar.UpdatePlatform(a.ctx.Platform)
152153
a.infoBar.UpdateDataUsageDir(a.ctx.DataUsage, a.ctx.DataDir)
153154
a.infoBar.UpdateWorkUsageDir(a.ctx.WorkUsage, a.ctx.WorkDir)
@@ -201,14 +202,14 @@ func (a *App) inputCapture(event *tcell.EventKey) *tcell.EventKey {
201202
func (a *App) initMenu() {
202203
getDataKey := &menu.Item{
203204
Index: 2,
204-
Name: "获取数据密钥",
205-
Description: "从进程获取数据密钥",
205+
Name: "获取密钥",
206+
Description: "从进程获取数据密钥 & 图片密钥",
206207
Selected: func(i *menu.Item) {
207208
modal := tview.NewModal()
208209
if runtime.GOOS == "darwin" {
209-
modal.SetText("获取数据密钥中...\n预计需要 20 秒左右的时间,期间微信会卡住,请耐心等待")
210+
modal.SetText("获取密钥中...\n预计需要 20 秒左右的时间,期间微信会卡住,请耐心等待")
210211
} else {
211-
modal.SetText("获取数据密钥中...")
212+
modal.SetText("获取密钥中...")
212213
}
213214
a.mainPages.AddPage("modal", modal, true, true)
214215
a.SetFocus(modal)
@@ -220,10 +221,10 @@ func (a *App) initMenu() {
220221
a.QueueUpdateDraw(func() {
221222
if err != nil {
222223
// 解密失败
223-
modal.SetText("获取数据密钥失败: " + err.Error())
224+
modal.SetText("获取密钥失败: " + err.Error())
224225
} else {
225226
// 解密成功
226-
modal.SetText("获取数据密钥成功")
227+
modal.SetText("获取密钥成功")
227228
}
228229

229230
// 添加确认按钮

internal/model/mediamessage.go

Lines changed: 176 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -8,10 +8,12 @@ import (
88
)
99

1010
type MediaMsg struct {
11-
XMLName xml.Name `xml:"msg"`
12-
Image Image `xml:"img,omitempty"`
13-
Video Video `xml:"videomsg,omitempty"`
14-
App App `xml:"appmsg,omitempty"`
11+
XMLName xml.Name `xml:"msg"`
12+
Image Image `xml:"img,omitempty"`
13+
Video Video `xml:"videomsg,omitempty"`
14+
App App `xml:"appmsg,omitempty"`
15+
Emoji Emoji `xml:"emoji,omitempty"`
16+
Location Location `xml:"location,omitempty"`
1517
}
1618

1719
type Image struct {
@@ -70,9 +72,63 @@ type App struct {
7072
FinderFeed *FinderFeed `xml:"finderFeed,omitempty"` // type 51 视频号
7173
ReferMsg *ReferMsg `xml:"refermsg,omitempty"` // type 57 引用
7274
PatMsg *PatMsg `xml:"patMsg,omitempty"` // type 62 拍一拍
75+
PatInfo *PatInfo `xml:"patinfo,omitempty"` // type 62 拍一拍 v2
76+
FinderLive *FinderLive `xml:"finderLive,omitempty"` // type 63 视频号直播
7377
WCPayInfo *WCPayInfo `xml:"wcpayinfo,omitempty"` // type 2000 微信转账
7478
}
7579

80+
type Emoji struct {
81+
FromUsername string `xml:"fromusername,attr"`
82+
ToUsername string `xml:"tousername,attr"`
83+
Type string `xml:"type,attr"`
84+
IdBuffer string `xml:"idbuffer,attr"`
85+
Md5 string `xml:"md5,attr"`
86+
Len string `xml:"len,attr"`
87+
CdnURL string `xml:"cdnurl,attr"`
88+
AesKey string `xml:"aeskey,attr"`
89+
Width string `xml:"width,attr"`
90+
Height string `xml:"height,attr"`
91+
// ProductId string `xml:"productid,attr"`
92+
// AndroidMd5 string `xml:"androidmd5,attr"`
93+
// AndroidLen string `xml:"androidlen,attr"`
94+
// S60v3Md5 string `xml:"s60v3md5,attr"`
95+
// S60v3Len string `xml:"s60v3len,attr"`
96+
// S60v5Md5 string `xml:"s60v5md5,attr"`
97+
// S60v5Len string `xml:"s60v5len,attr"`
98+
// DesignerId string `xml:"designerid,attr"`
99+
// ThumbUrl string `xml:"thumburl,attr"`
100+
// EncryptUrl string `xml:"encrypturl,attr"`
101+
// ExternUrl string `xml:"externurl,attr"`
102+
// ExternMd5 string `xml:"externmd5,attr"`
103+
// TpUrl string `xml:"tpurl,attr"`
104+
// TpAuthKey string `xml:"tpauthkey,attr"`
105+
// AttachedText string `xml:"attachedtext,attr"`
106+
// AttachedTextColor string `xml:"attachedtextcolor,attr"`
107+
// LensId string `xml:"lensid,attr"`
108+
// EmojiAttr string `xml:"emojiattr,attr"`
109+
// LinkId string `xml:"linkid,attr"`
110+
// Desc string `xml:"desc,attr"`
111+
}
112+
113+
type Location struct {
114+
X string `xml:"x,attr"`
115+
Y string `xml:"y,attr"`
116+
Scale string `xml:"scale,attr"`
117+
Label string `xml:"label,attr"`
118+
MapType string `xml:"maptype,attr"`
119+
Adcode string `xml:"adcode,attr"`
120+
CityName string `xml:"cityname,attr"`
121+
// PoiName string `xml:"poiname,attr"`
122+
// PoiId string `xml:"poiid,attr"`
123+
// BuildingId string `xml:"buildingId,attr"`
124+
// FloorName string `xml:"floorName,attr"`
125+
// PoiCategoryTips string `xml:"poiCategoryTips,attr"`
126+
// PoiBusinessHour string `xml:"poiBusinessHour,attr"`
127+
// PoiPhone string `xml:"poiPhone,attr"`
128+
// PoiPriceTips string `xml:"poiPriceTips,attr"`
129+
// IsFromPoiList string `xml:"isFromPoiList,attr"`
130+
}
131+
76132
// ReferMsg 表示引用消息
77133
type ReferMsg struct {
78134
Type int64 `xml:"type"`
@@ -153,27 +209,50 @@ type DataItem struct {
153209
MessageUUID string `xml:"messageuuid,omitempty"`
154210
FromNewMsgID string `xml:"fromnewmsgid,omitempty"`
155211

212+
// 链接
213+
Link string `xml:"link,omitempty"`
214+
215+
// 音乐
216+
StreamWebURL string `xml:"streamweburl,omitempty"`
217+
218+
// 位置
219+
Location DataItemLocation `xml:"location,omitempty"`
220+
156221
// 套娃合并转发
157222
DataTitle string `xml:"datatitle,omitempty"`
158223
RecordXML *RecordXML `xml:"recordxml,omitempty"`
159224
}
160225

226+
type DataItemLocation struct {
227+
Lat string `xml:"lat,attr"`
228+
Lng string `xml:"lng,attr"`
229+
Scale string `xml:"scale,attr"`
230+
Label string `xml:"label,attr"`
231+
PoiName string `xml:"poiname,attr"`
232+
}
233+
161234
type RecordXML struct {
162235
RecordInfo RecordInfo `xml:"recordinfo,omitempty"`
163236
}
164237

165-
func (r *RecordInfo) String(title, host string) string {
238+
func (r *RecordInfo) String(_type, title, host string) string {
166239
buf := strings.Builder{}
167240
if title == "" {
168241
title = r.Title
169242
}
170-
buf.WriteString(fmt.Sprintf("[合并转发|%s]\n", title))
243+
if title == "" {
244+
title = strings.TrimSpace(strings.ReplaceAll(r.Desc, "\n", " "))
245+
if len(title) > 80 {
246+
title = title[:80] + "..."
247+
}
248+
}
249+
buf.WriteString(fmt.Sprintf("[%s|%s]\n", _type, title))
171250
for _, item := range r.DataList.DataItems {
172251
buf.WriteString(fmt.Sprintf(" %s %s\n", item.SourceName, item.SourceTime))
173252

174253
// 套娃合并转发
175254
if item.DataType == "17" && item.RecordXML != nil {
176-
content := item.RecordXML.RecordInfo.String(item.DataTitle, host)
255+
content := item.RecordXML.RecordInfo.String(_type, item.DataTitle, host)
177256
if content != "" {
178257
for _, line := range strings.Split(content, "\n") {
179258
buf.WriteString(fmt.Sprintf(" %s\n", line))
@@ -182,14 +261,44 @@ func (r *RecordInfo) String(title, host string) string {
182261
continue
183262
}
184263

185-
switch item.DataFmt {
186-
case "pic", "jpg":
264+
switch item.DataType {
265+
case "2":
266+
// 图片
187267
buf.WriteString(fmt.Sprintf(" ![图片](http://%s/image/%s)\n", host, item.FullMD5))
268+
case "4":
269+
//视频
270+
buf.WriteString(fmt.Sprintf(" ![视频](http://%s/video/%s)\n", host, item.FullMD5))
271+
case "8":
272+
// 文件
273+
// FIXME 笔记的第一条是 htm 数据,暂时跳过处理
274+
if item.DataFmt == ".htm" {
275+
continue
276+
}
277+
buf.WriteString(fmt.Sprintf(" [文件|%s](http://%s/file/%s)\n", item.DataTitle, host, item.FullMD5))
278+
case "5":
279+
// Link
280+
buf.WriteString(fmt.Sprintf(" [链接|%s](%s)\n", item.DataTitle, item.Link))
281+
case "6":
282+
// Location
283+
buf.WriteString(fmt.Sprintf(" [位置|%s]\n", item.Location.PoiName))
284+
case "22":
285+
// 视频号
286+
buf.WriteString(fmt.Sprintf(" [视频号|%s]\n", strings.TrimSpace(strings.ReplaceAll(item.DataDesc, "\n", " "))))
287+
case "23":
288+
// 视频号直播
289+
buf.WriteString(fmt.Sprintf(" [视频号直播|%s]\n", strings.TrimSpace(strings.ReplaceAll(item.DataDesc, "\n", " "))))
290+
case "32":
291+
// 音乐
292+
buf.WriteString(fmt.Sprintf(" [音乐|%s](%s)\n", item.DataTitle, item.StreamWebURL))
293+
case "37":
294+
// 动画表情
295+
buf.WriteString(" [动画表情]\n")
188296
default:
189297
for _, line := range strings.Split(item.DataDesc, "\n") {
190298
buf.WriteString(fmt.Sprintf(" %s\n", line))
191299
}
192300
}
301+
193302
buf.WriteString("\n")
194303
}
195304
return buf.String()
@@ -202,6 +311,16 @@ type PatMsg struct {
202311
Records Records `xml:"records"` // 拍一拍记录
203312
}
204313

314+
// PatInfo 拍一拍 v2
315+
type PatInfo struct {
316+
FromUsername string `xml:"fromusername"`
317+
ChatUsername string `xml:"chatusername"`
318+
PattedUsername string `xml:"pattedusername"`
319+
PatSuffix string `xml:"patsuffix"`
320+
PatSuffixVersion int `xml:"patsuffixversion"`
321+
Template string `xml:"template"`
322+
}
323+
205324
// Records 拍一拍记录集合
206325
type Records struct {
207326
Record []PatRecord `xml:"record"` // 拍一拍记录列表
@@ -283,10 +402,49 @@ type FinderMegaVideo struct {
283402
ObjectNonceID string `xml:"objectNonceId"`
284403
}
285404

405+
type FinderLive struct {
406+
FinderLiveID string `xml:"finderLiveID"`
407+
FinderUsername string `xml:"finderUsername"`
408+
FinderObjectID string `xml:"finderObjectID"`
409+
FinderNonceID string `xml:"finderNonceID"`
410+
Nickname string `xml:"nickname"`
411+
HeadURL string `xml:"headUrl"`
412+
Desc string `xml:"desc"`
413+
LiveStatus int `xml:"liveStatus"`
414+
LiveSourceTypeStr string `xml:"liveSourceTypeStr"`
415+
ExtFlag int `xml:"extFlag"`
416+
LiveSecondaryDeviceFlagStr string `xml:"liveSecondaryDeviceFlagStr"`
417+
LiveFlag int `xml:"liveFlag"`
418+
AuthIconURL string `xml:"authIconUrl"`
419+
AuthIconTypeStr string `xml:"authIconTypeStr"`
420+
BindType int `xml:"bindType"`
421+
BizUsername string `xml:"bizUsername"`
422+
BizNickname string `xml:"bizNickname"`
423+
ChargeFlag int `xml:"chargeFlag"`
424+
ReplayStatus int `xml:"replayStatus"`
425+
SpamLiveExtFlagString string `xml:"spamLiveExtFlagString"`
426+
EnterSessionID string `xml:"enterSessionId"`
427+
LiveMode int `xml:"liveMode"`
428+
LiveSubMode int `xml:"liveSubMode"`
429+
Media FinderLiveMedia `xml:"media"`
430+
ShareScene int `xml:"shareScene"`
431+
}
432+
433+
type FinderLiveMedia struct {
434+
CoverURL FinderLiveMediaCoverURL `xml:"coverUrl"`
435+
Height int `xml:"height"`
436+
Width int `xml:"width"`
437+
}
438+
439+
type FinderLiveMediaCoverURL struct {
440+
Text string `xml:",cdata"`
441+
}
442+
286443
type SysMsg struct {
287444
Type string `xml:"type,attr"`
288445
DelChatRoomMember *DelChatRoomMember `xml:"delchatroommember,omitempty"`
289446
SysMsgTemplate *SysMsgTemplate `xml:"sysmsgtemplate,omitempty"`
447+
RevokeMsg *RevokeMsg `xml:"revokemsg,omitempty"`
290448
}
291449

292450
// 第一种消息类型:删除群成员/二维码邀请
@@ -296,6 +454,11 @@ type DelChatRoomMember struct {
296454
Link QRLink `xml:"link"`
297455
}
298456

457+
type RevokeMsg struct {
458+
Content string `xml:"content"`
459+
RevokeTime int `xml:"revoketime"`
460+
}
461+
299462
type QRLink struct {
300463
Scene string `xml:"scene"`
301464
Text string `xml:"text"`
@@ -345,8 +508,11 @@ type Member struct {
345508
}
346509

347510
func (s *SysMsg) String() string {
348-
if s.Type == "delchatroommember" {
511+
switch s.Type {
512+
case "delchatroommember":
349513
return s.DelChatRoomMemberString()
514+
case "revokemsg":
515+
return s.RevokeMsg.Content
350516
}
351517
return s.SysMsgTemplateString()
352518
}

0 commit comments

Comments
 (0)