微信机器人之开发体验

前言

目前在公司中的消息通知大部分使用邮件、短信、钉钉、App通知、websocket通知、微信企业版等等,针对于QQ和微信这种目前使用量较大的工具,通知机制并不完善。当然,主要是TX本身的功能要求决定了无法做类似的通知。
本篇文章主要讨论微信机器人的开发经验。

可选方案

桌面工具

这类的工具主要是嫁接到微信的桌面工具来使用,基于微信的windows客户端的功能做了节选。使用比较简单,但相对并不是很安全,工具也不够完整。

浏览器工具

浏览器工具是基于微信网页版进行开发,作为开发者来说,这类工具最受开发者欢迎,不需要服务器,只需要了解网页版API调用过程,就可以实现想要的功能。但是现在微信对网页版登录是有很多限定的,大部分微信已经不允许登录网页版了。而且网页版工具也有很大的限制,功能也不够完整,无法代替微信。

win sock开发

这个开发说得直白一些,是“桌面工具”的前提,桌面工具无非就是用这个方法分析并开发出来的。这个开发会很困难,相当于是解析微信windows客户端的exe文件,也有很大的风险,毕竟不是官方认可的内容。

iPad协议开发

ipad协议是微信在ipad上提供的一种接口协议,这个协议目前可使用的内容上来说,是功能最全的,只要分析出ipad协议的接口,就可以使用相应的功能,在ipad上的功能也是很全的。难点是,目前对ipad协议并没有被微信公开,只是很多公司有私下的研究公布,自己分析代价很大。

wechaty

基本信息

wechaty是句子科技使用nodeJS针对于微信开发出来的协议,其中包含网页版和ipad协议。wechaty github地址是: https://github.com/wechaty/wechaty
wechaty默认使用时是基于网页版协议的,如果需要使用ipad协议,需要在github上做申请,会有专人审核接入。

开发之前

我使用时是基于wechaty-puppet-padplus协议做的开发。
具体的可以参考:https://github.com/wechaty/wechaty-getting-started

环境准备

linux
node
typescript
微信
基于node:10.15.0-alpine系统需要对操作系统有一些初始化操作:

apk add build-base
apk add zlib-dev
apk add python
npm config set registry https://registry.npm.taobao.org
npm config set disturl https://npm.taobao.org/dist

开发过程

在开发过程中使用ts-node命令进行执行(对于typescript小白来说也查了很多资料)。
先把github上例子的ts文件拿下来执行,创建执行脚本:

export PATH=$PATH:/wechaty/padplus/node_modules/.bin/
ts-node $1

会自动提示登录二维码,例子中发送的消息会自动返回。

工具使用

我对wechaty的基本需求有两点:
1.定时的自动向指定人员发送变化的消息,面对不同人员不同时间发送不同的消息;
2.为其他程序端提供相应的接口。
因此,我做了一个mybot.ts:

import { Wechaty,Message       } from 'wechaty'
import { PuppetPadplus } from 'wechaty-puppet-padplus'
import { generate      } from 'qrcode-terminal'
import * as express from 'express';
import * as urlencode from 'urlencode';
import * as bodyParser from 'body-parser';

const urlencodedParser = bodyParser.urlencoded({ extended: false })
const token = 'xxxxxxxx' //此处需要替换你自己申请的token

const puppet = new PuppetPadplus({
  token,
})

const name  = 'anan'
const app = express(); // 用于声明服务器端所能提供的http服务


const bot = new Wechaty({
  puppet,
  name, // generate xxxx.memory-card.json and save login data for the next login
})

bot
  .on('scan', onScan)
  .on('message', onMessage )
  .start()
  
function onScan (qrcode, status) {
  generate(qrcode, { small: true })  // show qrcode on console
}
async function onMessage(msg){
    console.log("=============================")
    if (msg.self() || msg.from().name() === '微信团队') {
        console.log("myself message")
        return
    }
    console.log(`msg : ${msg}`)
    console.log(`from: ${msg.from().name()}: ${msg.from().id}`)
    console.log(`to: ${msg.to()}`)
    console.log(`text: ${msg.text()}`)
    console.log(`isRoom: ${msg.room()}`)
    

    console.log("=============================")
    if (msg.type() == Message.Type.Text) {
        if (msg.room()){
            const topic = await msg.room().topic()
            console.log(`roomTopic: ${topic}`)
            const room = await msg.room()
            const memberList = await room.memberList()
            for (let i = 0; i  {
    resp.send("Hello Express");
});
 
app.get("/send",urlencodedParser, (req, resp) => {
console.log(`url: ${req.url}`)
console.log(decodeURI(req.url))
//decodeURI(decodeURIComponent(escape(req.url)), "UTF-8")
    //const req = decodeURI(request)
    const contactvalue = decodeURI(req.query.contact)
    const contacttypevalue = decodeURI(req.query.contacttype)
    const messagevalue = decodeURI(req.query.message).replace(/\\n/g,"\n")
    const msgtypevalue = decodeURI(req.query.msgtype)
    const metionvalue = decodeURI(req.query.metion)
    console.log(`query:${contactvalue},${contacttypevalue},${messagevalue},${msgtypevalue},${metionvalue}`)
    sendMessage(contactvalue, contacttypevalue, messagevalue, msgtypevalue, metionvalue)
    resp.send("接收到商品查询请求");
});
 
const server = app.listen(8000, "localhost", () => {
    console.log("服务器已启动, 地址是:http://localhost:8000");
});

这个机器人主要做的是开通了一个send的http get方法,直接通过浏览器访问此接口就可以发送消息,另外还可以扩展方法来获取微信上的信息。
于是针对需求1的定时发送,我做了如下的脚本:

curl -G --data-urlencode "contact=中文测试" --data-urlencode "message=${message}" http://127.0.0.1:8000/send?contacttype=room\&msgtype=text

我们可以通过定时的执行这个脚本,就可以发送给相应的人或者群消息了,这个脚本里有很多都可以做成参数。

contact:人或者群名称
message:消息的详细内容
contacttype:room/person标识群或者个人
msgtype:定义消息的类型
注意此处对应中文的地方,一定要用urlencode,否则系统无法检索和识别

总结

目前市面上可以使用的,免费的,功能较全的,还是wechaty比较好,所以推荐给大家使用。