npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@zhin.js/adapter-icqq

v6.0.0

Published

Zhin.js adapter for ICQQ (QQ Bot)

Readme

@zhin.js/adapter-icqq

QQ 群助手 + 可选 @AI — 先在 demo.zhin.dev 或 Sandbox 调试逻辑,再接实机 QQ。启用 AI:npx zhin setup --ai。接入本适配器:npx zhin setup --adapters

Zhin.js ICQQ 适配器,通过 @icqqjs/cli 守护进程 IPC 连接已登录的 QQ 账号,支持群聊和私聊消息。协议与登录由 CLI 负责,Zhin 侧只配置 QQ 号并连接本地/远程守护进程。

功能特性

  • 🤖 支持 QQ 群聊、私聊与群临时会话消息处理
  • 🔐 登录由 icqq login 完成(短信/二维码/滑块等由 CLI 处理)
  • 🖥️ Web 控制台登录辅助:与 @zhin.js/host-api 同时启用时,在 /icqq 页面提供「概览 + 登录辅助」;HTTP 接口为 GET /api/login-assist/pendingPOST /api/login-assist/submitPOST /api/login-assist/cancel(由本适配器在路由上下文中注册,依赖核心 loginAssist 服务)。
  • 📨 消息发送和接收处理
  • 🔄 消息格式转换和适配
  • 📁 自动数据目录管理
  • 🖼️ 支持图片、语音、视频等多媒体消息
  • 🎯 支持 @ 提及和引用回复
  • 🔧 群管理工具:踢人、禁言、设置管理员、群名片、头衔等(AI 可调用)
  • 🔒 权限控制:基于群角色的工具权限过滤

安装

pnpm add @zhin.js/adapter-icqq

登录与守护进程由 @icqqjs/cli 提供(与适配器包解耦,可全局安装):

pnpm add -g @icqqjs/cli
# 或:npx icqq login

配置

zhin.config.yml 中声明 bot(不在此填写 QQ 密码):

endpoints:
  - context: icqq
    name: "${ICQQ_ACCOUNT}"   # QQ 号,须与 icqq login 的账号一致
    autoReconnect: true         # IPC 断开后自动重连,默认 true
    # 远程 RPC(可选;默认连接 ~/.icqq/<uin>/daemon.sock)
    # rpc:
    #   host: 10.0.0.2
    #   port: 9527
    #   token: ${ICQQ_RPC_TOKEN}
    typingIndicator:          # 可选:AI 处理中的群/私聊提示
      enabled: true
      defaultEmoji: "⏳"

plugins:
  - "@zhin.js/adapter-icqq"
  - "@zhin.js/host-router"     # 可选
  - "@zhin.js/host-api"        # 可选,Remote Console /icqq 页

TypeScript 配置等价写法:

import { defineConfig } from 'zhin.js'

export default defineConfig({
  endpoints: [
    {
      context: 'icqq',
      name: process.env.ICQQ_ACCOUNT!,
    },
  ],
  plugins: ['@zhin.js/adapter-icqq'],
})

配置参数说明

必需参数

  • context: 固定为 'icqq'
  • name: QQ 号(字符串,与守护进程账号一致)

