wechaty / puppet-whatsapp

Wechaty Puppet for Whatsapp
https://npmjs.com/package/wechaty-puppet-whatsapp
Apache License 2.0
24 stars 17 forks source link

关于 whatsapp 图片下载的逻辑 #171

Open su-chang opened 2 years ago

su-chang commented 2 years ago

案例

手机端发送一张图片,从日志来分析会经历以下几个阶段:

关于 Message ACK

/** Message ACK */
export enum MessageAck {
  ACK_ERROR = -1,
  ACK_PENDING = 0,
  ACK_SERVER = 1,
  ACK_DEVICE = 2,
  ACK_READ = 3,
  ACK_PLAYED = 4,
}

日志

10: 41: 06 INFO PuppetWhatsApp onMessageCreate({
  "id": {
    "fromMe": true,
    "remote": "8613811286503@c.us",
    "id": "3A71F8CA50E0135FAB4E",
    "_serialized": "true_8613811286503@c.us_3A71F8CA50E0135FAB4E"
  },
  "ack": 0,
  "hasMedia": false,
  "body": "/9j/4AAQSkZJRgABAQAAAQABAAD/2wBDABsSFBcUERsXFhceHBsgKEIrKCUlKFE6PTBCYFVlZF9VXVtqeJmBanGQc1tdhbWGkJ6jq62rZ4C8ybqmx5moq6T/2wBDARweHigjKE4rK06kbl1upKSkpKSkpKSkpKSkpKSkpKSkpKSkpKSkpKSkpKSkpKSkpKSkpKSkpKSkpKSkpKSkpKT/wgARCABIACkDASIAAhEBAxEB/8QAGQABAAMBAQAAAAAAAAAAAAAAAgABAwQF/8QAFwEBAQEBAAAAAAAAAAAAAAAAAAECA//aAAwDAQACEAMQAAAA9GVXfiOXrzlGmYl7BY1mCs5bFE7Qsw5rMowy9+YzseYMrJsgkAZC7kP/xAAWEQADAAAAAAAAAAAAAAAAAAAQETD/2gAIAQIBAT8ACr//xAAWEQADAAAAAAAAAAAAAAAAAAAQETD/2gAIAQMBAT8ADr//xAAiEAADAAIBAwUBAAAAAAAAAAAAAQIDERIEIVEFEBUiMVP/2gAIAQEAAT8ANmXFGRfZD6e8VcsFuWT6n1OHtmjmvKPmsX869mxsbKe/04x4QxsbKoqjkNlMdFV3HRsbGymUymchvRTKZTGzZTKZTGxmyspWQdjsV7NlWOx2cxWcz//+AAMA/9k=",
  "type": "image",
  "timestamp": 1644547266,
  "from": "8613126768525@c.us",
  "to": "8613811286503@c.us",
  "deviceType": "ios",
  "isForwarded": false,
  "forwardingScore": 0,
  "isStatus": false,
  "isStarred": false,
  "fromMe": true,
  "hasQuotedMsg": false,
  "vCards": [],
  "mentionedIds": [],
  "isGif": false,
  "isEphemeral": false,
  "links": []
})
10: 41: 11 INFO PuppetWhatsApp onMessageAck({
  "id": {
    "fromMe": true,
    "remote": "8613811286503@c.us",
    "id": "3A71F8CA50E0135FAB4E",
    "_serialized": "true_8613811286503@c.us_3A71F8CA50E0135FAB4E"
  },
  "ack": 1,
  "hasMedia": false,
  "body": "/9j/4AAQSkZJRgABAQAAAQABAAD/2wBDABsSFBcUERsXFhceHBsgKEIrKCUlKFE6PTBCYFVlZF9VXVtqeJmBanGQc1tdhbWGkJ6jq62rZ4C8ybqmx5moq6T/2wBDARweHigjKE4rK06kbl1upKSkpKSkpKSkpKSkpKSkpKSkpKSkpKSkpKSkpKSkpKSkpKSkpKSkpKSkpKSkpKSkpKT/wgARCABIACkDASIAAhEBAxEB/8QAGQABAAMBAQAAAAAAAAAAAAAAAgABAwQF/8QAFwEBAQEBAAAAAAAAAAAAAAAAAAECA//aAAwDAQACEAMQAAAA9GVXfiOXrzlGmYl7BY1mCs5bFE7Qsw5rMowy9+YzseYMrJsgkAZC7kP/xAAWEQADAAAAAAAAAAAAAAAAAAAQETD/2gAIAQIBAT8ACr//xAAWEQADAAAAAAAAAAAAAAAAAAAQETD/2gAIAQMBAT8ADr//xAAiEAADAAIBAwUBAAAAAAAAAAAAAQIDERIEIVEFEBUiMVP/2gAIAQEAAT8ANmXFGRfZD6e8VcsFuWT6n1OHtmjmvKPmsX869mxsbKe/04x4QxsbKoqjkNlMdFV3HRsbGymUymchvRTKZTGzZTKZTGxmyspWQdjsV7NlWOx2cxWcz//+AAMA/9k=",
  "type": "image",
  "timestamp": 1644547266,
  "from": "8613126768525@c.us",
  "to": "8613811286503@c.us",
  "deviceType": "ios",
  "isForwarded": false,
  "forwardingScore": 0,
  "isStatus": false,
  "isStarred": false,
  "fromMe": true,
  "hasQuotedMsg": false,
  "vCards": [],
  "mentionedIds": [],
  "isGif": false,
  "isEphemeral": false,
  "links": []
})
10: 41: 11 INFO PuppetWhatsApp onMediaUploaded({
  "id": {
    "fromMe": true,
    "remote": "8613811286503@c.us",
    "id": "3A71F8CA50E0135FAB4E",
    "_serialized": "true_8613811286503@c.us_3A71F8CA50E0135FAB4E"
  },
  "ack": 1,
  "hasMedia": false,
  "body": "/9j/4AAQSkZJRgABAQAAAQABAAD/2wBDABsSFBcUERsXFhceHBsgKEIrKCUlKFE6PTBCYFVlZF9VXVtqeJmBanGQc1tdhbWGkJ6jq62rZ4C8ybqmx5moq6T/2wBDARweHigjKE4rK06kbl1upKSkpKSkpKSkpKSkpKSkpKSkpKSkpKSkpKSkpKSkpKSkpKSkpKSkpKSkpKSkpKSkpKT/wgARCABIACkDASIAAhEBAxEB/8QAGQABAAMBAQAAAAAAAAAAAAAAAgABAwQF/8QAFwEBAQEBAAAAAAAAAAAAAAAAAAECA//aAAwDAQACEAMQAAAA9GVXfiOXrzlGmYl7BY1mCs5bFE7Qsw5rMowy9+YzseYMrJsgkAZC7kP/xAAWEQADAAAAAAAAAAAAAAAAAAAQETD/2gAIAQIBAT8ACr//xAAWEQADAAAAAAAAAAAAAAAAAAAQETD/2gAIAQMBAT8ADr//xAAiEAADAAIBAwUBAAAAAAAAAAAAAQIDERIEIVEFEBUiMVP/2gAIAQEAAT8ANmXFGRfZD6e8VcsFuWT6n1OHtmjmvKPmsX869mxsbKe/04x4QxsbKoqjkNlMdFV3HRsbGymUymchvRTKZTGzZTKZTGxmyspWQdjsV7NlWOx2cxWcz//+AAMA/9k=",
  "type": "image",
  "timestamp": 1644547266,
  "from": "8613126768525@c.us",
  "to": "8613811286503@c.us",
  "deviceType": "ios",
  "isForwarded": false,
  "forwardingScore": 0,
  "isStatus": false,
  "isStarred": false,
  "fromMe": true,
  "hasQuotedMsg": false,
  "vCards": [],
  "mentionedIds": [],
  "isGif": false,
  "isEphemeral": false,
  "links": []
})
10: 41: 12 INFO PuppetWhatsApp onMessageAck({
  "mediaKey": "W8CqF3WwSNdrO4gQvRTMWBPaQnB63lhH38/GHUwRZtU=",
  "id": {
    "fromMe": true,
    "remote": "8613811286503@c.us",
    "id": "3A71F8CA50E0135FAB4E",
    "_serialized": "true_8613811286503@c.us_3A71F8CA50E0135FAB4E"
  },
  "ack": 2,
  "hasMedia": true,
  "body": "",
  "type": "image",
  "timestamp": 1644547266,
  "from": "8613126768525@c.us",
  "to": "8613811286503@c.us",
  "deviceType": "ios",
  "isForwarded": false,
  "forwardingScore": 0,
  "isStatus": false,
  "isStarred": false,
  "fromMe": true,
  "hasQuotedMsg": false,
  "vCards": [],
  "mentionedIds": [],
  "isGif": false,
  "isEphemeral": false,
  "links": []
})

