共计 3062 个字符,预计需要花费 8 分钟才能阅读完成。
如果你想试试,或者不想理解原理,间接应用
请在公众号 小面条工具 回复 机器人
应用 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 这外面 toke 须要通过开源协定获取
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 即可