当前位置:首页 > 技术 > 正文内容

基于Node.js与Wechaty构建微信个人助手

访客 技术 2026年7月25日 1

本文介绍如何利用Node.js配合Wechaty框架开发一个具备多项实用功能的微信个人助手。该助手能够自动处理好友请求、关键词响应、群聊互动、小程序解析及翻译等任务。

Wechaty简介

Wechaty是一个面向聊天机器人的现代RPA SDK,开发者仅需少量代码即可快速构建功能丰富的聊天机器人。它支持将即时通讯账号转换为智能助手,并允许开发者根据具体需求进行定制扩展。

最小化示例

以下是最基础的机器人实现,仅需数行代码:

const { Wechaty } = require('wechaty')

async function main () {
  const bot = new Wechaty()
  bot
    .on('scan', (qrcode, status) => console.log(`扫描二维码登录: ${status}\nhttps://wechaty.js.org/qrcode/${encodeURIComponent(qrcode)}`))
    .on('login',   user => console.log(`用户 ${user} 已登录`))
    .on('message', message => console.log(`收到消息: ${message}`))
  await bot.start()
}

main().catch(console.error)

环境准备

开始前,请确保拥有可运行Wechaty的微信账号,并获取相应协议的Token(如puppet_padlocal)。

核心功能

  • 自动接受好友请求,支持关键字验证
  • 私信关键词响应,例如"加群"推送邀请
  • 群聊互动模式,支持@机器人对话
  • 小程序信息提取
  • 新成员入群欢迎语
  • 英文文本翻译(限2000字符内)

依赖接口

  • 有道翻译、百度翻译
  • 天行数据API

关键代码实现

主程序入口

bot.js

const { Wechaty } = require("wechaty");
const { PuppetPadlocal } = require("wechaty-puppet-padlocal");
const QrcodeTerminal = require("qrcode-terminal");
const onMessage = require("./onMessage");
const config = require("./config");

const bot = new Wechaty({
  puppet: new PuppetPadlocal({
    token: config.token,
  }),
});

bot
  .on("scan", (qrcode, status) => {
    console.log(`扫码登录: ${status}\nhttps://api.qrserver.com/v1/create-qr-code/?data=${encodeURIComponent(qrcode)}`);
    QrcodeTerminal.generate(qrcode);
  })
  .on("login", user => console.log(`${user} 登录成功`))
  .on("logout", user => console.log(`${user} 已登出`))
  .on("message", onMessage(bot))
  .start();

消息处理模块

onMessage.js

const { UrlLink } = require("wechaty");
const request = require("request");
const urlencode = require("urlencode");
const config = require("./config");
const miniProrReply = require("../utils/miniProReply");
const translate = require("../utils/translate");
const { rainbowFart, circle, drugInstruction } = require("../utils/txAPI");

const name = config.name;
const roomList = config.room.roomList;

module.exports = (bot) => {
  return async function onMessage(msg) {
    if (msg.self()) return;

    switch (msg.type()) {
      case 7: // 文本消息
        console.log("接收到文本");
        if (await handleJoinGroup(msg)) return;
        if (await handleGroupName(bot, msg)) return;
        
        if (msg.payload.roomId) {
          if (msg.payload.roomId === "20856899751@chatroom") {
            const reg = /^[\u4e00-\u9fa5]+$/;
            if (!reg.test(msg.text())) {
              translate(msg);
              return;
            } else {
              handleRoomChat(msg);
              return;
            }
          }
        }
        break;
      case 9: // 小程序
        console.log("检测到小程序");
        miniProrReply(msg);
        break;
      case 14: // 卡片链接
        console.log("检测到卡片链接");
        break;
      default:
        console.log("暂不支持此消息类型");
        break;
    }
  };
};

async function handleRoomChat(msg) {
  const room = msg.room();
  const text = msg.text();

  if (await msg.mentionSelf()) {
    const sendText = text.replace("@蔚蓝", "");
    let res = await callBotAPI(sendText);
    room.say(res);
  } else {
    let content = await callBotAPI(text);
    room.say(content);
    return;
  }

  if (/互动/.test(text)) {
    room.say("互动测试");
  } else if (/彩虹屁/.test(text)) {
    let reply = await rainbowFart({});
    room.say(reply);
  } else if (/文案/.test(text)) {
    let reply = await circle({});
    room.say(reply);
  } else if (/蔚蓝工作室/.test(text)) {
    room.say(new UrlLink(config.personal.introUrl));
  } else if (/药品/.test(text)) {
    let params = { word: text.substring(2) };
    let reply = await drugInstruction(params);
    room.say(reply);
  }
}