方案

  1. 使用 messageImage 方法时 imageType 字段可以恢复使用。

    • PUPPET.ImageType.Thumbnail 时,直接使用 body 字段中的 base64 作为图片
    • PUPPET.ImageType.Artwork 时,需要调用 downloadMedia 方法
  2. 需要控制调用 downloadMedia 方法的时机,必须要在接收到 media_uploaded 事件后,且 hasMedia 字段为 true 时方可执行。

待确认

  1. downloadMedia 方法的耗时
  2. 除了图片消息之外的媒体消息的接收/上传策略

问题

  1. base64的缩略图特别模糊 image
windmemory commented 2 years ago

图片下载建议采用lazy load的方式,如果没有接收到请求,就不下载图片。 另外,通过本地缓存保存下来每个富媒体消息图片上传情况,如果请求下载的时候没有上传完,则做一个循环等待,并设置一个等待最大时间

su-chang commented 2 years ago

bot的手机端发送的图片消息,接收到的日志如下。当 onMediaUploaded 事件中 hasMedia 字段为false的情况下,无法获取到图片信息,只能拿到缩率图。

16:20:32 SILL PuppetWhatsApp Manager onMessageCreate({
  "id":{
    "fromMe":true,
    "remote":"120363021332004743@g.us",
    "id":"3A1E482D51D4B8BBC35F",
    "_serialized":"true_120x6302x33x00x74x@g.us_3A1E482D51D4B8BBC35F"
  },
  "ack":0,
  "hasMedia":false,
  "body":"/9j/4AAQSkZJRgABAQAAAQABAAD/2wBDABsSFBcUERsXFhceHBsgKEIrKCUlKFE6PTBCYFVlZF9VXVtqeJmBanGQc1tdhbWGkJ6jq62rZ4C8ybqmx5moq6T/2wBDARweHigjKE4rK06kbl1upKSkpKSkpKSkpKSkpKSkpKSkpKSkpKSkpKSkpKSkpKSkpKSkpKSkpKSkpKSkpKSkpKT/wgARCABIACkDASIAAhEBAxEB/8QAGgAAAgMBAQAAAAAAAAAAAAAAAAQCAwUBBv/EABYBAQEBAAAAAAAAAAAAAAAAAAABAv/aAAwDAQACEAMQAAAAW1MHcG84gd5KMqWzh6e5bVCKN8urxfOaSEtPSqlEMwsgZi17NPL6SUWxRIHAVHNCygA//8QAGhEAAwADAQAAAAAAAAAAAAAAARARAAIhMf/aAAgBAgEBPwCZIhw9zY0os+sv/8QAGBEAAgMAAAAAAAAAAAAAAAAAAAEQITD/2gAIAQMBAT8Al2hZ/wD/xAArEAACAQMCBQIGAwAAAAAAAAABAgADBBESIQUTIjFBUWEQFFJxgZEjJHL/2gAIAQEAAT8AoXCMwXBBMtV65cD+u0qnFVUHYCE4+FsxatTGPMJZKZKDJnzNww0mmftASa5DqQ2IylthOWZSRadwmN95UOkADzvKbfzZMqHN43+Zpz2micwc9SPBherVUFKeQPQzNZG1GkwEpOXumJBG3mYAWah6wHLAEZlpfG0pFNGRnMpsLi0WocLqlREW4wjatu8YZHU0wv1RFIcEiV9hFbTw+mvtKD8y4Kn0jUtu85Z9pdKekLtiVerSB5IjUj8uo9hKWhLg6iAcTnJjdh+5zaf1L+5TFS5rhaffEXhVw7rkAAHeGyRU3qMfzLy2o0GD5DBvUw1rYHq0z5i09pa39rSqMxGD2GBF4xb+Ax/E4lxE1nXlMyqBuJWqOydTk/cwmajP//4AAwD/2Q==",
  "type":"image",
  "timestamp":1644913232,
  "from":"8613x2x7x8x2x@c.us",
  "to":"120363021332004743@g.us",
  "deviceType":"ios",
  "isForwarded":false,
  "forwardingScore":0,
  "isStatus":false,
  "isStarred":false,
  "fromMe":true,
  "hasQuotedMsg":false,
  "vCards":[],
  "mentionedIds":[],
  "isGif":false,
  "isEphemeral":false,
  "links":[]
})
16:20:57 SILL PuppetWhatsApp Manager onMessageAck({
  "id":{
    "fromMe":true,
    "remote":"120363021332004743@g.us",
    "id":"3A1E482D51D4B8BBC35F",
    "_serialized":"true_120x6302x33x00x74x@g.us_3A1E482D51D4B8BBC35F"
  },
  "ack":1,
  "hasMedia":false,
  "body":"/9j/4AAQSkZJRgABAQAAAQABAAD/2wBDABsSFBcUERsXFhceHBsgKEIrKCUlKFE6PTBCYFVlZF9VXVtqeJmBanGQc1tdhbWGkJ6jq62rZ4C8ybqmx5moq6T/2wBDARweHigjKE4rK06kbl1upKSkpKSkpKSkpKSkpKSkpKSkpKSkpKSkpKSkpKSkpKSkpKSkpKSkpKSkpKSkpKSkpKT/wgARCABIACkDASIAAhEBAxEB/8QAGgAAAgMBAQAAAAAAAAAAAAAAAAQCAwUBBv/EABYBAQEBAAAAAAAAAAAAAAAAAAABAv/aAAwDAQACEAMQAAAAW1MHcG84gd5KMqWzh6e5bVCKN8urxfOaSEtPSqlEMwsgZi17NPL6SUWxRIHAVHNCygA//8QAGhEAAwADAQAAAAAAAAAAAAAAARARAAIhMf/aAAgBAgEBPwCZIhw9zY0os+sv/8QAGBEAAgMAAAAAAAAAAAAAAAAAAAEQITD/2gAIAQMBAT8Al2hZ/wD/xAArEAACAQMCBQIGAwAAAAAAAAABAgADBBESIQUTIjFBUWEQFFJxgZEjJHL/2gAIAQEAAT8AoXCMwXBBMtV65cD+u0qnFVUHYCE4+FsxatTGPMJZKZKDJnzNww0mmftASa5DqQ2IylthOWZSRadwmN95UOkADzvKbfzZMqHN43+Zpz2micwc9SPBherVUFKeQPQzNZG1GkwEpOXumJBG3mYAWah6wHLAEZlpfG0pFNGRnMpsLi0WocLqlREW4wjatu8YZHU0wv1RFIcEiV9hFbTw+mvtKD8y4Kn0jUtu85Z9pdKekLtiVerSB5IjUj8uo9hKWhLg6iAcTnJjdh+5zaf1L+5TFS5rhaffEXhVw7rkAAHeGyRU3qMfzLy2o0GD5DBvUw1rYHq0z5i09pa39rSqMxGD2GBF4xb+Ax/E4lxE1nXlMyqBuJWqOydTk/cwmajP//4AAwD/2Q==",
  "type":"image",
  "timestamp":1644913232,
  "from":"8613x2x7x8x2x@c.us",
  "to":"120363021332004743@g.us",
  "deviceType":"ios",
  "isForwarded":false,
  "forwardingScore":0,
  "isStatus":false,
  "isStarred":false,
  "fromMe":true,
  "hasQuotedMsg":false,
  "vCards":[],
  "mentionedIds":[],
  "isGif":false,
  "isEphemeral":false,
  "links":[]
})
16:20:57 SILL PuppetWhatsApp Manager onMediaUploaded({
  "id":{
    "fromMe":true,
    "remote":"120363021332004743@g.us",
    "id":"3A1E482D51D4B8BBC35F",
    "_serialized":"true_120x6302x33x00x74x@g.us_3A1E482D51D4B8BBC35F"
  },
  "ack":1,
  "hasMedia":false,
  "body":"/9j/4AAQSkZJRgABAQAAAQABAAD/2wBDABsSFBcUERsXFhceHBsgKEIrKCUlKFE6PTBCYFVlZF9VXVtqeJmBanGQc1tdhbWGkJ6jq62rZ4C8ybqmx5moq6T/2wBDARweHigjKE4rK06kbl1upKSkpKSkpKSkpKSkpKSkpKSkpKSkpKSkpKSkpKSkpKSkpKSkpKSkpKSkpKSkpKSkpKT/wgARCABIACkDASIAAhEBAxEB/8QAGgAAAgMBAQAAAAAAAAAAAAAAAAQCAwUBBv/EABYBAQEBAAAAAAAAAAAAAAAAAAABAv/aAAwDAQACEAMQAAAAW1MHcG84gd5KMqWzh6e5bVCKN8urxfOaSEtPSqlEMwsgZi17NPL6SUWxRIHAVHNCygA//8QAGhEAAwADAQAAAAAAAAAAAAAAARARAAIhMf/aAAgBAgEBPwCZIhw9zY0os+sv/8QAGBEAAgMAAAAAAAAAAAAAAAAAAAEQITD/2gAIAQMBAT8Al2hZ/wD/xAArEAACAQMCBQIGAwAAAAAAAAABAgADBBESIQUTIjFBUWEQFFJxgZEjJHL/2gAIAQEAAT8AoXCMwXBBMtV65cD+u0qnFVUHYCE4+FsxatTGPMJZKZKDJnzNww0mmftASa5DqQ2IylthOWZSRadwmN95UOkADzvKbfzZMqHN43+Zpz2micwc9SPBherVUFKeQPQzNZG1GkwEpOXumJBG3mYAWah6wHLAEZlpfG0pFNGRnMpsLi0WocLqlREW4wjatu8YZHU0wv1RFIcEiV9hFbTw+mvtKD8y4Kn0jUtu85Z9pdKekLtiVerSB5IjUj8uo9hKWhLg6iAcTnJjdh+5zaf1L+5TFS5rhaffEXhVw7rkAAHeGyRU3qMfzLy2o0GD5DBvUw1rYHq0z5i09pa39rSqMxGD2GBF4xb+Ax/E4lxE1nXlMyqBuJWqOydTk/cwmajP//4AAwD/2Q==",
  "type":"image",
  "timestamp":1644913232,
  "from":"8613x2x7x8x2x@c.us",
  "to":"120363021332004743@g.us",
  "deviceType":"ios",
  "isForwarded":false,
  "forwardingScore":0,
  "isStatus":false,
  "isStarred":false,
  "fromMe":true,
  "hasQuotedMsg":false,
  "vCards":[],
  "mentionedIds":[],
  "isGif":false,
  "isEphemeral":false,
  "links":[]
})
su-chang commented 2 years ago

Related issue: https://github.com/pedroslopez/whatsapp-web.js/issues/1200