WeChatRemote是一个微信远程调用工具,使用MQTT连接本地或云端微信客户端实现远程操作
- 支持所有的Wechaty Puppet
- 解耦Wechaty客户端与业务应用服务端,使用熟悉语言实现MQTT Client即可调用
- 本地运行bot,远程接收消息和调用bot发消息
npm i wechat-remote
首先启动一个wechaty客户端(目前仅支持nodejs),并使用mqtt-wechaty插件 机器人可以运行在本地或云服务器中,只需要可以访问外网,不需要配置外网IP
import { WechatyBuilder } from 'wechaty'
import {
QRCodeTerminal,
MqttGateway,
MqttGatewayConfig,
} from 'wechat-remote'
const bot = WechatyBuilder.build({
name : 'ding-dong-bot',
})
const config: MqttGatewayConfig = {
events: [
'login',
'logout',
'reset',
'ready',
'dirty',
'dong',
'error',
// 'heartbeat',
'friendship',
'message', 'post',
'room-invite', 'room-join',
'room-leave', 'room-topic',
'scan',
],
mqtt: {
clientId: 'ding-dong-test01', // 替换成自己的clientId,建议不少于16个字符串
host: 'broker.emqx.io',
password: '',
port: 1883,
username: '',
},
options:{
secrectKey: '',
simple: false,
},
token: '',
}
bot.use(
MqttGateway(config),
QRCodeTerminal(),
)
bot.start()
.catch(console.error)
使用MQTT可视化工具调用接口,可以快速理解学习WeChatRemote使用
- 访问 http://www.emqx.io/online-mqtt-client ,配置并连接MQTT
- 订阅如下主题,其中的“chatbot/”之后的“+”可以换成具体的clientId
- 接收事件 thing/chatbot/+/event/post
- 应用端下发指令 thing/chatbot/+/command/invoke
- 接收响应 thing/chatbot/+/response/d2c/+
- 查询机器人状态,向 thing/chatbot/ding-dong-test01/command/invoke 主题发布如下payload:
{
"reqId":"2a42cff1-bfb5-4d5d-b185-353c8c71a00b",
"method":"command",
"version":"1.0",
"timestamp":1705384610041,
"name":"wechatyLogonoff",
"params":{}
}
4. 向指定好友发送消息,向 thing/chatbot/ding-dong-test01/command/invoke 主题发布如下payload:
{
"reqId":"2a42cff1-bfb5-4d5d-b185-353c8c71a00b",
"method":"command",
"version":"1.0",
"timestamp":1705384610041,
"name":"contactSay",
"params":{
"contacts":["atorber"],
"messageType":"Text",
"messagePayload":"hello"
}
}
下载安装MQTTX https://mqttx.app/zh/downloads 可以使用客户端更加稳定
以下是几种常用语言的SimpleCode,后续考虑提供SDK,期待大家贡献各种语言的sdk
- 安装依赖
npm install mqtt
- 接收消息
const mqtt = require('mqtt');
// MQTT 服务器设置
const MQTT_BROKER_URL = 'mqtt://your-mqtt-broker-url';
const TOPIC = 'thing/chatbot/xxxx/event/post';
const MQTT_PORT = 1883; // 替换为你的 MQTT 服务器端口
const USERNAME = 'your-username'; // 替换为你的用户名
const PASSWORD = 'your-password'; // 替换为你的密码
// 连接选项
const options = {
port: MQTT_PORT,
username: USERNAME,
password: PASSWORD,
};
// 创建 MQTT 客户端
const client = mqtt.connect(MQTT_BROKER_URL, options);
client.on('connect', () => {
console.log('Connected to MQTT Broker:', MQTT_BROKER_URL);
// 订阅指定主题
client.subscribe(TOPIC, (err) => {
if (!err) {
console.log(`Subscribed to topic: ${TOPIC}`);
} else {
console.error(`Failed to subscribe: ${err}`);
}
});
});
client.on('message', (topic, message) => {
if (topic === TOPIC) {
try {
// 尝试解析消息为 JSON
const jsonMessage = JSON.parse(message.toString());
console.log('Received JSON Message:', jsonMessage);
} catch (error) {
console.error('Received non-JSON message:', message.toString());
}
}
});
client.on('error', (error) => {
console.error('MQTT Client Error:', error);
});
- 调用API
const mqtt = require('mqtt');
const MQTT_BROKER_URL = 'mqtt://your-mqtt-broker-url';
const COMMAND_TOPIC = 'thing/chatbot/xxxx/command/invoke';
const RESPONSE_TOPIC = 'thing/chatbot/xxxx/response/d2c/+';
const MQTT_PORT = 1883; // 或者你的 MQTT 服务器端口
const USERNAME = 'your-username'; // 或者你的用户名
const PASSWORD = 'your-password'; // 或者你的密码
const message = {
reqId: "2a42cff1-bfb5-4d5d-b185-353c8c71a00b",
method: "command",
version: "1.0",
timestamp: 1705384610041,
name: "contactSay",
params: {
contacts: ["ledongmao", "choogoo"],
messageType: "Text",
messagePayload: "hello"
}
};
const options = {
port: MQTT_PORT,
username: USERNAME,
password: PASSWORD,
};
const client = mqtt.connect(MQTT_BROKER_URL, options);
client.on('connect', () => {
console.log('Connected to MQTT Broker:', MQTT_BROKER_URL);
// 订阅响应主题
client.subscribe(RESPONSE_TOPIC, (err) => {
if (!err) {
console.log(`Subscribed to response topic: ${RESPONSE_TOPIC}`);
} else {
console.error(`Failed to subscribe: ${err}`);
}
});
// 发布命令消息
client.publish(COMMAND_TOPIC, JSON.stringify(message));
console.log(`Message published to command topic: ${COMMAND_TOPIC}`);
});
client.on('message', (topic, message) => {
console.log(`Received message from ${topic}: ${message.toString()}`);
});
client.on('error', (error) => {
console.error('MQTT Client Error:', error);
});
- 安装依赖
npm install mqtt
npm install @types/node --save-dev
- 接收消息
import * as mqtt from 'mqtt';
// MQTT 服务器设置
const MQTT_BROKER_URL = 'mqtt://your-mqtt-broker-url';
const TOPIC = 'thing/chatbot/xxxx/event/post';
const MQTT_PORT = 1883; // 替换为你的 MQTT 服务器端口
const USERNAME = 'your-username'; // 替换为你的用户名
const PASSWORD = 'your-password'; // 替换为你的密码
// 连接选项
const options: mqtt.IClientOptions = {
port: MQTT_PORT,
username: USERNAME,
password: PASSWORD,
};
// 创建 MQTT 客户端
const client = mqtt.connect(MQTT_BROKER_URL, options);
client.on('connect', () => {
console.log('Connected to MQTT Broker:', MQTT_BROKER_URL);
// 订阅指定主题
client.subscribe(TOPIC, (err) => {
if (!err) {
console.log(`Subscribed to topic: ${TOPIC}`);
} else {
console.error(`Failed to subscribe: ${err}`);
}
});
// 订阅指定主题
client.subscribe(TOPIC, (err) => {
if (!err) {
console.log(`Subscribed to topic: ${TOPIC}`);
} else {
console.error(`Failed to subscribe: ${err}`);
}
});
});
client.on('message', (topic, message) => {
if (topic === TOPIC) {
try {
// 尝试解析消息为 JSON
const jsonMessage = JSON.parse(message.toString());
console.log('Received JSON Message:', jsonMessage);
} catch (error) {
console.error('Received non-JSON message:', message.toString());
}
}
});
client.on('error', (error) => {
console.error('MQTT Client Error:', error);
});
- 调用API
import * as mqtt from 'mqtt';
import type { IClientOptions, MqttClient } from 'mqtt';
const MQTT_BROKER_URL: string = 'mqtt://your-mqtt-broker-url';
const COMMAND_TOPIC: string = 'thing/chatbot/xxxx/command/invoke';
const RESPONSE_TOPIC: string = 'thing/chatbot/xxxx/response/d2c/+';
const MQTT_PORT: number = 1883; // 或者你的 MQTT 服务器端口
const USERNAME: string = 'your-username'; // 或者你的用户名
const PASSWORD: string = 'your-password'; // 或者你的密码
interface Message {
reqId: string;
method: string;
version: string;
timestamp: number;
name: string;
params: {
contacts: string[];
messageType: string;
messagePayload: string;
};
}
const message: Message = {
reqId: "2a42cff1-bfb5-4d5d-b185-353c8c71a00b",
method: "command",
version: "1.0",
timestamp: 1705384610041,
name: "contactSay",
params: {
contacts: ["ledongmao", "choogoo"],
messageType: "Text",
messagePayload: "hello"
}
};
const options: IClientOptions = {
port: MQTT_PORT,
username: USERNAME,
password: PASSWORD,
};
const client: MqttClient = mqtt.connect(MQTT_BROKER_URL, options);
client.on('connect', () => {
console.log('Connected to MQTT Broker:', MQTT_BROKER_URL);
// 订阅响应主题
client.subscribe(RESPONSE_TOPIC, (err) => {
if (!err) {
console.log(`Subscribed to response topic: ${RESPONSE_TOPIC}`);
} else {
console.error(`Failed to subscribe: ${err}`);
}
});
// 发布命令消息
client.publish(COMMAND_TOPIC, JSON.stringify(message));
console.log(`Message published to command topic: ${COMMAND_TOPIC}`);
});
client.on('message', (topic: string, message: Buffer) => {
console.log(`Received message from ${topic}: ${message.toString()}`);
});
client.on('error', (error: Error) => {
console.error('MQTT Client Error:', error);
});
- 安装依赖
pip install paho-mqtt
- 接收消息
import json
import paho.mqtt.client as mqtt
# MQTT 服务器设置
MQTT_BROKER_URL = 'mqtt://your-mqtt-broker-url'
TOPIC = 'thing/chatbot/xxxx/event/post'
MQTT_PORT = 1883 # 替换为你的 MQTT 服务器端口
USERNAME = 'your-username' # 替换为你的用户名
PASSWORD = 'your-password' # 替换为你的密码
# 连接成功回调函数
def on_connect(client, userdata, flags, rc):
print(f'Connected to MQTT Broker: {MQTT_BROKER_URL}')
client.subscribe(TOPIC)
print(f'Subscribed to topic: {TOPIC}')
# 接收消息回调函数
def on_message(client, userdata, msg):
if msg.topic == TOPIC:
try:
# 尝试解析消息为 JSON
json_message = json.loads(msg.payload.decode())
print('Received JSON Message:', json_message)
except ValueError:
print('Received non-JSON message:', msg.payload.decode())
# MQTT 客户端设置
client = mqtt.Client()
client.username_pw_set(USERNAME, PASSWORD)
client.on_connect = on_connect
client.on_message = on_message
# 连接 MQTT Broker
client.connect(MQTT_BROKER_URL, MQTT_PORT, 60)
# 网络循环,以处理回调函数并保持脚本运行
client.loop_forever()
- 调用API
import json
import paho.mqtt.client as mqtt
MQTT_BROKER_URL = 'mqtt://your-mqtt-broker-url'
COMMAND_TOPIC = 'thing/chatbot/xxxx/command/invoke'
RESPONSE_TOPIC = 'thing/chatbot/xxxx/response/d2c/+'
MQTT_PORT = 1883 # 或者你的 MQTT 服务器端口
USERNAME = 'your-username' # 或者你的用户名
PASSWORD = 'your-password' # 或者你的密码
message = {
"reqId": "2a42cff1-bfb5-4d5d-b185-353c8c71a00b",
"method": "command",
"version": "1.0",
"timestamp": 1705384610041,
"name": "contactSay",
"params": {
"contacts": ["ledongmao", "choogoo"],
"messageType": "Text",
"messagePayload": "hello"
}
}
def on_connect(client, userdata, flags, rc):
print(f"Connected to MQTT Broker: {MQTT_BROKER_URL}")
# 订阅响应主题
client.subscribe(RESPONSE_TOPIC)
print(f"Subscribed to response topic: {RESPONSE_TOPIC}")
# 发布命令消息
client.publish(COMMAND_TOPIC, json.dumps(message))
print(f"Message published to command topic: {COMMAND_TOPIC}")
def on_message(client, userdata, msg):
print(f"Received message from {msg.topic}: {msg.payload.decode()}")
def on_error(client, userdata, rc):
print(f"MQTT Client Error: {rc}")
client = mqtt.Client()
client.username_pw_set(USERNAME, PASSWORD)
client.on_connect = on_connect
client.on_message = on_message
client.on_error = on_error
client.connect(MQTT_BROKER_URL.replace('mqtt://', ''), MQTT_PORT, 60)
client.loop_forever()
- 安装依赖
go get github.com/eclipse/paho.mqtt.golang
- 接收消息
package main
import (
"encoding/json"
"fmt"
"os"
"time"
mqtt "github.com/eclipse/paho.mqtt.golang"
)
const (
MQTT_BROKER_URL = "tcp://your-mqtt-broker-url:1883" // 注意更换为你的 MQTT 服务器地址和端口
TOPIC = "thing/chatbot/xxxx/event/post" // 更换为你的主题
USERNAME = "your-username" // 更换为你的用户名
PASSWORD = "your-password" // 更换为你的密码
)
func onConnectHandler(client mqtt.Client) {
if token := client.Subscribe(TOPIC, 0, onMessageReceivedHandler); token.Wait() && token.Error() != nil {
fmt.Println("Subscribe error:", token.Error())
os.Exit(1)
}
fmt.Println("Connected to MQTT Broker:", MQTT_BROKER_URL)
fmt.Println("Subscribed to topic:", TOPIC)
}
func onMessageReceivedHandler(client mqtt.Client, msg mqtt.Message) {
fmt.Printf("Received message on topic %s: %s\n", msg.Topic(), string(msg.Payload()))
var jsonMessage map[string]interface{}
if err := json.Unmarshal(msg.Payload(), &jsonMessage); err != nil {
fmt.Println("Error parsing JSON message:", err)
} else {
fmt.Println("Received JSON Message:", jsonMessage)
}
}
func main() {
opts := mqtt.NewClientOptions().AddBroker(MQTT_BROKER_URL).SetUsername(USERNAME).SetPassword(PASSWORD)
opts.SetDefaultPublishHandler(onMessageReceivedHandler)
opts.OnConnect = onConnectHandler
client := mqtt.NewClient(opts)
if token := client.Connect(); token.Wait() && token.Error() != nil {
fmt.Println("Connection error:", token.Error())
os.Exit(1)
}
// Keep the main function running until interrupted
select {}
}
- API调用
- 安装依赖
<dependencies>
<dependency>
<groupId>org.eclipse.paho</groupId>
<artifactId>org.eclipse.paho.client.mqttv3</artifactId>
<version>1.2.5</version>
</dependency>
</dependencies>
- 接收消息
import org.eclipse.paho.client.mqttv3.IMqttDeliveryToken;
import org.eclipse.paho.client.mqttv3.MqttCallback;
import org.eclipse.paho.client.mqttv3.MqttClient;
import org.eclipse.paho.client.mqttv3.MqttConnectOptions;
import org.eclipse.paho.client.mqttv3.MqttMessage;
import org.json.JSONObject;
public class MqttSubscribeSample {
public static void main(String[] args) {
final String brokerUrl = "tcp://your-mqtt-broker-url:1883"; // 替换为你的MQTT Broker的URL
final String topic = "thing/chatbot/xxxx/event/post"; // 替换为你的主题
final String clientId = "JavaClient";
final String username = "your-username"; // 替换为你的用户名
final String password = "your-password"; // 替换为你的密码
try {
MqttClient sampleClient = new MqttClient(brokerUrl, clientId);
MqttConnectOptions connOpts = new MqttConnectOptions();
connOpts.setCleanSession(true);
connOpts.setUserName(username);
connOpts.setPassword(password.toCharArray());
System.out.println("Connecting to broker: " + brokerUrl);
sampleClient.connect(connOpts);
System.out.println("Connected");
sampleClient.setCallback(new MqttCallback() {
@Override
public void connectionLost(Throwable cause) {
System.out.println("Connection lost!");
}
@Override
public void messageArrived(String topic, MqttMessage message) throws Exception {
System.out.println("Message arrived: " + message.toString());
try {
JSONObject jsonMessage = new JSONObject(message.toString());
System.out.println("Received JSON Message: " + jsonMessage.toString(2)); // Indent with 2 spaces
} catch (Exception e) {
System.out.println("Received non-JSON message: " + message.toString());
}
}
@Override
public void deliveryComplete(IMqttDeliveryToken token) {
// Not used in this example
}
});
System.out.println("Subscribing to topic: " + topic);
sampleClient.subscribe(topic);
} catch(Exception e) {
System.out.println("Exception: " + e.getMessage());
}
}
- API调用
import org.eclipse.paho.client.mqttv3.IMqttDeliveryToken;
import org.eclipse.paho.client.mqttv3.MqttCallback;
import org.eclipse.paho.client.mqttv3.MqttClient;
import org.eclipse.paho.client.mqttv3.MqttConnectOptions;
import org.eclipse.paho.client.mqttv3.MqttException;
import org.eclipse.paho.client.mqttv3.MqttMessage;
import org.json.JSONObject;
public class MqttClientDemo {
private static final String MQTT_BROKER_URL = "tcp://your-mqtt-broker-url:1883";
private static final String COMMAND_TOPIC = "thing/chatbot/xxxx/command/invoke";
private static final String RESPONSE_TOPIC = "thing/chatbot/xxxx/response/d2c/+";
private static final String USERNAME = "your-username";
private static final String PASSWORD = "your-password";
public static void main(String[] args) {
try {
MqttClient client = new MqttClient(MQTT_BROKER_URL, MqttClient.generateClientId());
MqttConnectOptions options = new MqttConnectOptions();
options.setUserName(USERNAME);
options.setPassword(PASSWORD.toCharArray());
client.setCallback(new MqttCallback() {
@Override
public void connectionLost(Throwable cause) {
System.out.println("MQTT Client Error: " + cause.getMessage());
}
@Override
public void messageArrived(String topic, MqttMessage message) {
System.out.println("Received message from " + topic + ": " + new String(message.getPayload()));
}
@Override
public void deliveryComplete(IMqttDeliveryToken token) {
}
});
client.connect(options);
System.out.println("Connected to MQTT Broker: " + MQTT_BROKER_URL);
client.subscribe(RESPONSE_TOPIC);
System.out.println("Subscribed to response topic: " + RESPONSE_TOPIC);
JSONObject message = new JSONObject();
message.put("reqId", "2a42cff1-bfb5-4d5d-b185-353c8c71a00b");
message.put("method", "command");
message.put("version", "1.0");
message.put("timestamp", 1705384610041L);
message.put("name", "contactSay");
JSONObject params = new JSONObject();
params.put("contacts", new String[]{"ledongmao", "choogoo"});
params.put("messageType", "Text");
params.put("messagePayload", "hello");
message.put("params", params);
client.publish(COMMAND_TOPIC, new MqttMessage(message.toString().getBytes()));
System.out.println("Message published to command topic: " + COMMAND_TOPIC);
} catch (MqttException e) {
e.printStackTrace();
}
}
}
其他语言示例欢迎在评论里粘贴代码或提需求,也可以交给GPTs 多语言代码转换大师
:::warning 目前仅实现了常用API的支持,其他API需求可以在评论中留言,当然API的范围不能超出Wechaty支持范围 ::: 远程调用调用端向 thing/chatbot/${clinetId}/command/invoke发送调用指令(其中${clinetId}表示具体的clientId) Wechaty客户端接收到指令后向thing/chatbot/${clinetId}/response/d2c/${reqId}主题推送响应消息 应用端订阅响应消息:
- 订阅指定请求消息:thing/chatbot/xxxx/response/d2c/1234
- 订阅所有请求消息:thing/chatbot/xxxx/response/d2c/+
- 请求
{
"reqId":"2a42cff1-bfb5-4d5d-b185-353c8c71a00b",
"method":"command",
"version":"1.0",
"timestamp":1705384610041,
"name":"wechatyLogonoff",
"params":{}
}
- 响应
{
"reqId": "2a42cff1-bfb5-4d5d-b185-353c8c71a00b",
"method": "response",
"version": "1.0",
"timestamp": 1705408082094,
"name": "wechatyLogonoff",
"code": 200,
"message": "success",
"params": {
"logonoff": true
}
}
- 请求
{
"reqId":"2a42cff1-bfb5-4d5d-b185-353c8c71a00b",
"method":"command",
"version":"1.0",
"timestamp":1705384610041,
"name":"wechatyUserSelf",
"params":{}
}
- 响应
{
"reqId": "2a42cff1-bfb5-4d5d-b185-353c8c71a00b",
"method": "response",
"version": "1.0",
"timestamp": 1705408574486,
"name": "wechatyUserSelf",
"code": 200,
"message": "success",
"params": {
"_events": {},
"_eventsCount": 0,
"id": "@a4c7b5b71eb79b5f790f5d4c2270b0f3b787952a3a8ca08b228efe4832021299",
"payload": {
"alias": "",
"avatar": "/cgi-bin/mmwebwx-bin/webwxgeticon?seq=1851844649&username=@a4c7b5b71eb79b5f790f5d4c2270b0f3b787952a3a8ca08b228efe4832021299&skey=@crypt_3f47a99d_1d59eeac1c79b47948fa86522b106b12",
"friend": false,
"gender": 2,
"id": "@a4c7b5b71eb79b5f790f5d4c2270b0f3b787952a3a8ca08b228efe4832021299",
"name": "瓦力",
"phone": [],
"star": false,
"type": 1
}
}
}
- 请求
{
"reqId":"2a42cff1-bfb5-4d5d-b185-353c8c71a00b",
"method":"command",
"version":"1.0",
"timestamp":1705384610041,
"name":"contactFindAll",
"params":{
"size":100
}
}
- 响应
{
"reqId":"2a42cff1-bfb5-4d5d-b185-353c8c71a00b",
"method":"response",
"version":"1.0",
"timestamp":1705384610041,
"code":200,
"message":"success",
"name":"contactFindAll",
"params":{
"page":1,
"size":100,
"total":3500,
"items":[
{
"_events":{
},
"_eventsCount":0,
"id":"@a4c7b5b71eb79b5f790f5d4c2270b0f3b787952a3a8ca08b228efe4832021299",
"payload":{
"alias":"",
"avatar":"/cgi-bin/mmwebwx-bin/webwxgeticon?seq=11550719&username=@a4c7b5b71eb79b5f790f5d4c2270b0f3b787952a3a8ca08b228efe4832021299&skey=@crypt_3f47a99d_1d59eeac1c79b47948fa86522b106b12",
"friend":false,
"gender":2,
"id":"@a4c7b5b71eb79b5f790f5d4c2270b0f3b787952a3a8ca08b228efe4832021299",
"name":"瓦力",
"phone":[
],
"star":false,
"type":1
}
},
{
"_events":{
},
"_eventsCount":0,
"id":"@a4c7b5b71eb79b5f790f5d4c2270b0f3b787952a3a8ca08b228efe4832021299",
"payload":{
"alias":"",
"avatar":"/cgi-bin/mmwebwx-bin/webwxgeticon?seq=11550719&username=@a4c7b5b71eb79b5f790f5d4c2270b0f3b787952a3a8ca08b228efe4832021299&skey=@crypt_3f47a99d_1d59eeac1c79b47948fa86522b106b12",
"friend":false,
"gender":2,
"id":"@a4c7b5b71eb79b5f790f5d4c2270b0f3b787952a3a8ca08b228efe4832021299",
"name":"瓦力",
"phone":[
],
"star":false,
"type":1
}
}
]
}
}
- 请求
alias、id、name至少填写一个
{
"reqId":"2a42cff1-bfb5-4d5d-b185-353c8c71a00b",
"method":"command",
"version":"1.0",
"timestamp":1705384610041,
"name":"contactFind",
"params":{
"alias":"",
"id":"@a4c7b5b71eb79b5f790f5d4c2270b0f3b787952a3a8ca08b228efe4832021299",
"name":"瓦力"
}
}
- 响应
{
"reqId":"2a42cff1-bfb5-4d5d-b185-353c8c71a00b",
"method":"response",
"version":"1.0",
"timestamp":1705384610041,
"code":200,
"message":"success",
"name":"contactFind",
"params":{
"_events":{},
"_eventsCount":0,
"id":"@a4c7b5b71eb79b5f790f5d4c2270b0f3b787952a3a8ca08b228efe4832021299",
"payload":{
"alias":"",
"avatar":"/cgi-bin/mmwebwx-bin/webwxgeticon?seq=11550719&username=@a4c7b5b71eb79b5f790f5d4c2270b0f3b787952a3a8ca08b228efe4832021299&skey=@crypt_3f47a99d_1d59eeac1c79b47948fa86522b106b12",
"friend":false,
"gender":2,
"id":"@a4c7b5b71eb79b5f790f5d4c2270b0f3b787952a3a8ca08b228efe4832021299",
"name":"瓦力",
"phone":[],
"star":false,
"type":1
}
}
}
目前仅支持发送文本消息,图片、文件、视频、语音等消息即将支持
- 请求
{
"reqId":"2a42cff1-bfb5-4d5d-b185-353c8c71a00b",
"method":"command",
"version":"1.0",
"timestamp":1705384610041,
"name":"contactSay",
"params":{
"contacts":[
"ledongmao",
"choogoo"
],
"messageType":"Text",
"messagePayload":"hello"
}
}
- 响应
返回发送结果列表
{
"reqId":"2a42cff1-bfb5-4d5d-b185-353c8c71a00b",
"method":"response",
"version":"1.0",
"timestamp":1705384610041,
"code":200,
"message":"success",
"name":"contactSay",
"params":{
"success":[],
"fail":[]
}
}
- 请求
{
"reqId":"2a42cff1-bfb5-4d5d-b185-353c8c71a00b",
"method":"command",
"version":"1.0",
"timestamp":1705384610041,
"name":"roomFindAll",
"params":{
"size":100
}
}
- 响应
{
"reqId":"2a42cff1-bfb5-4d5d-b185-353c8c71a00b",
"method":"response",
"version":"1.0",
"timestamp":1705384610041,
"code":200,
"message":"success",
"name":"roomFindAll",
"params":{
"page":1,
"size":100,
"count":3500,
"items":[
{
"_events":{},
"_eventsCount":0,
"id":"19036636423@chatroom",
"payload":{
"adminIdList":[],
"avatar":"",
"external":false,
"id":"19036636423@chatroom",
"ownerId":"",
"topic":"宁波金茂汇项目团队"
}
},
{
"_events":{},
"_eventsCount":0,
"id":"19036636423@chatroom",
"payload":{
"adminIdList":[],
"avatar":"",
"external":false,
"id":"19036636423@chatroom",
"ownerId":"",
"topic":"宁波金茂汇项目团队"
}
}
]
}
}
- 请求
{
"reqId":"2a42cff1-bfb5-4d5d-b185-353c8c71a00b",
"method":"command",
"version":"1.0",
"timestamp":1705384610041,
"name":"roomFind",
"params":{
"id":"@a4c7b5b71eb79b5f790f5d4c2270b0f3b787952a3a8ca08b228efe4832021299",
"topic":"瓦力是群主"
}
}
- 响应
{
"reqId": "2a42cff1-bfb5-4d5d-b185-353c8c71a00b",
"method": "response",
"version": "1.0",
"timestamp": 1705418869966,
"name": "roomFind",
"code": 200,
"message": "success",
"params": {
"_events": {},
"_eventsCount": 0,
"id": "5550027590@chatroom",
"payload": {
"adminIdList": [
"wxid_m7kf9tq12"
],
"avatar": "",
"external": false,
"id": "5550027590@chatroom",
"memberIdList": [
"wxid_m7kf9tq12",
"tyutl",
"wxid_0f57221"
],
"ownerId": "wxid_m7kf9tq12",
"topic": "瓦力是群主"
}
}
}
- 请求
id、topic至少填写一项
{
"reqId":"2a42cff1-bfb5-4d5d-b185-353c8c71a00b",
"method":"command",
"version":"1.0",
"timestamp":1705384610041,
"name":"roomMemberAllGet",
"params":{
"size":100,
"id":"@a4c7b5b71eb79b5f790f5d4c2270b0f3b787952a3a8ca08b228efe4832021299",
"topic":"瓦力是群主"
}
}
- 响应
{
"reqId": "2a42cff1-bfb5-4d5d-b185-353c8c71a00b",
"method": "response",
"version": "1.0",
"timestamp": 1705462410448,
"name": "roomMemberAllGet",
"code": 200,
"message": "success",
"params": {
"page": 1,
"size": 100,
"total": 3,
"items": [
{
"_events": {},
"_eventsCount": 0,
"id": "wxid_pnza7m7kf9tq12",
"payload": {
"alias": "",
"friend": true,
"id": "wxid_pnza7m7kf9tq12",
"name": "瓦力",
"phone": [],
"type": 1
}
},
{
"_events": {},
"_eventsCount": 0,
"id": "tyutluyc",
"payload": {
"alias": "超哥",
"friend": true,
"id": "tyutluyc",
"name": "luyuchao",
"phone": [],
"type": 1
}
},
{
"_events": {},
"_eventsCount": 0,
"id": "wxid_0o1t51l3f57221",
"payload": {
"alias": "",
"avatar": "https://wx.qlogo.cn/mmhead/ver_1/xUlBgtTamVSCTw5KnGTxusBCT6eSQSgwDoRnp18ICZRp5JcWWFju1aLCzj5UurApCMDcLmfGOyxvDSwPL9yyoIB9zug49f5QjbI2HTk4ib1w/132",
"friend": false,
"gender": 0,
"id": "wxid_0o1t51l3f57221",
"name": "大师",
"phone": [],
"type": 1
}
}
]
}
}
目前仅支持发送文本消息,图片、文件、视频、语音等消息即将支持
- 请求
{
"reqId":"2a42cff1-bfb5-4d5d-b185-353c8c71a00b",
"method":"command",
"version":"1.0",
"timestamp":1705384610041,
"name":"roomSay",
"params":{
"rooms":[
"ledongmao@chat.room"
],
"messageType":"Text",
"messagePayload":"hello"
}
}
- 响应
{
"reqId": "2a42cff1-bfb5-4d5d-b185-353c8c71a00b",
"method": "response",
"version": "1.0",
"timestamp": 1705461448305,
"name": "roomSay",
"code": 200,
"message": "success",
"params": {
"id": "ledongmao@chat.room"
}
}
有瑕疵,调试中...
- 请求
{
"reqId":"2a42cff1-bfb5-4d5d-b185-353c8c71a00b",
"method":"command",
"version":"1.0",
"timestamp":1705384610041,
"name":"roomSayAt",
"params":{
"contacts":[
"ledongmao",
"choogoo"
],
"room":"ledongmao@chat.room",
"messageType":"Text",
"messagePayload":"hello"
}
}
- 响应
{
"reqId": "2a42cff1-bfb5-4d5d-b185-353c8c71a00b",
"method": "response",
"version": "1.0",
"timestamp": 1705462056289,
"name": "roomSayAt",
"code": 200,
"message": "success"
}
- 请求
{
"reqId":"2a42cff1-bfb5-4d5d-b185-353c8c71a00b",
"method":"command",
"version":"1.0",
"timestamp":1705384610041,
"name":"messageSay",
"params":{
"id":"xxxxx",
"messageType":"Text",
"messagePayload":"hello"
}
}
- 响应
{
"reqId": "2a42cff1-bfb5-4d5d-b185-353c8c71a00b",
"method": "response",
"version": "1.0",
"timestamp": 1705463098535,
"name": "messageSay",
"code": 200,
"message": "success",
"params": {
"id": "clrh8op130002yszc9col2coq"
}
}
{
"reqId": "2a42cff1-bfb5-4d5d-b185-353c8c71a00b",
"method": "response",
"version": "1.0",
"timestamp": 1705463049890,
"name": "messageSay",
"code": 200,
"message": "消息不存在",
"params": {}
}
事件被推送到 thing/chatbot/${clinetId}/event/post主题(其中${clinetId}表示具体的clientId) 订阅thing/chatbot/xxxx/event/post接收事件数据
{
"reqId": "2a42cff1-bfb5-4d5d-b185-353c8c71a00b",
"method": "event",
"version": "1.0",
"timestamp": 1705384610041,
"name": "scan",
"params": {
"qrcode": "https://login.weixin.qq.com/l/gaD8UC3bcA==",
"status": 2
}
}
{
"reqId": "6e80b9ce-3585-46d2-982c-9be0087f21e2",
"method": "event",
"version": "1.0",
"timestamp": 1705384714220,
"name": "login",
"params": {
"_events": {},
"_eventsCount": 0,
"id": "@a4c7b5b71eb79b5f790f5d4c2270b0f3b787952a3a8ca08b228efe4832021299",
"payload": {
"alias": "",
"avatar": "/cgi-bin/mmwebwx-bin/webwxgeticon?seq=11550719&username=@a4c7b5b71eb79b5f790f5d4c2270b0f3b787952a3a8ca08b228efe4832021299&skey=@crypt_3f47a99d_1d59eeac1c79b47948fa86522b106b12",
"friend": false,
"gender": 2,
"id": "@a4c7b5b71eb79b5f790f5d4c2270b0f3b787952a3a8ca08b228efe4832021299",
"name": "瓦力",
"phone": [],
"star": false,
"type": 1
}
}
}
{
"reqId": "e0e8fb62-42a0-4b7c-9217-c3aadb9059dd",
"method": "event",
"version": "1.0",
"timestamp": 1705384609786,
"name": "logout",
"params": [
{
"_events": {},
"_eventsCount": 0,
"id": "@85ee0016d30773031e259b3de554c8542340104d9b7a2c2646f73076b990130a",
"payload": {
"alias": "",
"avatar": "/cgi-bin/mmwebwx-bin/webwxgeticon?seq=1946854219&username=@85ee0016d30773031e259b3de554c8542340104d9b7a2c2646f73076b990130a&skey=@crypt_3f47a99d_291be9b57007f9ec09ccd9cfda807c9c",
"friend": false,
"gender": 2,
"id": "@85ee0016d30773031e259b3de554c8542340104d9b7a2c2646f73076b990130a",
"name": "瓦力",
"phone": [],
"star": false,
"type": 1
}
},
"logout()"
]
}
{
"reqId": "46d3bcb9-f21b-4236-91a3-88efb99ff9f9",
"method": "event",
"version": "1.0",
"timestamp": 1705384530329,
"name": "ready",
"params": []
}
{
"reqId": "52bd5dae-6cf5-44bb-a76c-982744ba585e",
"method": "event",
"version": "1.0",
"timestamp": 1705384604626,
"name": "error",
"params": [
{
"code": 2,
"details": "Error: 连续3次同步失败,5s后尝试重启\n at C:\\Users\\Administrator\\Documents\\GitHub\\plugin-contrib\\node_modules\\wechat4u\\src\\wechat.js:100:19\n at processTicksAndRejections (node:internal/process/task_queues:96:5)",
"message": "连续3次同步失败,5s后尝试重启",
"name": "Error",
"stack": "Error: 连续3次同步失败,5s后尝试重启\n at C:\\Users\\Administrator\\Documents\\GitHub\\plugin-contrib\\node_modules\\wechat4u\\src\\wechat.js:100:19\n at processTicksAndRejections (node:internal/process/task_queues:96:5)"
}
]
}
{
"reqId": "2ee3362b-3142-44d5-b859-a15cb4177445",
"method": "event",
"version": "1.0",
"timestamp": 1705384017113,
"name": "message",
"params": {
"_events": {},
"_eventsCount": 0,
"id": "8768818756347691243",
"payload": {
"id": "8768818756347691243",
"talkerId": "@d3cc07d80f9add1b4acd87e49817d061",
"text": "h",
"timestamp": 1705384016,
"type": 7,
"roomId": "@@e3e01b946e9f19978ad0718269b78b4f5dc853fd8eda5aa2dd5601ac57cdb3a5",
"mentionIdList": []
}
}
}
{
"reqId": "b8ae2de2-19a3-4533-a5d5-9c2b7630a113",
"method": "thing.event.post",
"version": "1.0",
"timestamp": 1705385708810,
"events": {
"onMessage": {
"_id": "clrfyma84006vropd2i4ecmax",
"data": {
"_events": {},
"_eventsCount": 0,
"id": "clrfyma84006vropd2i4ecmax",
"payload": {
"id": "clrfyma84006vropd2i4ecmax",
"listenerId": "",
"roomId": "19036636423@chatroom",
"talkerId": "wxid_zqbyd7b5kwy322",
"text": "各位领导、同事\n 关于集团第四季度模拟钓鱼邮件演练,金茂商业有7名同事点击钓鱼链接,按总部要求加强各单位钓鱼邮件的识别、防御和处理能力。\n我们项目出现中招情况,故此,进行项目全员钓鱼邮件专题考试,希望大家在钓鱼邮件方面进一步加强安全意识意识和处置技能。\n以下为考试链接,请全员在1月19日前完成考试,我们将在群内公示考试人数。\nhttps://docs.chinajinmao.cn/form/ew/HOasNVyb/\n邀你填写「预防钓鱼邮件专题考试」",
"timestamp": 1705385708356,
"toId": "",
"type": 7
}
},
"room": {
"_events": {},
"_eventsCount": 0,
"id": "19036636423@chatroom",
"payload": {
"adminIdList": [],
"avatar": "",
"external": false,
"id": "19036636423@chatroom",
"ownerId": "",
"topic": "宁波金茂汇项目团队"
}
},
"talker": {
"_events": {},
"_eventsCount": 0,
"id": "wxid_zqbyd7b5kwy322",
"payload": {
"friend": true,
"id": "wxid_zqbyd7b5kwy322",
"name": "清昼",
"phone": [],
"type": 1
}
},
"time": "56011-07-10 20:19:16",
"timestamp": 1705385708356000
}
}
}
https://wechaty.js.org/docs/api/wechaty
Name | Type | Description |
---|---|---|
error | string | When the bot get error, there will be a Wechaty error event fired. |
login | string | After the bot login full successful, the event login will be emitted, with a Contact of current logined user. |
logout | string | Logout will be emitted when bot detected log out, with a Contact of the current login user. |
heartbeat | string | Get bot's heartbeat. |
friendship | string | When someone sends you a friend request, there will be a Wechaty friendship event fired. |
message | string | Emit when there's a new message. |
ready | string | Emit when all data has load completed, in wechaty-puppet-padchat, it means it has sync Contact and Room completed |
room-join | string | Emit when anyone join any room. |
room-topic | string | Get topic event, emitted when someone change room topic. |
room-leave | string | Emit when anyone leave the room. |
room-invite | string | Emit when there is a room invitation, see more in RoomInvitation |
If someone leaves the room by themselves, wechat will not notice other people in the room, so the bot will never get the "leave" event. | ||
scan | string | A scan event will be emitted when the bot needs to show you a QR Code for scanning. It is recommend to install qrcode-terminal(run npm install qrcode-terminal) in order to show qrcode in the terminal. |