美文网首页
开发一个将微信表情保存到相册,导出微信表情到电脑的工具,附带源码

开发一个将微信表情保存到相册,导出微信表情到电脑的工具,附带源码

作者: GLORIA_cfa5 | 来源:发表于2020-11-25 19:31 被阅读0次

    如果你想试试,或者不想了解原理,直接使用

    请在公众号 小面条工具 回复 机器人


    使用wechaty来开发一个用于将表情保存到相册的机器人

    起因

    为什么我要开发一个这样的机器人。

    从18年开始,网页版微信已经陆续被封禁,之前我们使用网页微信登录后,可以轻松获得表情的cdn地址,但是这种方法不可以了之后,我们现在仅仅能选择公众号网页后台的形式,下载表情包,但是这两种方式都需要借用电脑的帮助。

    如果仅仅用手机怎么办呢,那么我们只能选择其他的黑科技方式。

    我目前的思路一共是两种。

    • 1.使用无头浏览器挂网页公众号后台,解析协议。

    • 2.使用微信协议,写机器人,解析表情包cdn。

    最后经过我的调研之后选择了第二种,并且使用了wechaty来作为开发的库,并且使用的是‘wechaty-puppet-hostie’协议。

    因为wechaty使用node开发,所以我会同样使用nodejs作为开发语言

    话不多说 直接上代码,我会一步步讲解


    
    const { Wechaty } = require('wechaty')
    
    const { ScanStatus } = require('wechaty-puppet')
    
    const QrcodeTerminal = require('qrcode-terminal')
    
    const { FileBox } = require('file-box')
    
    const parseString = require('xml2js').parseString;
    
    

    首先引入这几个库。

    wechaty wechaty主库

    file-box wechaty 上传文件使用的库

    xml2js 解析xml的库


    
    const token = "xxx"
    
    const bot = new Wechaty({
    
      puppet: 'wechaty-puppet-hostie',
    
      puppetOptions: {
    
        token,
    
      }
    
    });
    
    

    初始化bot 这里面token 需要通过开源协议获取


    
    bot
    
      .on('scan', (qrcode, status) => {
    
        if (status === ScanStatus.Waiting) {
    
          QrcodeTerminal.generate(qrcode, {
    
            small: true
    
          })
    
        }
    
      })
    
      .on('login', async user => {
    
        console.log(`user: ${JSON.stringify(user)}`)
    
      })
    
    

    此处为二维码展示,和登录情况,

    那么接下来就是重点了。

    
    .on('message', async msg => {
    
        if (msg.self()) {
    
          // Don't deal with message from yourself.
    
          return
    
        }
    
        console.log(JSON.stringify(msg))
    
        console.log(msg.payload.fromId)
    
        let is_e = false
    
        const contact = msg.from()
    
        if (contact && msg.payload.text) {
    
          let xml = msg.payload.text;
    
          let pr = new Promise((resolve, reject) => {
    
            parseString(xml, function (err, result) {
    
              if (result && result.msg && result.msg.emoji && result.msg.emoji) {
    
                if (result.msg.emoji.length && result.msg.emoji.length > 0) {
    
                  if (result.msg.emoji[0].$ && result.msg.emoji[0].$.cdnurl) {
    
                    is_e = true
    
                  }
    
                }
    
              }
    
              if (is_e) {
    
                resolve(result.msg.emoji[0].$.cdnurl)
    
              } else {
    
                try {
    
                  if (result.msg.appmsg[0].type[0] === '8') {
    
                    contact.say('这张图片是分享图片,请删除后再添加,然后在发送')
    
                    reject()
    
                  }
    
                } catch (err) {
    
                  reject('1')
    
                }
    
              }
    
            });
    
          })
    
          let url
    
          try {
    
            url = await pr
    
            try {
    
              let user = msg.payload.fromId
    
              var timestamp = Date.parse(new Date()) / 1000
    
              if (um[user]) {
    
                if (timestamp - um[user] > miaoshu) {
    
                  um[user] = timestamp
    
                } else {
    
                  let contact = msg.from()
    
                  contact.say((miaoshu - (timestamp - um[user])) + '秒后可以继续使用')
    
                  return
    
                }
    
              } else {
    
                um[user] = timestamp
    
              }
    
            } catch (err) {
    
              return
    
            }
    
            url = url.replace('http://vweixinf.tc.qq.com', 'https://xxxxxxx')
    
          } catch (err) {
    
            if (err === '1') {
    
              await contact.say('我现在只会下载表情包~给我发送表情包就行了~')
    
            }
    
          }
    
        }
    
      })
    
    

    这段代码比较多,我一点点剖析

    
    if (msg.self()) {
    
          // Don't deal with message from yourself.
    
          return
    
        }
    
    

    此处的意思是 ,如果收到自己的消息,就不进行处理,很重要,因为每次发消息,bot自身也会接受到一个消息。

    
    const contact = msg.from()
    
    

    此处为 必须是用户发来的消息我们才解析

    
    let pr = new Promise((resolve, reject) => {
    
        ...
    
    }
    
    

    这个promise 为 解析xml如果 ,并且我处理了无法分析的表情包,如果解析成功,会resolve(url)


    
    try {
    
                        let user = msg.payload.fromId
    
                        var timestamp = Date.parse(new Date()) / 1000
    
                        if (um[user]) {
    
                            if (timestamp - um[user] > miaoshu) {
    
                                um[user] = timestamp
    
                            } else {
    
                                let contact = msg.from()
    
                                contact.say((miaoshu - (timestamp - um[user])) + '秒后可以继续使用')
    
                                return
    
                            }
    
                        } else {
    
                            um[user] = timestamp
    
                        }
    
                    } catch (err) {
    
                        return
    
                    }
    
    

    此处我加了一个 限制,20秒内才能下载一个 在上面必须定义一下时间

    
    let um = {}
    
    let miaoshu = 20
    
    

    
    url = url.replace('http://vweixinf.tc.qq.com', 'https://xxxxxxx')
    
    

    这里是因为这个域名不支持https 所以我将这个域名用nginx 反向代理到了我自己的服务器用于下载

    最后

    
    .on('friendship', async friendship => {
    
            console.log(JSON.stringify(friendship))
    
              friendship.accept().catch(async (err) => {
    
                  console.log(err)
    
              })
    
        })
    
        .start()
    
    

    加上秒通过,这样你下载表情的工具就完成了,我会将源码放到github 有需要的话直接使用即可。

    github地址 https://github.com/channg/wechaty-getwechatmeme

    最后说一下微信包 cdn地址 分好多种,只有我replace的那种不支持https,如果需要https的话需要反向代理,其他的直接改成https即可

    相关文章

      网友评论

          本文标题:开发一个将微信表情保存到相册,导出微信表情到电脑的工具,附带源码

          本文链接:https://www.haomeiwen.com/subject/ekzniktx.html