可选参数

  • autoReconnect: IPC/RPC 意外断开时是否指数退避重连(默认 true
  • rpc: 远程守护进程连接(host / port / token);不配置则使用本地 Unix socket ~/.icqq/<uin>/daemon.sock
  • typingIndicator: AI 处理中的 reaction 或临时消息提示(见 IcqqEndpointConfig 类型)

使用示例

基础消息处理

import { addCommand, MessageCommand } from 'zhin.js'

addCommand(new MessageCommand('hello <name:text>')
  .action(async (message, result) => {
    return `你好,${result.params.name}!`
  })
)

群聊消息

import { onGroupMessage } from 'zhin.js'

onGroupMessage(async (message) => {
  console.log(`群 ${message.$channel.id} 收到消息:${message.$raw}`)
  
  // 回复群消息
  await message.$reply('收到消息了!')
})

私聊消息

import { onPrivateMessage } from 'zhin.js'

onPrivateMessage(async (message) => {
  console.log(`私聊消息来自:${message.$sender.name}`)
  await message.$reply('你好!')
})

发送图片

addCommand(new MessageCommand('pic <url:text>')
  .action(async (message, result) => {
    return [
      { type: 'image', data: { file: result.params.url } }
    ]
  })
)

Zhin 与 icqq 守护进程不在同一台机器时,请在 zhin.config.yml 为该 bot 设置 outboundMedia: base64(或配置 rpc 时会自动默认 base64)。此时 segment 保留 base64,经 CQ [image:base64://...] 交给守护进程解码,不要使用仅在本机有效的临时文件路径。

Agent generate_image 文生图出站的大图同样依赖上述配置;同机默认可用本机临时文件路径(outboundMedia: file)。详见 文生图 (generate_image)

endpoints:
  - context: icqq
    name: "123456"
    outboundMedia: base64   # 异机 / 远程 RPC
    # rpc: { host: ..., port: ..., token: ... }  # 配置 rpc 时默认已是 base64

发送语音

addCommand(new MessageCommand('voice <file:text>')
  .action(async (message, result) => {
    return [
      { type: 'record', data: { file: result.params.file } }
    ]
  })
)

@ 提及

addCommand(new MessageCommand('at <user:at>')
  .action(async (message, result) => {
    const atUser = result.params.user
    return [
      { type: 'at', data: { qq: atUser.data.qq } },
      { type: 'text', data: { text: ' 你好!' } }
    ]
  })
)

登录流程

  1. 先登录 QQ:在终端执行 icqq login,按 CLI 提示完成密码/扫码/滑块/设备锁等验证;会话由 @icqqjs/cli 守护进程维护。
  2. 再启动 Zhinzhin.config.ymlendpoints[].name 与上一步 QQ 号一致,启动 zhin dev / zhin start;适配器连接守护进程并开始收发消息。
  3. 若守护进程未运行或账号未登录,适配器会保持未连接状态,日志中会提示检查 icqq 守护进程。

Web 控制台登录辅助(可选)

@zhin.js/host-api 同时启用时,Remote Console 的 ICQQ 管理/icqq)可提供登录辅助 Tab,对应 API:GET/POST /api/login-assist/*(依赖核心 loginAssist 服务)。

守护进程在登录/重连时按 @icqqjs/cli IPC 契约推送 IpcEventid: "*" + event: "system.login.*" + data)。其中 system.login.auth 携带 url + device 设备指纹(形状见 @icqqjs/icqq EventMap)。适配器将其桥接到 LoginAssist 并在控制台展示;用户完成验证后,续传 invoke 与 CLI LoginFlow 一致(login / submit_slider / submit_sms_code / send_sms_code,见 login-ipc-contract.ts)。

消息类型支持

接收消息类型

  • ✅ 文本消息
  • ✅ 图片消息
  • ✅ 语音消息
  • ✅ 视频消息
  • ✅ @ 提及
  • ✅ 表情消息
  • ✅ 引用回复
  • ✅ 文件消息
  • ✅ JSON 卡片消息
  • 群临时会话message_type=private + sub_type=group$channelprivate + parent.group

发送消息类型

  • ✅ 文本消息
  • ✅ 图片消息(支持本地文件、URL、Base64)
  • ✅ 语音消息
  • ✅ 视频消息
  • ✅ @ 提及
  • ✅ 表情消息
  • ✅ 引用回复
  • ✅ 文件消息
  • ✅ JSON 卡片消息
  • ✅ 戳一戳
  • ✅ 音乐分享
  • 群临时会话type: private + parent: { type: 'group', id } → IPC send_temp_msg

群临时会话

当群成员通过「临时会话」私聊机器人时,新版 @icqqjs/cli 会以私聊事件推送(sub_type: groupsender.group_id 为来源群)。适配器使用 private + parent.group 表达场景,而非发明新的顶层 MessageType

| 字段 | 值 | |------|-----| | $channel.type | private(对端 QQ) | | $channel.parent | { type: 'group', id: 群号 } |

message.$reply 会原样带上 parent,出站自动走 send_temp_msg

await adapter.sendMessage({
  context: 'icqq',
  endpoint: '你的QQ号',
  type: 'private',
  id: '987654321',
  parent: { type: 'group', id: '123456789' },
  content: [{ type: 'text', data: { text: '你好' } }],
})

API 方法

const endpoint = app.adapters.get('icqq')?.endpoints.get('你的QQ号')

// 发送群消息
await endpoint.sendGroupMsg(groupId, '消息内容')

// 发送私聊消息
await endpoint.sendPrivateMsg(userId, '消息内容')

// 撤回消息
await endpoint.$recallMessage(messageId)

// 获取群列表
const groupList = endpoint.getGroupList()

// 获取好友列表
const friendList = endpoint.getFriendList()

// 获取群成员信息
const memberInfo = endpoint.getGroupMemberInfo(groupId, userId)

🔧 群管理工具(AI 可调用)

适配器通过覆写 IGroupManagement 标准方法自动注册群管理工具,同时保留平台特有工具,这些工具可以被 AI 调用,实现智能化的群管理。

标准群管工具(自动生成)

通过覆写 IGroupManagement 方法,start() 时自动检测并生成对应 Tool:

| 工具 | 覆写方法 | 所需权限 | 说明 | |------|---------|----------|------| | icqq_kick_member | kickMember | 管理员 | 踢出群成员 | | icqq_mute_member | muteMember | 管理员 | 禁言群成员 | | icqq_mute_all | muteAll | 管理员 | 全员禁言 | | icqq_set_admin | setAdmin | 群主 | 设置/取消管理员 | | icqq_set_nickname | setMemberNickname | 管理员 | 设置群名片 | | icqq_set_group_name | setGroupName | 管理员 | 修改群名称 | | icqq_list_members | listMembers | 普通用户 | 获取群成员列表 |

平台特有工具(手动注册)

| 工具 | 所需权限 | 说明 | |------|----------|------| | icqq_set_title | 群主 | 设置专属头衔 | | icqq_announce | 管理员 | 发送群公告 | | icqq_poke | 普通用户 | 戳一戳 | | icqq_list_muted | 普通用户 | 获取被禁言成员列表 | | icqq_send_user_like | 普通用户 | 发送用户点赞 | | icqq_set_anonymous | 管理员 | 开启/关闭匿名聊天 | | icqq_group_files | 普通用户 | 获取群文件列表 | | icqq_friend_list | 普通用户 | 获取好友列表 |

使用示例

通过 AI 对话管理群

用户(群主):把 @小明 踢出群并拉黑
AI:已将 小明 踢出群并拉黑。

用户(管理员):禁言 @捣蛋鬼 1小时
AI:已禁言 捣蛋鬼 3600 秒。

用户(管理员):发个群公告:明天下午3点开会
AI:群公告已发送。

用户:戳一戳 @朋友
AI:已戳了戳 朋友。

编程调用

// 获取 ICQQ Endpoint 实例
const icqqAdapter = app.adapters.get('icqq')
const endpoint = icqqAdapter?.endpoints.get('你的QQ号')

// 踢出成员
await endpoint.kickMember(groupId, userId, true) // 第三个参数为是否拉黑

// 禁言成员(单位:秒)
await endpoint.muteMember(groupId, userId, 600) // 禁言 10 分钟
await endpoint.muteMember(groupId, userId, 0)   // 解除禁言

// 全员禁言
await endpoint.muteAll(groupId, true)  // 开启
await endpoint.muteAll(groupId, false) // 关闭

// 设置管理员
await endpoint.setAdmin(groupId, userId, true)  // 设为管理员
await endpoint.setAdmin(groupId, userId, false) // 取消管理员

// 设置群名片
await endpoint.setCard(groupId, userId, '新名片')

// 设置专属头衔
await endpoint.setTitle(groupId, userId, '大佬', -1) // -1 表示永久

// 修改群名
await endpoint.setGroupName(groupId, '新群名')

// 发送群公告
await endpoint.sendAnnounce(groupId, '公告内容')

// 戳一戳
await endpoint.pokeMember(groupId, userId)

// 获取群成员列表
const members = await endpoint.getMemberList(groupId)

// 获取被禁言成员列表
const mutedList = await endpoint.getMutedMembers(groupId)

// 开启/关闭匿名
await endpoint.setAnonymous(groupId, true)

发送者权限信息

消息中的 $sender 包含 ICQQ 特有的权限信息:

interface IcqqSenderInfo {
  id: string;           // QQ 号
  name: string;         // 昵称
  role?: GroupRole;     // 'owner' | 'admin' | 'member'
  isOwner?: boolean;    // 是否为群主
  isAdmin?: boolean;    // 是否为管理员
  card?: string;        // 群名片
  title?: string;       // 专属头衔
}

在插件中检查权限

onGroupMessage(async (message) => {
  const sender = message.$sender as IcqqSenderInfo;
  
  if (sender.isOwner) {
    console.log('这是群主的消息');
  }
  
  if (sender.isAdmin) {
    console.log('这是管理员的消息');
  }
  
  if (sender.role === 'member') {
    console.log('这是普通成员的消息');
  }
})

icqq CLI 与 AI bash 安全

启用 icqq 技能skills/icqq)时,模型通常会通过 bash 调用 icqq … 命令行。此时由框架 execSecurity / execApprovalModeOwner 私聊指令approve always bashapprove rule <正则> 等)共同约束:在 allowlist 下,非敏感子命令多数可直接执行;敏感子命令(踢人、禁言、解散、支付等)在 execApprovalMode: ask 时需 Owner 确认,并可用 正则匹配整条子命令 做持久化放行(不必把 QQ 号写进配置)。持久化文件为数据目录下的 owner-approve-always.json

完整说明与指令表见仓库文档:docs/advanced/ai.md(锚点:#icqq-bash-exec#owner-approve-commands)。

注意事项

账号安全

  • 建议使用小号测试
  • 避免短时间内发送大量消息
  • 保持 @icqqjs/cli 与适配器版本更新

风控与掉线

  • 登录设备类型、签名服务等由 icqq login / CLI 配置 管理,不在 zhin.config 的 bot 段配置
  • 掉线时先检查守护进程:icqq 是否仍在运行、账号是否被踢下线
  • 可降低发消息频率,并在手机 QQ 完成安全验证后重新 icqq login

常见问题

Q: 启动后 bot 一直未连接?

A:

  1. 确认已对该 QQ 号执行过 icqq login 且守护进程在运行
  2. 确认 endpoints[].name 与登录 QQ 号一致
  3. 远程部署时检查 rpc.host / rpc.port / rpc.token

Q: 还需要在 zhin.config 里写 password / platform 吗?

A: 不需要。这些字段属于旧版直连协议,当前适配器仅通过 IPC 连接 CLI 守护进程。

Q: 无法发送图片?

A:

  1. 检查图片 URL 是否有效
  2. 本地文件需使用绝对路径
  3. 确认图片格式和大小符合要求

Q: 如何处理滑块/设备锁验证?

A: 在运行 icqq login 的终端按提示操作;若启用了 Host API,也可在 Remote Console /icqq 登录辅助 Tab 提交验证码。

相关链接

依赖项

  • @icqqjs/cli - 登录与守护进程(运行时需已安装并在 PATH 中)
  • zhin.js / @zhin.js/core - Zhin 框架(peer)
  • @zhin.js/host-router / @zhin.js/host-api - 可选,Console 与 HTTP 路由

开发

pnpm build  # 构建
pnpm clean  # 清理构建文件

许可证

MIT License

贡献

欢迎提交 Issue 和 Pull Request!