{"id":15509886,"url":"https://github.com/atorber/wechat-remote","last_synced_at":"2025-08-26T06:37:21.591Z","repository":{"id":217699739,"uuid":"744576958","full_name":"atorber/wechat-remote","owner":"atorber","description":"一个微信远程调用工具，使用MQTT连接本地或云端微信客户端实现远程操作","archived":false,"fork":false,"pushed_at":"2024-02-02T09:24:45.000Z","size":119,"stargazers_count":5,"open_issues_count":0,"forks_count":1,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-06-03T21:09:55.781Z","etag":null,"topics":["chatbot","mqtt","wechaty","wechaty-plugin","wehcat","wehcatbot","wxbot"],"latest_commit_sha":null,"homepage":"https://www.yuque.com/atorber/chatflow/hwqf0tgqg9o51epc","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/atorber.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null}},"created_at":"2024-01-17T15:28:53.000Z","updated_at":"2025-05-23T04:38:14.000Z","dependencies_parsed_at":"2024-01-18T00:04:24.760Z","dependency_job_id":"e555c25c-8ef5-4274-bf54-753944fc269e","html_url":"https://github.com/atorber/wechat-remote","commit_stats":null,"previous_names":["atorber/wechat-remote"],"tags_count":0,"template":true,"template_full_name":"atorber/plugin-contrib","purl":"pkg:github/atorber/wechat-remote","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/atorber%2Fwechat-remote","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/atorber%2Fwechat-remote/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/atorber%2Fwechat-remote/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/atorber%2Fwechat-remote/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/atorber","download_url":"https://codeload.github.com/atorber/wechat-remote/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/atorber%2Fwechat-remote/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":272186211,"owners_count":24888333,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-08-26T02:00:07.904Z","response_time":60,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["chatbot","mqtt","wechaty","wechaty-plugin","wehcat","wehcatbot","wxbot"],"created_at":"2024-10-02T09:44:45.913Z","updated_at":"2025-08-26T06:37:21.567Z","avatar_url":"https://github.com/atorber.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# WeChatRemote\n\n## 概述\n\nWeChatRemote是一个微信远程调用工具，使用MQTT连接本地或云端微信客户端实现远程操作\n\n- 支持所有的Wechaty Puppet\n- 解耦Wechaty客户端与业务应用服务端，使用熟悉语言实现MQTT Client即可调用\n- 本地运行bot，远程接收消息和调用bot发消息\n\n![原理图](https://cdn.nlark.com/yuque/0/2024/jpeg/250308/1705459538734-81f76086-02e8-4ac2-8fc5-868ce63afc13.jpeg)\n\n## 快速入门\n\n### 安装wechat-remote插件\n\n```shell\nnpm i wechat-remote\n```\n\n### 启动机器人\n\n首先启动一个wechaty客户端（目前仅支持nodejs），并使用mqtt-wechaty插件\n机器人可以运行在本地或云服务器中，只需要可以访问外网，不需要配置外网IP\n\n```typescript\nimport { WechatyBuilder } from 'wechaty'\nimport {\n  QRCodeTerminal,\n  MqttGateway,\n  MqttGatewayConfig,\n} from 'wechat-remote'\n\nconst bot = WechatyBuilder.build({\n  name : 'ding-dong-bot',\n})\n\nconst config: MqttGatewayConfig = {\n  events: [\n    'login',\n    'logout',\n    'reset',\n    'ready',\n    'dirty',\n    'dong',\n    'error',\n    // 'heartbeat',\n    'friendship',\n    'message', 'post',\n    'room-invite', 'room-join',\n    'room-leave', 'room-topic',\n    'scan',\n  ],\n  mqtt: {\n    clientId: 'ding-dong-test01', // 替换成自己的clientId，建议不少于16个字符串\n    host: 'broker.emqx.io',\n    password: '',\n    port: 1883,\n    username: '',\n  },\n  options:{\n    secrectKey: '',\n    simple: false,\n  },\n  token: '',\n}\n\nbot.use(\n  MqttGateway(config),\n  QRCodeTerminal(),\n)\n\nbot.start()\n  .catch(console.error)\n\n```\n\n### MQTTX调用\n\n使用MQTT可视化工具调用接口，可以快速理解学习WeChatRemote使用\n\n1. 访问 [http://www.emqx.io/online-mqtt-client](http://www.emqx.io/online-mqtt-client) ，配置并连接MQTT\n2. 订阅如下主题，其中的“chatbot/”之后的“+”可以换成具体的clientId\n   - 接收事件 thing/chatbot/+/event/post\n   - 应用端下发指令 thing/chatbot/+/command/invoke\n   - 接收响应 thing/chatbot/+/response/d2c/+\n3. 查询机器人状态，向 thing/chatbot/ding-dong-test01/command/invoke 主题发布如下payload：\n\n```json\n{\n    \"reqId\":\"2a42cff1-bfb5-4d5d-b185-353c8c71a00b\",\n    \"method\":\"command\",\n    \"version\":\"1.0\",\n    \"timestamp\":1705384610041,\n    \"name\":\"wechatyLogonoff\",\n    \"params\":{}\n}\n```\n\n![image.png](https://cdn.nlark.com/yuque/0/2024/png/250308/1705456827915-8e1ace3a-3fa2-414f-9104-e861468e3f48.png#averageHue=%23dff5e0\u0026clientId=uadef19d5-ced0-4\u0026from=paste\u0026height=1040\u0026id=u2b7b76d0\u0026originHeight=1040\u0026originWidth=1918\u0026originalType=binary\u0026ratio=1\u0026rotation=0\u0026showTitle=false\u0026size=308523\u0026status=done\u0026style=none\u0026taskId=uad897fa2-96d1-470e-bb8e-dc2655cd408\u0026title=\u0026width=1918)\n4. 向指定好友发送消息，向 thing/chatbot/ding-dong-test01/command/invoke 主题发布如下payload：\n\n```json\n{\n    \"reqId\":\"2a42cff1-bfb5-4d5d-b185-353c8c71a00b\",\n    \"method\":\"command\",\n    \"version\":\"1.0\",\n    \"timestamp\":1705384610041,\n    \"name\":\"contactSay\",\n    \"params\":{\n        \"contacts\":[\"atorber\"],\n        \"messageType\":\"Text\",\n        \"messagePayload\":\"hello\"\n    }\n}\n```\n\n![image.png](https://cdn.nlark.com/yuque/0/2024/png/250308/1705457339087-f8a1d427-2596-45a7-b6ea-4b11f3880ebd.png#averageHue=%23fefefd\u0026clientId=uadef19d5-ced0-4\u0026from=paste\u0026height=1039\u0026id=ubd817504\u0026originHeight=1039\u0026originWidth=1917\u0026originalType=binary\u0026ratio=1\u0026rotation=0\u0026showTitle=false\u0026size=304967\u0026status=done\u0026style=none\u0026taskId=uea142729-c52c-42bb-a3d0-9fe0c0c9944\u0026title=\u0026width=1917)\n\n\u003e 下载安装MQTTX [https://mqttx.app/zh/downloads](https://mqttx.app/zh/downloads) 可以使用客户端更加稳定\n\n### 程序调用\n\n以下是几种常用语言的SimpleCode，后续考虑提供SDK，期待大家贡献各种语言的sdk\n\n#### JavaScript\n\n- 安装依赖\n\n```shell\nnpm install mqtt\n```\n\n- 接收消息\n\n```javascript\nconst mqtt = require('mqtt');\n\n// MQTT 服务器设置\nconst MQTT_BROKER_URL = 'mqtt://your-mqtt-broker-url';\nconst TOPIC = 'thing/chatbot/xxxx/event/post';\nconst MQTT_PORT = 1883; // 替换为你的 MQTT 服务器端口\nconst USERNAME = 'your-username'; // 替换为你的用户名\nconst PASSWORD = 'your-password'; // 替换为你的密码\n\n// 连接选项\nconst options = {\n  port: MQTT_PORT,\n  username: USERNAME,\n  password: PASSWORD,\n};\n\n// 创建 MQTT 客户端\nconst client = mqtt.connect(MQTT_BROKER_URL, options);\n\nclient.on('connect', () =\u003e {\n  console.log('Connected to MQTT Broker:', MQTT_BROKER_URL);\n  // 订阅指定主题\n  client.subscribe(TOPIC, (err) =\u003e {\n    if (!err) {\n      console.log(`Subscribed to topic: ${TOPIC}`);\n    } else {\n      console.error(`Failed to subscribe: ${err}`);\n    }\n  });\n});\n\nclient.on('message', (topic, message) =\u003e {\n  if (topic === TOPIC) {\n    try {\n      // 尝试解析消息为 JSON\n      const jsonMessage = JSON.parse(message.toString());\n      console.log('Received JSON Message:', jsonMessage);\n    } catch (error) {\n      console.error('Received non-JSON message:', message.toString());\n    }\n  }\n});\n\nclient.on('error', (error) =\u003e {\n  console.error('MQTT Client Error:', error);\n});\n```\n\n- 调用API\n\n```javascript\nconst mqtt = require('mqtt');\n\nconst MQTT_BROKER_URL = 'mqtt://your-mqtt-broker-url';\nconst COMMAND_TOPIC = 'thing/chatbot/xxxx/command/invoke';\nconst RESPONSE_TOPIC = 'thing/chatbot/xxxx/response/d2c/+';\nconst MQTT_PORT = 1883; // 或者你的 MQTT 服务器端口\nconst USERNAME = 'your-username'; // 或者你的用户名\nconst PASSWORD = 'your-password'; // 或者你的密码\n\nconst message = {\n  reqId: \"2a42cff1-bfb5-4d5d-b185-353c8c71a00b\",\n  method: \"command\",\n  version: \"1.0\",\n  timestamp: 1705384610041,\n  name: \"contactSay\",\n  params: {\n    contacts: [\"ledongmao\", \"choogoo\"],\n    messageType: \"Text\",\n    messagePayload: \"hello\"\n  }\n};\n\nconst options = {\n  port: MQTT_PORT,\n  username: USERNAME,\n  password: PASSWORD,\n};\n\nconst client = mqtt.connect(MQTT_BROKER_URL, options);\n\nclient.on('connect', () =\u003e {\n  console.log('Connected to MQTT Broker:', MQTT_BROKER_URL);\n\n  // 订阅响应主题\n  client.subscribe(RESPONSE_TOPIC, (err) =\u003e {\n    if (!err) {\n      console.log(`Subscribed to response topic: ${RESPONSE_TOPIC}`);\n    } else {\n      console.error(`Failed to subscribe: ${err}`);\n    }\n  });\n\n  // 发布命令消息\n  client.publish(COMMAND_TOPIC, JSON.stringify(message));\n  console.log(`Message published to command topic: ${COMMAND_TOPIC}`);\n});\n\nclient.on('message', (topic, message) =\u003e {\n  console.log(`Received message from ${topic}: ${message.toString()}`);\n});\n\nclient.on('error', (error) =\u003e {\n  console.error('MQTT Client Error:', error);\n});\n```\n\n#### TypeScript\n\n- 安装依赖\n\n```shell\nnpm install mqtt\nnpm install @types/node --save-dev\n```\n\n- 接收消息\n\n```typescript\nimport * as mqtt from 'mqtt';\n\n// MQTT 服务器设置\nconst MQTT_BROKER_URL = 'mqtt://your-mqtt-broker-url';\nconst TOPIC = 'thing/chatbot/xxxx/event/post';\nconst MQTT_PORT = 1883; // 替换为你的 MQTT 服务器端口\nconst USERNAME = 'your-username'; // 替换为你的用户名\nconst PASSWORD = 'your-password'; // 替换为你的密码\n\n// 连接选项\nconst options: mqtt.IClientOptions = {\n  port: MQTT_PORT,\n  username: USERNAME,\n  password: PASSWORD,\n};\n\n// 创建 MQTT 客户端\nconst client = mqtt.connect(MQTT_BROKER_URL, options);\n\nclient.on('connect', () =\u003e {\n  console.log('Connected to MQTT Broker:', MQTT_BROKER_URL);\n  // 订阅指定主题\n  client.subscribe(TOPIC, (err) =\u003e {\n    if (!err) {\n      console.log(`Subscribed to topic: ${TOPIC}`);\n    } else {\n      console.error(`Failed to subscribe: ${err}`);\n    }\n  });\n  // 订阅指定主题\n  client.subscribe(TOPIC, (err) =\u003e {\n    if (!err) {\n      console.log(`Subscribed to topic: ${TOPIC}`);\n    } else {\n      console.error(`Failed to subscribe: ${err}`);\n    }\n  });\n});\n\nclient.on('message', (topic, message) =\u003e {\n  if (topic === TOPIC) {\n    try {\n      // 尝试解析消息为 JSON\n      const jsonMessage = JSON.parse(message.toString());\n      console.log('Received JSON Message:', jsonMessage);\n    } catch (error) {\n      console.error('Received non-JSON message:', message.toString());\n    }\n  }\n});\n\nclient.on('error', (error) =\u003e {\n  console.error('MQTT Client Error:', error);\n});\n```\n\n- 调用API\n\n```typescript\nimport * as mqtt from 'mqtt';\nimport type { IClientOptions, MqttClient } from 'mqtt';\n\nconst MQTT_BROKER_URL: string = 'mqtt://your-mqtt-broker-url';\nconst COMMAND_TOPIC: string = 'thing/chatbot/xxxx/command/invoke';\nconst RESPONSE_TOPIC: string = 'thing/chatbot/xxxx/response/d2c/+';\nconst MQTT_PORT: number = 1883; // 或者你的 MQTT 服务器端口\nconst USERNAME: string = 'your-username'; // 或者你的用户名\nconst PASSWORD: string = 'your-password'; // 或者你的密码\n\ninterface Message {\n  reqId: string;\n  method: string;\n  version: string;\n  timestamp: number;\n  name: string;\n  params: {\n    contacts: string[];\n    messageType: string;\n    messagePayload: string;\n  };\n}\n\nconst message: Message = {\n  reqId: \"2a42cff1-bfb5-4d5d-b185-353c8c71a00b\",\n  method: \"command\",\n  version: \"1.0\",\n  timestamp: 1705384610041,\n  name: \"contactSay\",\n  params: {\n    contacts: [\"ledongmao\", \"choogoo\"],\n    messageType: \"Text\",\n    messagePayload: \"hello\"\n  }\n};\n\nconst options: IClientOptions = {\n  port: MQTT_PORT,\n  username: USERNAME,\n  password: PASSWORD,\n};\n\nconst client: MqttClient = mqtt.connect(MQTT_BROKER_URL, options);\n\nclient.on('connect', () =\u003e {\n  console.log('Connected to MQTT Broker:', MQTT_BROKER_URL);\n\n  // 订阅响应主题\n  client.subscribe(RESPONSE_TOPIC, (err) =\u003e {\n    if (!err) {\n      console.log(`Subscribed to response topic: ${RESPONSE_TOPIC}`);\n    } else {\n      console.error(`Failed to subscribe: ${err}`);\n    }\n  });\n\n  // 发布命令消息\n  client.publish(COMMAND_TOPIC, JSON.stringify(message));\n  console.log(`Message published to command topic: ${COMMAND_TOPIC}`);\n});\n\nclient.on('message', (topic: string, message: Buffer) =\u003e {\n  console.log(`Received message from ${topic}: ${message.toString()}`);\n});\n\nclient.on('error', (error: Error) =\u003e {\n  console.error('MQTT Client Error:', error);\n});\n```\n\n#### Python\n\n- 安装依赖\n\n```shell\npip install paho-mqtt\n```\n\n- 接收消息\n\n```python\nimport json\nimport paho.mqtt.client as mqtt\n\n# MQTT 服务器设置\nMQTT_BROKER_URL = 'mqtt://your-mqtt-broker-url'\nTOPIC = 'thing/chatbot/xxxx/event/post'\nMQTT_PORT = 1883  # 替换为你的 MQTT 服务器端口\nUSERNAME = 'your-username'  # 替换为你的用户名\nPASSWORD = 'your-password'  # 替换为你的密码\n\n# 连接成功回调函数\ndef on_connect(client, userdata, flags, rc):\n    print(f'Connected to MQTT Broker: {MQTT_BROKER_URL}')\n    client.subscribe(TOPIC)\n    print(f'Subscribed to topic: {TOPIC}')\n\n# 接收消息回调函数\ndef on_message(client, userdata, msg):\n    if msg.topic == TOPIC:\n        try:\n            # 尝试解析消息为 JSON\n            json_message = json.loads(msg.payload.decode())\n            print('Received JSON Message:', json_message)\n        except ValueError:\n            print('Received non-JSON message:', msg.payload.decode())\n\n# MQTT 客户端设置\nclient = mqtt.Client()\nclient.username_pw_set(USERNAME, PASSWORD)\nclient.on_connect = on_connect\nclient.on_message = on_message\n\n# 连接 MQTT Broker\nclient.connect(MQTT_BROKER_URL, MQTT_PORT, 60)\n\n# 网络循环，以处理回调函数并保持脚本运行\nclient.loop_forever()\n```\n\n- 调用API\n\n```python\nimport json\nimport paho.mqtt.client as mqtt\n\nMQTT_BROKER_URL = 'mqtt://your-mqtt-broker-url'\nCOMMAND_TOPIC = 'thing/chatbot/xxxx/command/invoke'\nRESPONSE_TOPIC = 'thing/chatbot/xxxx/response/d2c/+'\nMQTT_PORT = 1883  # 或者你的 MQTT 服务器端口\nUSERNAME = 'your-username'  # 或者你的用户名\nPASSWORD = 'your-password'  # 或者你的密码\n\nmessage = {\n    \"reqId\": \"2a42cff1-bfb5-4d5d-b185-353c8c71a00b\",\n    \"method\": \"command\",\n    \"version\": \"1.0\",\n    \"timestamp\": 1705384610041,\n    \"name\": \"contactSay\",\n    \"params\": {\n        \"contacts\": [\"ledongmao\", \"choogoo\"],\n        \"messageType\": \"Text\",\n        \"messagePayload\": \"hello\"\n    }\n}\n\ndef on_connect(client, userdata, flags, rc):\n    print(f\"Connected to MQTT Broker: {MQTT_BROKER_URL}\")\n\n    # 订阅响应主题\n    client.subscribe(RESPONSE_TOPIC)\n    print(f\"Subscribed to response topic: {RESPONSE_TOPIC}\")\n\n    # 发布命令消息\n    client.publish(COMMAND_TOPIC, json.dumps(message))\n    print(f\"Message published to command topic: {COMMAND_TOPIC}\")\n\ndef on_message(client, userdata, msg):\n    print(f\"Received message from {msg.topic}: {msg.payload.decode()}\")\n\ndef on_error(client, userdata, rc):\n    print(f\"MQTT Client Error: {rc}\")\n\nclient = mqtt.Client()\n\nclient.username_pw_set(USERNAME, PASSWORD)\nclient.on_connect = on_connect\nclient.on_message = on_message\nclient.on_error = on_error\n\nclient.connect(MQTT_BROKER_URL.replace('mqtt://', ''), MQTT_PORT, 60)\n\nclient.loop_forever()\n```\n\n#### Go\n\n- 安装依赖\n\n```shell\ngo get github.com/eclipse/paho.mqtt.golang\n```\n\n- 接收消息\n\n```go\npackage main\n\nimport (\n    \"encoding/json\"\n    \"fmt\"\n    \"os\"\n    \"time\"\n\n    mqtt \"github.com/eclipse/paho.mqtt.golang\"\n)\n\nconst (\n    MQTT_BROKER_URL = \"tcp://your-mqtt-broker-url:1883\" // 注意更换为你的 MQTT 服务器地址和端口\n    TOPIC           = \"thing/chatbot/xxxx/event/post\"   // 更换为你的主题\n    USERNAME        = \"your-username\"                   // 更换为你的用户名\n    PASSWORD        = \"your-password\"                   // 更换为你的密码\n)\n\nfunc onConnectHandler(client mqtt.Client) {\n    if token := client.Subscribe(TOPIC, 0, onMessageReceivedHandler); token.Wait() \u0026\u0026 token.Error() != nil {\n        fmt.Println(\"Subscribe error:\", token.Error())\n        os.Exit(1)\n    }\n    fmt.Println(\"Connected to MQTT Broker:\", MQTT_BROKER_URL)\n    fmt.Println(\"Subscribed to topic:\", TOPIC)\n}\n\nfunc onMessageReceivedHandler(client mqtt.Client, msg mqtt.Message) {\n    fmt.Printf(\"Received message on topic %s: %s\\n\", msg.Topic(), string(msg.Payload()))\n\n    var jsonMessage map[string]interface{}\n    if err := json.Unmarshal(msg.Payload(), \u0026jsonMessage); err != nil {\n        fmt.Println(\"Error parsing JSON message:\", err)\n    } else {\n        fmt.Println(\"Received JSON Message:\", jsonMessage)\n    }\n}\n\nfunc main() {\n    opts := mqtt.NewClientOptions().AddBroker(MQTT_BROKER_URL).SetUsername(USERNAME).SetPassword(PASSWORD)\n    opts.SetDefaultPublishHandler(onMessageReceivedHandler)\n    opts.OnConnect = onConnectHandler\n\n    client := mqtt.NewClient(opts)\n    if token := client.Connect(); token.Wait() \u0026\u0026 token.Error() != nil {\n        fmt.Println(\"Connection error:\", token.Error())\n        os.Exit(1)\n    }\n\n    // Keep the main function running until interrupted\n    select {}\n}\n```\n\n- API调用\n\n#### Java\n\n- 安装依赖\n\n```shell\n\u003cdependencies\u003e\n    \u003cdependency\u003e\n        \u003cgroupId\u003eorg.eclipse.paho\u003c/groupId\u003e\n        \u003cartifactId\u003eorg.eclipse.paho.client.mqttv3\u003c/artifactId\u003e\n        \u003cversion\u003e1.2.5\u003c/version\u003e\n    \u003c/dependency\u003e\n\u003c/dependencies\u003e\n```\n\n- 接收消息\n\n```shell\nimport org.eclipse.paho.client.mqttv3.IMqttDeliveryToken;\nimport org.eclipse.paho.client.mqttv3.MqttCallback;\nimport org.eclipse.paho.client.mqttv3.MqttClient;\nimport org.eclipse.paho.client.mqttv3.MqttConnectOptions;\nimport org.eclipse.paho.client.mqttv3.MqttMessage;\nimport org.json.JSONObject;\n\npublic class MqttSubscribeSample {\n\n    public static void main(String[] args) {\nfinal String brokerUrl = \"tcp://your-mqtt-broker-url:1883\"; // 替换为你的MQTT Broker的URL\nfinal String topic = \"thing/chatbot/xxxx/event/post\"; // 替换为你的主题\nfinal String clientId = \"JavaClient\";\nfinal String username = \"your-username\"; // 替换为你的用户名\nfinal String password = \"your-password\"; // 替换为你的密码\n    try {\n        MqttClient sampleClient = new MqttClient(brokerUrl, clientId);\n        MqttConnectOptions connOpts = new MqttConnectOptions();\n        connOpts.setCleanSession(true);\n        connOpts.setUserName(username);\n        connOpts.setPassword(password.toCharArray());\n        \n        System.out.println(\"Connecting to broker: \" + brokerUrl);\n        sampleClient.connect(connOpts);\n        System.out.println(\"Connected\");\n        \n        sampleClient.setCallback(new MqttCallback() {\n            @Override\n            public void connectionLost(Throwable cause) {\n                System.out.println(\"Connection lost!\");\n            }\n            \n            @Override\n            public void messageArrived(String topic, MqttMessage message) throws Exception {\n                System.out.println(\"Message arrived: \" + message.toString());\n                try {\n                    JSONObject jsonMessage = new JSONObject(message.toString());\n                    System.out.println(\"Received JSON Message: \" + jsonMessage.toString(2)); // Indent with 2 spaces\n                } catch (Exception e) {\n                    System.out.println(\"Received non-JSON message: \" + message.toString());\n                }\n            }\n            \n            @Override\n            public void deliveryComplete(IMqttDeliveryToken token) {\n                // Not used in this example\n            }\n        });\n        \n        System.out.println(\"Subscribing to topic: \" + topic);\n        sampleClient.subscribe(topic);\n    } catch(Exception e) {\n        System.out.println(\"Exception: \" + e.getMessage());\n    }\n}\n```\n\n- API调用\n\n```go\nimport org.eclipse.paho.client.mqttv3.IMqttDeliveryToken;\nimport org.eclipse.paho.client.mqttv3.MqttCallback;\nimport org.eclipse.paho.client.mqttv3.MqttClient;\nimport org.eclipse.paho.client.mqttv3.MqttConnectOptions;\nimport org.eclipse.paho.client.mqttv3.MqttException;\nimport org.eclipse.paho.client.mqttv3.MqttMessage;\nimport org.json.JSONObject;\n\npublic class MqttClientDemo {\n    private static final String MQTT_BROKER_URL = \"tcp://your-mqtt-broker-url:1883\";\n    private static final String COMMAND_TOPIC = \"thing/chatbot/xxxx/command/invoke\";\n    private static final String RESPONSE_TOPIC = \"thing/chatbot/xxxx/response/d2c/+\";\n    private static final String USERNAME = \"your-username\";\n    private static final String PASSWORD = \"your-password\";\n\n    public static void main(String[] args) {\n        try {\n            MqttClient client = new MqttClient(MQTT_BROKER_URL, MqttClient.generateClientId());\n            MqttConnectOptions options = new MqttConnectOptions();\n            options.setUserName(USERNAME);\n            options.setPassword(PASSWORD.toCharArray());\n            \n            client.setCallback(new MqttCallback() {\n                @Override\n                public void connectionLost(Throwable cause) {\n                    System.out.println(\"MQTT Client Error: \" + cause.getMessage());\n                }\n\n                @Override\n                public void messageArrived(String topic, MqttMessage message) {\n                    System.out.println(\"Received message from \" + topic + \": \" + new String(message.getPayload()));\n                }\n\n                @Override\n                public void deliveryComplete(IMqttDeliveryToken token) {\n                }\n            });\n\n            client.connect(options);\n            System.out.println(\"Connected to MQTT Broker: \" + MQTT_BROKER_URL);\n            \n            client.subscribe(RESPONSE_TOPIC);\n            System.out.println(\"Subscribed to response topic: \" + RESPONSE_TOPIC);\n            \n            JSONObject message = new JSONObject();\n            message.put(\"reqId\", \"2a42cff1-bfb5-4d5d-b185-353c8c71a00b\");\n            message.put(\"method\", \"command\");\n            message.put(\"version\", \"1.0\");\n            message.put(\"timestamp\", 1705384610041L);\n            message.put(\"name\", \"contactSay\");\n            JSONObject params = new JSONObject();\n            params.put(\"contacts\", new String[]{\"ledongmao\", \"choogoo\"});\n            params.put(\"messageType\", \"Text\");\n            params.put(\"messagePayload\", \"hello\");\n            message.put(\"params\", params);\n\n            client.publish(COMMAND_TOPIC, new MqttMessage(message.toString().getBytes()));\n            System.out.println(\"Message published to command topic: \" + COMMAND_TOPIC);\n\n        } catch (MqttException e) {\n            e.printStackTrace();\n        }\n    }\n}\n```\n\n\u003e 其他语言示例欢迎在评论里粘贴代码或提需求，也可以交给GPTs [多语言代码转换大师](https://chat.openai.com/g/g-TgFzzIJjo-duo-yu-yan-dai-ma-zhuan-huan-da-shi)\n\n## API说明\n\n:::warning\n目前仅实现了常用API的支持，其他API需求可以在评论中留言，当然API的范围不能超出Wechaty支持范围\n:::\n远程调用调用端向 thing/chatbot/${clinetId}/command/invoke发送调用指令（其中${clinetId}表示具体的clientId）\nWechaty客户端接收到指令后向thing/chatbot/${clinetId}/response/d2c/${reqId}主题推送响应消息\n应用端订阅响应消息：\n\n- 订阅指定请求消息：thing/chatbot/xxxx/response/d2c/1234\n- 订阅所有请求消息：thing/chatbot/xxxx/response/d2c/+\n\n### 查询机器人状态\n\n- 请求\n\n```json\n{\n    \"reqId\":\"2a42cff1-bfb5-4d5d-b185-353c8c71a00b\",\n    \"method\":\"command\",\n    \"version\":\"1.0\",\n    \"timestamp\":1705384610041,\n    \"name\":\"wechatyLogonoff\",\n    \"params\":{}\n}\n```\n\n- 响应\n\n```json\n{\n  \"reqId\": \"2a42cff1-bfb5-4d5d-b185-353c8c71a00b\",\n  \"method\": \"response\",\n  \"version\": \"1.0\",\n  \"timestamp\": 1705408082094,\n  \"name\": \"wechatyLogonoff\",\n  \"code\": 200,\n  \"message\": \"success\",\n  \"params\": {\n    \"logonoff\": true\n  }\n}\n```\n\n### 获取机器人信息\n\n- 请求\n\n```json\n{\n    \"reqId\":\"2a42cff1-bfb5-4d5d-b185-353c8c71a00b\",\n    \"method\":\"command\",\n    \"version\":\"1.0\",\n    \"timestamp\":1705384610041,\n    \"name\":\"wechatyUserSelf\",\n    \"params\":{}\n}\n```\n\n- 响应\n\n```json\n{\n  \"reqId\": \"2a42cff1-bfb5-4d5d-b185-353c8c71a00b\",\n  \"method\": \"response\",\n  \"version\": \"1.0\",\n  \"timestamp\": 1705408574486,\n  \"name\": \"wechatyUserSelf\",\n  \"code\": 200,\n  \"message\": \"success\",\n  \"params\": {\n    \"_events\": {},\n    \"_eventsCount\": 0,\n    \"id\": \"@a4c7b5b71eb79b5f790f5d4c2270b0f3b787952a3a8ca08b228efe4832021299\",\n    \"payload\": {\n      \"alias\": \"\",\n      \"avatar\": \"/cgi-bin/mmwebwx-bin/webwxgeticon?seq=1851844649\u0026username=@a4c7b5b71eb79b5f790f5d4c2270b0f3b787952a3a8ca08b228efe4832021299\u0026skey=@crypt_3f47a99d_1d59eeac1c79b47948fa86522b106b12\",\n      \"friend\": false,\n      \"gender\": 2,\n      \"id\": \"@a4c7b5b71eb79b5f790f5d4c2270b0f3b787952a3a8ca08b228efe4832021299\",\n      \"name\": \"瓦力\",\n      \"phone\": [],\n      \"star\": false,\n      \"type\": 1\n    }\n  }\n}\n```\n\n### 获取好友列表\n\n- 请求\n\n```json\n{\n    \"reqId\":\"2a42cff1-bfb5-4d5d-b185-353c8c71a00b\",\n    \"method\":\"command\",\n    \"version\":\"1.0\",\n    \"timestamp\":1705384610041,\n    \"name\":\"contactFindAll\",\n    \"params\":{\n      \"size\":100\n    }\n}\n```\n\n- 响应\n\n```json\n{\n    \"reqId\":\"2a42cff1-bfb5-4d5d-b185-353c8c71a00b\",\n    \"method\":\"response\",\n    \"version\":\"1.0\",\n    \"timestamp\":1705384610041,\n    \"code\":200,\n    \"message\":\"success\",\n    \"name\":\"contactFindAll\",\n    \"params\":{\n        \"page\":1,\n        \"size\":100,\n        \"total\":3500,\n        \"items\":[\n            {\n                \"_events\":{\n\n                },\n                \"_eventsCount\":0,\n                \"id\":\"@a4c7b5b71eb79b5f790f5d4c2270b0f3b787952a3a8ca08b228efe4832021299\",\n                \"payload\":{\n                    \"alias\":\"\",\n                    \"avatar\":\"/cgi-bin/mmwebwx-bin/webwxgeticon?seq=11550719\u0026username=@a4c7b5b71eb79b5f790f5d4c2270b0f3b787952a3a8ca08b228efe4832021299\u0026skey=@crypt_3f47a99d_1d59eeac1c79b47948fa86522b106b12\",\n                    \"friend\":false,\n                    \"gender\":2,\n                    \"id\":\"@a4c7b5b71eb79b5f790f5d4c2270b0f3b787952a3a8ca08b228efe4832021299\",\n                    \"name\":\"瓦力\",\n                    \"phone\":[\n\n                    ],\n                    \"star\":false,\n                    \"type\":1\n                }\n            },\n            {\n                \"_events\":{\n\n                },\n                \"_eventsCount\":0,\n                \"id\":\"@a4c7b5b71eb79b5f790f5d4c2270b0f3b787952a3a8ca08b228efe4832021299\",\n                \"payload\":{\n                    \"alias\":\"\",\n                    \"avatar\":\"/cgi-bin/mmwebwx-bin/webwxgeticon?seq=11550719\u0026username=@a4c7b5b71eb79b5f790f5d4c2270b0f3b787952a3a8ca08b228efe4832021299\u0026skey=@crypt_3f47a99d_1d59eeac1c79b47948fa86522b106b12\",\n                    \"friend\":false,\n                    \"gender\":2,\n                    \"id\":\"@a4c7b5b71eb79b5f790f5d4c2270b0f3b787952a3a8ca08b228efe4832021299\",\n                    \"name\":\"瓦力\",\n                    \"phone\":[\n\n                    ],\n                    \"star\":false,\n                    \"type\":1\n                }\n            }\n        ]\n    }\n}\n```\n\n### 查询好友详情\n\n- 请求\n\nalias、id、name至少填写一个\n\n```json\n{\n    \"reqId\":\"2a42cff1-bfb5-4d5d-b185-353c8c71a00b\",\n    \"method\":\"command\",\n    \"version\":\"1.0\",\n    \"timestamp\":1705384610041,\n    \"name\":\"contactFind\",\n    \"params\":{\n        \"alias\":\"\",\n        \"id\":\"@a4c7b5b71eb79b5f790f5d4c2270b0f3b787952a3a8ca08b228efe4832021299\",\n        \"name\":\"瓦力\"\n    }\n}\n```\n\n- 响应\n\n```json\n{\n    \"reqId\":\"2a42cff1-bfb5-4d5d-b185-353c8c71a00b\",\n    \"method\":\"response\",\n    \"version\":\"1.0\",\n    \"timestamp\":1705384610041,\n    \"code\":200,\n    \"message\":\"success\",\n    \"name\":\"contactFind\",\n    \"params\":{\n        \"_events\":{},\n        \"_eventsCount\":0,\n        \"id\":\"@a4c7b5b71eb79b5f790f5d4c2270b0f3b787952a3a8ca08b228efe4832021299\",\n        \"payload\":{\n            \"alias\":\"\",\n            \"avatar\":\"/cgi-bin/mmwebwx-bin/webwxgeticon?seq=11550719\u0026username=@a4c7b5b71eb79b5f790f5d4c2270b0f3b787952a3a8ca08b228efe4832021299\u0026skey=@crypt_3f47a99d_1d59eeac1c79b47948fa86522b106b12\",\n            \"friend\":false,\n            \"gender\":2,\n            \"id\":\"@a4c7b5b71eb79b5f790f5d4c2270b0f3b787952a3a8ca08b228efe4832021299\",\n            \"name\":\"瓦力\",\n            \"phone\":[],\n            \"star\":false,\n            \"type\":1\n        }\n    }\n}\n```\n\n### 向指定好友发消息\n\n\u003e 目前仅支持发送文本消息，图片、文件、视频、语音等消息即将支持\n\n- 请求\n\n```json\n{\n    \"reqId\":\"2a42cff1-bfb5-4d5d-b185-353c8c71a00b\",\n    \"method\":\"command\",\n    \"version\":\"1.0\",\n    \"timestamp\":1705384610041,\n    \"name\":\"contactSay\",\n    \"params\":{\n        \"contacts\":[\n            \"ledongmao\",\n            \"choogoo\"\n        ],\n        \"messageType\":\"Text\",\n        \"messagePayload\":\"hello\"\n    }\n}\n```\n\n- 响应\n\n返回发送结果列表\n\n```json\n{\n    \"reqId\":\"2a42cff1-bfb5-4d5d-b185-353c8c71a00b\",\n    \"method\":\"response\",\n    \"version\":\"1.0\",\n    \"timestamp\":1705384610041,\n    \"code\":200,\n    \"message\":\"success\",\n    \"name\":\"contactSay\",\n    \"params\":{\n      \"success\":[],\n      \"fail\":[]\n    }\n}\n```\n\n### 获取群列表\n\n- 请求\n\n```json\n{\n    \"reqId\":\"2a42cff1-bfb5-4d5d-b185-353c8c71a00b\",\n    \"method\":\"command\",\n    \"version\":\"1.0\",\n    \"timestamp\":1705384610041,\n    \"name\":\"roomFindAll\",\n    \"params\":{\n      \"size\":100\n    }\n}\n```\n\n- 响应\n\n```json\n{\n    \"reqId\":\"2a42cff1-bfb5-4d5d-b185-353c8c71a00b\",\n    \"method\":\"response\",\n    \"version\":\"1.0\",\n    \"timestamp\":1705384610041,\n    \"code\":200,\n    \"message\":\"success\",\n    \"name\":\"roomFindAll\",\n    \"params\":{\n        \"page\":1,\n        \"size\":100,\n        \"count\":3500,\n        \"items\":[\n            {\n                \"_events\":{},\n                \"_eventsCount\":0,\n                \"id\":\"19036636423@chatroom\",\n                \"payload\":{\n                    \"adminIdList\":[],\n                    \"avatar\":\"\",\n                    \"external\":false,\n                    \"id\":\"19036636423@chatroom\",\n                    \"ownerId\":\"\",\n                    \"topic\":\"宁波金茂汇项目团队\"\n                }\n            },\n            {\n                \"_events\":{},\n                \"_eventsCount\":0,\n                \"id\":\"19036636423@chatroom\",\n                \"payload\":{\n                    \"adminIdList\":[],\n                    \"avatar\":\"\",\n                    \"external\":false,\n                    \"id\":\"19036636423@chatroom\",\n                    \"ownerId\":\"\",\n                    \"topic\":\"宁波金茂汇项目团队\"\n                }\n            }\n        ]\n    }\n}\n```\n\n### 获取群详情\n\n- 请求\n\n```json\n{\n    \"reqId\":\"2a42cff1-bfb5-4d5d-b185-353c8c71a00b\",\n    \"method\":\"command\",\n    \"version\":\"1.0\",\n    \"timestamp\":1705384610041,\n    \"name\":\"roomFind\",\n    \"params\":{\n        \"id\":\"@a4c7b5b71eb79b5f790f5d4c2270b0f3b787952a3a8ca08b228efe4832021299\",\n        \"topic\":\"瓦力是群主\"\n    }\n}\n```\n\n- 响应\n\n```json\n{\n  \"reqId\": \"2a42cff1-bfb5-4d5d-b185-353c8c71a00b\",\n  \"method\": \"response\",\n  \"version\": \"1.0\",\n  \"timestamp\": 1705418869966,\n  \"name\": \"roomFind\",\n  \"code\": 200,\n  \"message\": \"success\",\n  \"params\": {\n    \"_events\": {},\n    \"_eventsCount\": 0,\n    \"id\": \"5550027590@chatroom\",\n    \"payload\": {\n      \"adminIdList\": [\n        \"wxid_m7kf9tq12\"\n      ],\n      \"avatar\": \"\",\n      \"external\": false,\n      \"id\": \"5550027590@chatroom\",\n      \"memberIdList\": [\n        \"wxid_m7kf9tq12\",\n        \"tyutl\",\n        \"wxid_0f57221\"\n      ],\n      \"ownerId\": \"wxid_m7kf9tq12\",\n      \"topic\": \"瓦力是群主\"\n    }\n  }\n}\n```\n\n### 查询群成员列表\n\n- 请求\n\nid、topic至少填写一项\n\n```json\n{\n    \"reqId\":\"2a42cff1-bfb5-4d5d-b185-353c8c71a00b\",\n    \"method\":\"command\",\n    \"version\":\"1.0\",\n    \"timestamp\":1705384610041,\n    \"name\":\"roomMemberAllGet\",\n    \"params\":{\n        \"size\":100,\n        \"id\":\"@a4c7b5b71eb79b5f790f5d4c2270b0f3b787952a3a8ca08b228efe4832021299\",\n        \"topic\":\"瓦力是群主\"\n    }\n}\n```\n\n- 响应\n\n```json\n{\n  \"reqId\": \"2a42cff1-bfb5-4d5d-b185-353c8c71a00b\",\n  \"method\": \"response\",\n  \"version\": \"1.0\",\n  \"timestamp\": 1705462410448,\n  \"name\": \"roomMemberAllGet\",\n  \"code\": 200,\n  \"message\": \"success\",\n  \"params\": {\n    \"page\": 1,\n    \"size\": 100,\n    \"total\": 3,\n    \"items\": [\n      {\n        \"_events\": {},\n        \"_eventsCount\": 0,\n        \"id\": \"wxid_pnza7m7kf9tq12\",\n        \"payload\": {\n          \"alias\": \"\",\n          \"friend\": true,\n          \"id\": \"wxid_pnza7m7kf9tq12\",\n          \"name\": \"瓦力\",\n          \"phone\": [],\n          \"type\": 1\n        }\n      },\n      {\n        \"_events\": {},\n        \"_eventsCount\": 0,\n        \"id\": \"tyutluyc\",\n        \"payload\": {\n          \"alias\": \"超哥\",\n          \"friend\": true,\n          \"id\": \"tyutluyc\",\n          \"name\": \"luyuchao\",\n          \"phone\": [],\n          \"type\": 1\n        }\n      },\n      {\n        \"_events\": {},\n        \"_eventsCount\": 0,\n        \"id\": \"wxid_0o1t51l3f57221\",\n        \"payload\": {\n          \"alias\": \"\",\n          \"avatar\": \"https://wx.qlogo.cn/mmhead/ver_1/xUlBgtTamVSCTw5KnGTxusBCT6eSQSgwDoRnp18ICZRp5JcWWFju1aLCzj5UurApCMDcLmfGOyxvDSwPL9yyoIB9zug49f5QjbI2HTk4ib1w/132\",\n          \"friend\": false,\n          \"gender\": 0,\n          \"id\": \"wxid_0o1t51l3f57221\",\n          \"name\": \"大师\",\n          \"phone\": [],\n          \"type\": 1\n        }\n      }\n    ]\n  }\n}\n```\n\n### 向指定群发消息\n\n\u003e 目前仅支持发送文本消息，图片、文件、视频、语音等消息即将支持\n\n- 请求\n\n```json\n{\n    \"reqId\":\"2a42cff1-bfb5-4d5d-b185-353c8c71a00b\",\n    \"method\":\"command\",\n    \"version\":\"1.0\",\n    \"timestamp\":1705384610041,\n    \"name\":\"roomSay\",\n    \"params\":{\n        \"rooms\":[\n            \"ledongmao@chat.room\"\n        ],\n        \"messageType\":\"Text\",\n        \"messagePayload\":\"hello\"\n    }\n}\n```\n\n- 响应\n\n```json\n{\n  \"reqId\": \"2a42cff1-bfb5-4d5d-b185-353c8c71a00b\",\n  \"method\": \"response\",\n  \"version\": \"1.0\",\n  \"timestamp\": 1705461448305,\n  \"name\": \"roomSay\",\n  \"code\": 200,\n  \"message\": \"success\",\n  \"params\": {\n    \"id\": \"ledongmao@chat.room\"\n  }\n}\n```\n\n### @指定群好友\n\n有瑕疵，调试中...\n\n- 请求\n\n```json\n{\n    \"reqId\":\"2a42cff1-bfb5-4d5d-b185-353c8c71a00b\",\n    \"method\":\"command\",\n    \"version\":\"1.0\",\n    \"timestamp\":1705384610041,\n    \"name\":\"roomSayAt\",\n    \"params\":{\n        \"contacts\":[\n            \"ledongmao\",\n            \"choogoo\"\n        ],\n        \"room\":\"ledongmao@chat.room\",\n        \"messageType\":\"Text\",\n        \"messagePayload\":\"hello\"\n    }\n}\n```\n\n- 响应\n\n```json\n{\n  \"reqId\": \"2a42cff1-bfb5-4d5d-b185-353c8c71a00b\",\n  \"method\": \"response\",\n  \"version\": \"1.0\",\n  \"timestamp\": 1705462056289,\n  \"name\": \"roomSayAt\",\n  \"code\": 200,\n  \"message\": \"success\"\n}\n```\n\n### 回复消息\n\n- 请求\n\n```json\n{\n    \"reqId\":\"2a42cff1-bfb5-4d5d-b185-353c8c71a00b\",\n    \"method\":\"command\",\n    \"version\":\"1.0\",\n    \"timestamp\":1705384610041,\n    \"name\":\"messageSay\",\n    \"params\":{\n      \"id\":\"xxxxx\",\n      \"messageType\":\"Text\",\n      \"messagePayload\":\"hello\"\n    }\n}\n```\n\n- 响应\n\n```json\n{\n  \"reqId\": \"2a42cff1-bfb5-4d5d-b185-353c8c71a00b\",\n  \"method\": \"response\",\n  \"version\": \"1.0\",\n  \"timestamp\": 1705463098535,\n  \"name\": \"messageSay\",\n  \"code\": 200,\n  \"message\": \"success\",\n  \"params\": {\n    \"id\": \"clrh8op130002yszc9col2coq\"\n  }\n}\n```\n\n```json\n{\n  \"reqId\": \"2a42cff1-bfb5-4d5d-b185-353c8c71a00b\",\n  \"method\": \"response\",\n  \"version\": \"1.0\",\n  \"timestamp\": 1705463049890,\n  \"name\": \"messageSay\",\n  \"code\": 200,\n  \"message\": \"消息不存在\",\n  \"params\": {}\n}\n```\n\n## 事件消息推送\n\n事件被推送到 thing/chatbot/${clinetId}/event/post主题（其中${clinetId}表示具体的clientId）\n订阅thing/chatbot/xxxx/event/post接收事件数据\n\n### 扫码 scan\n\n```json\n{\n  \"reqId\": \"2a42cff1-bfb5-4d5d-b185-353c8c71a00b\",\n  \"method\": \"event\",\n  \"version\": \"1.0\",\n  \"timestamp\": 1705384610041,\n  \"name\": \"scan\",\n  \"params\": {\n    \"qrcode\": \"https://login.weixin.qq.com/l/gaD8UC3bcA==\",\n    \"status\": 2\n  }\n}\n```\n\n### 登录 login\n\n```json\n{\n  \"reqId\": \"6e80b9ce-3585-46d2-982c-9be0087f21e2\",\n  \"method\": \"event\",\n  \"version\": \"1.0\",\n  \"timestamp\": 1705384714220,\n  \"name\": \"login\",\n  \"params\": {\n    \"_events\": {},\n    \"_eventsCount\": 0,\n    \"id\": \"@a4c7b5b71eb79b5f790f5d4c2270b0f3b787952a3a8ca08b228efe4832021299\",\n    \"payload\": {\n      \"alias\": \"\",\n      \"avatar\": \"/cgi-bin/mmwebwx-bin/webwxgeticon?seq=11550719\u0026username=@a4c7b5b71eb79b5f790f5d4c2270b0f3b787952a3a8ca08b228efe4832021299\u0026skey=@crypt_3f47a99d_1d59eeac1c79b47948fa86522b106b12\",\n      \"friend\": false,\n      \"gender\": 2,\n      \"id\": \"@a4c7b5b71eb79b5f790f5d4c2270b0f3b787952a3a8ca08b228efe4832021299\",\n      \"name\": \"瓦力\",\n      \"phone\": [],\n      \"star\": false,\n      \"type\": 1\n    }\n  }\n}\n```\n\n### 登出 logout\n\n```json\n{\n  \"reqId\": \"e0e8fb62-42a0-4b7c-9217-c3aadb9059dd\",\n  \"method\": \"event\",\n  \"version\": \"1.0\",\n  \"timestamp\": 1705384609786,\n  \"name\": \"logout\",\n  \"params\": [\n    {\n      \"_events\": {},\n      \"_eventsCount\": 0,\n      \"id\": \"@85ee0016d30773031e259b3de554c8542340104d9b7a2c2646f73076b990130a\",\n      \"payload\": {\n        \"alias\": \"\",\n        \"avatar\": \"/cgi-bin/mmwebwx-bin/webwxgeticon?seq=1946854219\u0026username=@85ee0016d30773031e259b3de554c8542340104d9b7a2c2646f73076b990130a\u0026skey=@crypt_3f47a99d_291be9b57007f9ec09ccd9cfda807c9c\",\n        \"friend\": false,\n        \"gender\": 2,\n        \"id\": \"@85ee0016d30773031e259b3de554c8542340104d9b7a2c2646f73076b990130a\",\n        \"name\": \"瓦力\",\n        \"phone\": [],\n        \"star\": false,\n        \"type\": 1\n      }\n    },\n    \"logout()\"\n  ]\n}\n```\n\n### 准备就绪 ready\n\n```json\n{\n  \"reqId\": \"46d3bcb9-f21b-4236-91a3-88efb99ff9f9\",\n  \"method\": \"event\",\n  \"version\": \"1.0\",\n  \"timestamp\": 1705384530329,\n  \"name\": \"ready\",\n  \"params\": []\n}\n```\n\n### 错误 error\n\n```json\n{\n  \"reqId\": \"52bd5dae-6cf5-44bb-a76c-982744ba585e\",\n  \"method\": \"event\",\n  \"version\": \"1.0\",\n  \"timestamp\": 1705384604626,\n  \"name\": \"error\",\n  \"params\": [\n    {\n      \"code\": 2,\n      \"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)\",\n      \"message\": \"连续3次同步失败，5s后尝试重启\",\n      \"name\": \"Error\",\n      \"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)\"\n    }\n  ]\n}\n```\n\n### 消息 message\n\n```json\n{\n  \"reqId\": \"2ee3362b-3142-44d5-b859-a15cb4177445\",\n  \"method\": \"event\",\n  \"version\": \"1.0\",\n  \"timestamp\": 1705384017113,\n  \"name\": \"message\",\n  \"params\": {\n    \"_events\": {},\n    \"_eventsCount\": 0,\n    \"id\": \"8768818756347691243\",\n    \"payload\": {\n      \"id\": \"8768818756347691243\",\n      \"talkerId\": \"@d3cc07d80f9add1b4acd87e49817d061\",\n      \"text\": \"h\",\n      \"timestamp\": 1705384016,\n      \"type\": 7,\n      \"roomId\": \"@@e3e01b946e9f19978ad0718269b78b4f5dc853fd8eda5aa2dd5601ac57cdb3a5\",\n      \"mentionIdList\": []\n    }\n  }\n}\n```\n\n```json\n{\n  \"reqId\": \"b8ae2de2-19a3-4533-a5d5-9c2b7630a113\",\n  \"method\": \"thing.event.post\",\n  \"version\": \"1.0\",\n  \"timestamp\": 1705385708810,\n  \"events\": {\n    \"onMessage\": {\n      \"_id\": \"clrfyma84006vropd2i4ecmax\",\n      \"data\": {\n        \"_events\": {},\n        \"_eventsCount\": 0,\n        \"id\": \"clrfyma84006vropd2i4ecmax\",\n        \"payload\": {\n          \"id\": \"clrfyma84006vropd2i4ecmax\",\n          \"listenerId\": \"\",\n          \"roomId\": \"19036636423@chatroom\",\n          \"talkerId\": \"wxid_zqbyd7b5kwy322\",\n          \"text\": \"各位领导、同事\\n      关于集团第四季度模拟钓鱼邮件演练，金茂商业有7名同事点击钓鱼链接，按总部要求加强各单位钓鱼邮件的识别、防御和处理能力。\\n我们项目出现中招情况，故此，进行项目全员钓鱼邮件专题考试，希望大家在钓鱼邮件方面进一步加强安全意识意识和处置技能。\\n以下为考试链接，请全员在1月19日前完成考试，我们将在群内公示考试人数。\\nhttps://docs.chinajinmao.cn/form/ew/HOasNVyb/\\n邀你填写「预防钓鱼邮件专题考试」\",\n          \"timestamp\": 1705385708356,\n          \"toId\": \"\",\n          \"type\": 7\n        }\n      },\n      \"room\": {\n        \"_events\": {},\n        \"_eventsCount\": 0,\n        \"id\": \"19036636423@chatroom\",\n        \"payload\": {\n          \"adminIdList\": [],\n          \"avatar\": \"\",\n          \"external\": false,\n          \"id\": \"19036636423@chatroom\",\n          \"ownerId\": \"\",\n          \"topic\": \"宁波金茂汇项目团队\"\n        }\n      },\n      \"talker\": {\n        \"_events\": {},\n        \"_eventsCount\": 0,\n        \"id\": \"wxid_zqbyd7b5kwy322\",\n        \"payload\": {\n          \"friend\": true,\n          \"id\": \"wxid_zqbyd7b5kwy322\",\n          \"name\": \"清昼\",\n          \"phone\": [],\n          \"type\": 1\n        }\n      },\n      \"time\": \"56011-07-10 20:19:16\",\n      \"timestamp\": 1705385708356000\n    }\n  }\n}\n```\n\n### 心跳 heartbeat\n\n### 好友关系 friendship\n\n### 邀请进群 room-invite\n\n### 加入群 room-join\n\n### 离开群 room-leave\n\n### 群名称变更 room-topic\n\n### 重载 dirty\n\n## 附录\n\n### Wechaty文档\n\n[https://wechaty.js.org/docs/api/wechaty](https://wechaty.js.org/docs/api/wechaty)\n\n### Wechaty事件定义\n\n| Name | Type | Description |\n| --- | --- | --- |\n| error | string | When the bot get error, there will be a Wechaty error event fired. |\n| login | string | After the bot login full successful, the event login will be emitted, with a Contact of current logined user. |\n| logout | string | Logout will be emitted when bot detected log out, with a Contact of the current login user. |\n| heartbeat | string | Get bot's heartbeat. |\n| friendship | string | When someone sends you a friend request, there will be a Wechaty friendship event fired. |\n| message | string | Emit when there's a new message. |\n| ready | string | Emit when all data has load completed, in wechaty-puppet-padchat, it means it has sync Contact and Room completed |\n| room-join | string | Emit when anyone join any room. |\n| room-topic | string | Get topic event, emitted when someone change room topic. |\n| room-leave | string | Emit when anyone leave the room. |\n| room-invite | string | Emit when there is a room invitation, see more in [RoomInvitation](https://wechaty.js.org/docs/api/room-invitation)\n 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. |\n| scan | string | A scan event will be emitted when the bot needs to show you a QR Code for scanning. \u003c/br\u003e It is recommend to install qrcode-terminal(run npm install qrcode-terminal) in order to show qrcode in the terminal. |\n\n### 案例\n\n[https://www.yuque.com/atorber/chatflow/ei64dvh6ba21yfes](https://www.yuque.com/atorber/chatflow/ei64dvh6ba21yfes)\n\n[https://github.com/atorber/chatbot-iot-terminal](https://github.com/atorber/chatbot-iot-terminal)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fatorber%2Fwechat-remote","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fatorber%2Fwechat-remote","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fatorber%2Fwechat-remote/lists"}