async function handleJoinGroup(msg) {
  if (msg.text() == "加群") {
    let roomNames = Object.keys(roomList);
    let info = `${name}当前管理${roomNames.length}个群聊,回复群名即可加入\n\n`;
    roomNames.forEach(v => {
      info += "【" + v + "】\n";
    });
    msg.say(info);
    return true;
  }
  return false;
}

async function handleGroupName(bot, msg) {
  if (Object.keys(roomList).some(v => v == msg.text())) {
    const room = await bot.Room.find({ id: roomList[msg.text()] });
    
    if (await room.has(msg.from())) {
      await msg.say("您已在该群聊中");
      return true;
    }

    await room.add(msg.from());
    await msg.say("已发送群邀请");
    return true;
  }
  return false;
}

function callBotAPI(info) {
  return new Promise((resolve) => {
    let url = `https://open.drea.cc/bbsapi/chat/get?keyWord=${urlencode(info)}`;
    request(url, (error, response, body) => {
      if (!error && response.statusCode == 200) {
        let res = JSON.parse(body);
        if (res.isSuccess) {
          let send = res.data.reply.replace(/Smile/g, name);
          resolve(send);
        } else {
          resolve(res.code == 1010 ? "没事别老艾特我" : "听不懂你说的");
        }
      } else {
        resolve("网络异常,请稍后再试");
      }
    });
  });
}

工具函数目录

utils目录包含翻译接口调用、小程序参数解析、第三方API封装等功能模块,可根据实际需要修改相关密钥配置。

常见问题

  • 若使用旧版padplus协议,建议升级至hostie或service协议
  • 部分npm包可能已更名,请使用最新版本替代

Token获取

推荐使用padlocal协议,提供7天免费试用期。

通过合理配置各组件,您可以快速搭建属于自己的微信智能助手。完整源码可在GitHub查看。

相关文章

Linux crontab 详解

1) crontab 是什么cron 是 Linux 的定时任务守护进程;crontab 是用来编辑/查看“按时间周期执行命令”的表(cron table)。常见两类:用户 crontab:每个用户一份(crontab -e 编辑)系统级 crontab / cron.d:可指定执行用户(/etc/crontab、/etc/cron.d/*)2) crontab 时间...

富文本里可以允许的 HTML 属性

一、所有标签默认允许的安全属性(极少)class        (可选)id           (通常建议禁用)title️ 注意:id 容易被滥用做锚点注入,很多系统直接禁用class 允许的话最好只允许固定前缀(如 editor-*)二、a 标签允许属性<a href="" t...

Mac 安装 Node.js 指南

方法一:通过官网安装包(最简单,适合初学者)如果你只是想快速安装并开始使用,这是最直接的方法。访问 Node.js 官网。页面会显示两个版本:LTS (Recommended For Most Users):长期支持版,最稳定。建议选这个。Current:最新特性版,包含最新功能但可能不够稳定。下载 .pkg 安装包并运行。按照安装向导点击“下一步”即可完成。方法二:使用 Homebrew 安装(...

Dom\HTML_NO_DEFAULT_NS 的副作用:自动加闭合标签

在使用Dom\HTMLDocument时,Dom\HTML_NO_DEFAULT_NS 将禁止在解析过程中设置元素的命名空间, 此设置是为了与DOMDocument向后兼容而存在的。当使用它时,已知的一个副作用就是:自动加闭合标签例如 </img> 为什么会这样?当你使用:Dom\HTML_NO_DEFAULT_NS文档会变成 无命名空间模式,此时内部更接近 XML...

Laravel 事件和监听器创建

在 Laravel 中,使用 Artisan 命令创建 Events(事件) 和 Listeners(监听器) 是非常高效的。你可以通过以下几种方式来实现:1. 手动创建单个 Event如果你只想创建一个事件类,可以使用 make:event 命令:Bashphp artisan make:event UserRegistered执行后,文件将生成在 app/Even...

自定义域名解析神器 dnsmasq

什么是 dnsmasq?dnsmasq 是一个轻量级、功能强大的网络服务工具,专为小型和中等规模网络设计。它是一个综合的网络基础设施解决方案[1]。dnsmasq 能做什么?功能说明应用场景DNS 转发与缓存将 DNS 查询转发到上游服务器(ISP、Google DNS 等),并在本地缓存结果加快 DNS 查询速度,减少外部 DNS 流量本地 DNS解析本地网络设备的主机名,无需编辑&n...

发表评论

访客

◎欢迎参与讨论,请在这里发表您的看法和观点。