@zhin.js/adapter-icqq 6.0.2 → 7.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (125) hide show
  1. package/CHANGELOG.md +65 -0
  2. package/README.md +48 -435
  3. package/adapters/icqq.ts +92 -0
  4. package/agent/tools/announce.ts +2 -2
  5. package/agent/tools/essence.ts +2 -2
  6. package/agent/tools/friend_list.ts +2 -2
  7. package/agent/tools/group_files.ts +2 -2
  8. package/agent/tools/group_invite.ts +2 -2
  9. package/agent/tools/group_list.ts +2 -2
  10. package/agent/tools/group_sign.ts +2 -2
  11. package/agent/tools/list_muted.ts +2 -2
  12. package/agent/tools/poke.ts +2 -2
  13. package/agent/tools/send_user_like.ts +2 -2
  14. package/agent/tools/set_anonymous.ts +2 -2
  15. package/agent/tools/set_title.ts +2 -2
  16. package/lib/agent-prompt.d.ts +2 -0
  17. package/lib/{src/agent-prompt.js → agent-prompt.js} +0 -1
  18. package/lib/cq-message.d.ts +9 -0
  19. package/lib/{src/cq-message.js → cq-message.js} +0 -1
  20. package/lib/endpoint.d.ts +101 -0
  21. package/lib/endpoint.js +715 -0
  22. package/lib/forward-msg.d.ts +26 -0
  23. package/lib/{src/forward-msg.js → forward-msg.js} +0 -1
  24. package/lib/icqq-agent-deps.d.ts +25 -0
  25. package/lib/icqq-agent-deps.js +32 -0
  26. package/lib/icqq-guild.d.ts +53 -0
  27. package/lib/{src/icqq-guild.js → icqq-guild.js} +4 -2
  28. package/lib/icqq-inbound.d.ts +139 -0
  29. package/lib/{src/icqq-inbound.js → icqq-inbound.js} +27 -3
  30. package/lib/icqq-inbox.d.ts +33 -0
  31. package/lib/icqq-inbox.js +129 -0
  32. package/lib/index.d.ts +6 -0
  33. package/lib/index.js +6 -0
  34. package/lib/ipc-client.d.ts +73 -0
  35. package/lib/{src/ipc-client.js → ipc-client.js} +0 -1
  36. package/lib/outbound-media.d.ts +13 -0
  37. package/lib/{src/outbound-media.js → outbound-media.js} +0 -1
  38. package/lib/protocol.d.ts +269 -0
  39. package/lib/{src/protocol.js → protocol.js} +124 -2
  40. package/lib/types.d.ts +87 -0
  41. package/lib/{src/types.js → types.js} +0 -1
  42. package/package.json +49 -45
  43. package/plugin.ts +32 -0
  44. package/schema.json +104 -0
  45. package/src/endpoint.ts +704 -795
  46. package/src/icqq-agent-deps.ts +48 -9
  47. package/src/icqq-guild.ts +10 -4
  48. package/src/icqq-inbound.ts +31 -2
  49. package/src/icqq-inbox.ts +155 -0
  50. package/src/index.ts +36 -69
  51. package/src/protocol.ts +191 -1
  52. package/src/types.ts +16 -0
  53. package/client/ICQQManagement.tsx +0 -147
  54. package/client/LoginAssistPanel.tsx +0 -300
  55. package/client/index.tsx +0 -11
  56. package/client/tsconfig.json +0 -7
  57. package/client/utils/api.ts +0 -30
  58. package/dist/index.js +0 -34
  59. package/lib/agent/tools/announce.js +0 -21
  60. package/lib/agent/tools/announce.js.map +0 -1
  61. package/lib/agent/tools/essence.js +0 -22
  62. package/lib/agent/tools/essence.js.map +0 -1
  63. package/lib/agent/tools/friend_list.js +0 -19
  64. package/lib/agent/tools/friend_list.js.map +0 -1
  65. package/lib/agent/tools/group_files.js +0 -29
  66. package/lib/agent/tools/group_files.js.map +0 -1
  67. package/lib/agent/tools/group_invite.js +0 -20
  68. package/lib/agent/tools/group_invite.js.map +0 -1
  69. package/lib/agent/tools/group_list.js +0 -20
  70. package/lib/agent/tools/group_list.js.map +0 -1
  71. package/lib/agent/tools/group_sign.js +0 -19
  72. package/lib/agent/tools/group_sign.js.map +0 -1
  73. package/lib/agent/tools/list_muted.js +0 -23
  74. package/lib/agent/tools/list_muted.js.map +0 -1
  75. package/lib/agent/tools/poke.js +0 -20
  76. package/lib/agent/tools/poke.js.map +0 -1
  77. package/lib/agent/tools/send_user_like.js +0 -22
  78. package/lib/agent/tools/send_user_like.js.map +0 -1
  79. package/lib/agent/tools/set_anonymous.js +0 -22
  80. package/lib/agent/tools/set_anonymous.js.map +0 -1
  81. package/lib/agent/tools/set_title.js +0 -25
  82. package/lib/agent/tools/set_title.js.map +0 -1
  83. package/lib/src/adapter.js +0 -128
  84. package/lib/src/adapter.js.map +0 -1
  85. package/lib/src/agent-prompt.js.map +0 -1
  86. package/lib/src/cq-message.js.map +0 -1
  87. package/lib/src/endpoint.js +0 -755
  88. package/lib/src/endpoint.js.map +0 -1
  89. package/lib/src/forward-msg.js.map +0 -1
  90. package/lib/src/get-msg.js +0 -46
  91. package/lib/src/get-msg.js.map +0 -1
  92. package/lib/src/icqq-agent-deps.js +0 -10
  93. package/lib/src/icqq-agent-deps.js.map +0 -1
  94. package/lib/src/icqq-guild.js.map +0 -1
  95. package/lib/src/icqq-inbound.js.map +0 -1
  96. package/lib/src/icqq-login-assist-bridge.js +0 -148
  97. package/lib/src/icqq-login-assist-bridge.js.map +0 -1
  98. package/lib/src/icqq-side-events.js +0 -130
  99. package/lib/src/icqq-side-events.js.map +0 -1
  100. package/lib/src/index.js +0 -50
  101. package/lib/src/index.js.map +0 -1
  102. package/lib/src/ipc-client.js.map +0 -1
  103. package/lib/src/login-assist-routes.js +0 -29
  104. package/lib/src/login-assist-routes.js.map +0 -1
  105. package/lib/src/login-ipc-contract.js +0 -35
  106. package/lib/src/login-ipc-contract.js.map +0 -1
  107. package/lib/src/outbound-media.js.map +0 -1
  108. package/lib/src/protocol.js.map +0 -1
  109. package/lib/src/routes.js +0 -67
  110. package/lib/src/routes.js.map +0 -1
  111. package/lib/src/segment-mapper.js +0 -2
  112. package/lib/src/segment-mapper.js.map +0 -1
  113. package/lib/src/tools/index.js +0 -23
  114. package/lib/src/tools/index.js.map +0 -1
  115. package/lib/src/types.js.map +0 -1
  116. package/plugin.yml +0 -3
  117. package/src/adapter.ts +0 -151
  118. package/src/get-msg.ts +0 -56
  119. package/src/icqq-login-assist-bridge.ts +0 -196
  120. package/src/icqq-side-events.ts +0 -143
  121. package/src/login-assist-routes.ts +0 -39
  122. package/src/login-ipc-contract.ts +0 -52
  123. package/src/routes.ts +0 -83
  124. package/src/segment-mapper.ts +0 -1
  125. package/src/tools/index.ts +0 -31
@@ -1,29 +0,0 @@
1
- export function registerLoginAssistRoutes(router, root) {
2
- const loginAssist = root.inject("loginAssist");
3
- if (!loginAssist)
4
- return;
5
- router.get("/api/login-assist/pending", async (ctx) => {
6
- ctx.body = loginAssist.listPending();
7
- });
8
- router.post("/api/login-assist/submit", async (ctx) => {
9
- const body = (ctx.request.body ?? {});
10
- if (!body.id) {
11
- ctx.status = 400;
12
- ctx.body = { success: false, message: "missing id" };
13
- return;
14
- }
15
- const ok = loginAssist.submit(body.id, body.value ?? "");
16
- ctx.body = { success: ok };
17
- });
18
- router.post("/api/login-assist/cancel", async (ctx) => {
19
- const body = (ctx.request.body ?? {});
20
- if (!body.id) {
21
- ctx.status = 400;
22
- ctx.body = { success: false, message: "missing id" };
23
- return;
24
- }
25
- const ok = loginAssist.cancel(body.id, body.reason);
26
- ctx.body = { success: ok };
27
- });
28
- }
29
- //# sourceMappingURL=login-assist-routes.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"login-assist-routes.js","sourceRoot":"","sources":["../../src/login-assist-routes.ts"],"names":[],"mappings":"AAMA,MAAM,UAAU,yBAAyB,CAAC,MAAc,EAAE,IAAY;IACpE,MAAM,WAAW,GAAG,IAAI,CAAC,MAAM,CAAC,aAAa,CAAC,CAAC;IAC/C,IAAI,CAAC,WAAW;QAAE,OAAO;IAEzB,MAAM,CAAC,GAAG,CAAC,2BAA2B,EAAE,KAAK,EAAE,GAAG,EAAE,EAAE;QACpD,GAAG,CAAC,IAAI,GAAG,WAAW,CAAC,WAAW,EAAE,CAAC;IACvC,CAAC,CAAC,CAAC;IAEH,MAAM,CAAC,IAAI,CAAC,0BAA0B,EAAE,KAAK,EAAE,GAAQ,EAAE,EAAE;QACzD,MAAM,IAAI,GAAG,CAAC,GAAG,CAAC,OAAO,CAAC,IAAI,IAAI,EAAE,CAGnC,CAAC;QACF,IAAI,CAAC,IAAI,CAAC,EAAE,EAAE,CAAC;YACb,GAAG,CAAC,MAAM,GAAG,GAAG,CAAC;YACjB,GAAG,CAAC,IAAI,GAAG,EAAE,OAAO,EAAE,KAAK,EAAE,OAAO,EAAE,YAAY,EAAE,CAAC;YACrD,OAAO;QACT,CAAC;QACD,MAAM,EAAE,GAAG,WAAW,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE,EAAE,IAAI,CAAC,KAAK,IAAI,EAAE,CAAC,CAAC;QACzD,GAAG,CAAC,IAAI,GAAG,EAAE,OAAO,EAAE,EAAE,EAAE,CAAC;IAC7B,CAAC,CAAC,CAAC;IAEH,MAAM,CAAC,IAAI,CAAC,0BAA0B,EAAE,KAAK,EAAE,GAAQ,EAAE,EAAE;QACzD,MAAM,IAAI,GAAG,CAAC,GAAG,CAAC,OAAO,CAAC,IAAI,IAAI,EAAE,CAAqC,CAAC;QAC1E,IAAI,CAAC,IAAI,CAAC,EAAE,EAAE,CAAC;YACb,GAAG,CAAC,MAAM,GAAG,GAAG,CAAC;YACjB,GAAG,CAAC,IAAI,GAAG,EAAE,OAAO,EAAE,KAAK,EAAE,OAAO,EAAE,YAAY,EAAE,CAAC;YACrD,OAAO;QACT,CAAC;QACD,MAAM,EAAE,GAAG,WAAW,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE,EAAE,IAAI,CAAC,MAAM,CAAC,CAAC;QACpD,GAAG,CAAC,IAAI,GAAG,EAAE,OAAO,EAAE,EAAE,EAAE,CAAC;IAC7B,CAAC,CAAC,CAAC;AACL,CAAC"}
@@ -1,35 +0,0 @@
1
- /**
2
- * ICQQ 登录 IPC 契约(与 @icqqjs/cli / @icqqjs/icqq 对齐)
3
- *
4
- * **推送(Daemon → Client)** — 见 @icqqjs/cli `src/daemon/protocol.ts` 的 `IpcEvent`:
5
- * ```json
6
- * { "id": "*", "event": "system.login.auth", "data": { "url", "device" } }
7
- * ```
8
- * 事件名与载荷形状以 @icqqjs/icqq `EventMap` 为准(非 OneBot `post_type`)。
9
- *
10
- * **续传(Client → Daemon)** — 与 CLI `LoginFlow` / `AccountBootstrap` 对 icqq Client 的调用一致,
11
- * action 名为 Client 方法的 snake_case;收录于守护进程 `action-catalog` 后可通过 IPC invoke。
12
- *
13
- * @see https://github.com/icqqjs/cli/blob/master/src/daemon/protocol.ts
14
- * @see https://github.com/icqqjs/cli/blob/master/src/lib/account-bootstrap.ts
15
- * @see https://github.com/icqqjs/cli/blob/master/src/components/LoginFlow.tsx
16
- */
17
- /** 登录续传 IPC action(与 LoginFlow → Client 方法一一对应) */
18
- export const LoginIpcActions = {
19
- /** 扫码确认 / 设备锁链接确认 / auth 237 验证完成后继续 — client.login() */
20
- LOGIN: 'login',
21
- /** 滑块 ticket — client.submitSlider(ticket) */
22
- SUBMIT_SLIDER: 'submit_slider',
23
- /** 设备锁短信验证码 — client.submitSmsCode(code) */
24
- SUBMIT_SMS_CODE: 'submit_sms_code',
25
- /** 请求发送设备锁短信 — client.sendSmsCode() */
26
- SEND_SMS_CODE: 'send_sms_code',
27
- };
28
- /** CLI LoginFlow 237 验证步骤(供 Web 控制台展示) */
29
- export const AUTH_DEVICE_STEPS = [
30
- '打开上方验证链接,正常完成验证流程,直到发送完验证码,不要点击「我已发送」',
31
- '复制下方 JS,打开浏览器开发者工具(F12)→ Console,粘贴并回车',
32
- '在弹窗中粘贴设备信息 JSON 并确认(可使用下方单行 JSON)',
33
- '回到验证页点击「我已发送」,完成 237 验证后回到控制台点击确认',
34
- ];
35
- //# sourceMappingURL=login-ipc-contract.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"login-ipc-contract.js","sourceRoot":"","sources":["../../src/login-ipc-contract.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAgBH,mDAAmD;AACnD,MAAM,CAAC,MAAM,eAAe,GAAG;IAC7B,yDAAyD;IACzD,KAAK,EAAE,OAAO;IACd,8CAA8C;IAC9C,aAAa,EAAE,eAAe;IAC9B,4CAA4C;IAC5C,eAAe,EAAE,iBAAiB;IAClC,uCAAuC;IACvC,aAAa,EAAE,eAAe;CACtB,CAAC;AAIX,0CAA0C;AAC1C,MAAM,CAAC,MAAM,iBAAiB,GAAG;IAC/B,uCAAuC;IACvC,wCAAwC;IACxC,mCAAmC;IACnC,mCAAmC;CAC3B,CAAC"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"outbound-media.js","sourceRoot":"","sources":["../../src/outbound-media.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,SAAS,CAAC;AAC9B,OAAO,KAAK,EAAE,MAAM,SAAS,CAAC;AAC9B,OAAO,KAAK,IAAI,MAAM,WAAW,CAAC;AAClC,OAAO,KAAK,MAAM,MAAM,aAAa,CAAC;AAMtC,SAAS,UAAU,CAAC,IAAY,EAAE,QAAgB;IAChD,MAAM,GAAG,GAA2B;QAClC,YAAY,EAAE,MAAM;QACpB,WAAW,EAAE,MAAM;QACnB,WAAW,EAAE,MAAM;QACnB,YAAY,EAAE,OAAO;QACrB,YAAY,EAAE,MAAM;QACpB,WAAW,EAAE,MAAM;QACnB,WAAW,EAAE,MAAM;KACpB,CAAC;IACF,OAAO,GAAG,CAAC,IAAI,CAAC,IAAI,QAAQ,CAAC;AAC/B,CAAC;AAED,SAAS,iBAAiB,CACxB,MAAc,EACd,IAAY,EACZ,IAAY;IAEZ,MAAM,GAAG,GAAG,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,MAAM,EAAE,EAAE,oBAAoB,CAAC,CAAC;IACzD,EAAE,CAAC,SAAS,CAAC,GAAG,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IACvC,MAAM,GAAG,GAAG,UAAU,CAAC,IAAI,EAAE,IAAI,KAAK,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,KAAK,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC;IAC7F,MAAM,QAAQ,GAAG,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,IAAI,IAAI,MAAM,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC,GAAG,GAAG,EAAE,CAAC,CAAC;IAC1F,EAAE,CAAC,aAAa,CAAC,QAAQ,EAAE,MAAM,CAAC,IAAI,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAC,CAAC;IAC1D,OAAO,QAAQ,CAAC;AAClB,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,4BAA4B,CAC1C,MAAyD;IAEzD,IAAI,MAAM,CAAC,aAAa,KAAK,QAAQ,IAAI,MAAM,CAAC,aAAa,KAAK,MAAM,EAAE,CAAC;QACzE,OAAO,MAAM,CAAC,aAAa,CAAC;IAC9B,CAAC;IACD,OAAO,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC;AACxC,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,yBAAyB,CACvC,OAAoB,EACpB,OAA8B,MAAM;IAEpC,IAAI,IAAI,KAAK,QAAQ;QAAE,OAAO,OAAO,CAAC;IAEtC,MAAM,QAAQ,GAAG,KAAK,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC;IAC9D,OAAO,QAAQ,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE;QAC1B,IAAI,OAAO,GAAG,KAAK,QAAQ;YAAE,OAAO,GAAG,CAAC;QACxC,MAAM,EAAE,IAAI,EAAE,IAAI,EAAE,GAAG,GAAqB,CAAC;QAC7C,MAAM,CAAC,GAAG,IAA+B,CAAC;QAC1C,MAAM,GAAG,GAAG,CAAC,CAAC,MAAM,IAAI,CAAC,CAAC,IAAI,CAAC;QAC/B,IAAI,OAAO,GAAG,KAAK,QAAQ,IAAI,CAAC,GAAG;YAAE,OAAO,GAAG,CAAC;QAEhD,MAAM,IAAI,GAAG,MAAM,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC,CAAC,QAAQ,IAAI,EAAE,CAAC,CAAC;QAChD,IAAI,IAAI,KAAK,OAAO,IAAI,IAAI,KAAK,QAAQ,IAAI,IAAI,KAAK,OAAO,IAAI,IAAI,KAAK,OAAO,EAAE,CAAC;YAClF,MAAM,QAAQ,GAAG,iBAAiB,CAChC,GAAG,EACH,IAAI,IAAI,CAAC,IAAI,KAAK,OAAO,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,IAAI,KAAK,OAAO,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,YAAY,CAAC,EACzF,IAAI,KAAK,QAAQ,IAAI,IAAI,KAAK,OAAO,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,CACvD,CAAC;YACF,OAAO;gBACL,IAAI;gBACJ,IAAI,EAAE;oBACJ,GAAG,CAAC;oBACJ,IAAI,EAAE,QAAQ;oBACd,GAAG,EAAE,QAAQ;iBACd;aACgB,CAAC;QACtB,CAAC;QACD,OAAO,GAAG,CAAC;IACb,CAAC,CAAC,CAAC;AACL,CAAC"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"protocol.js","sourceRoot":"","sources":["../../src/protocol.ts"],"names":[],"mappings":"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"}
package/lib/src/routes.js DELETED
@@ -1,67 +0,0 @@
1
- import { Actions } from "./protocol.js";
2
- export function registerRoutes(router, icqq, _root) {
3
- router.get("/api/icqq/endpoints", async (ctx) => {
4
- try {
5
- const endpoints = Array.from(icqq.endpoints.values());
6
- if (endpoints.length === 0) {
7
- ctx.body = { success: true, data: [], message: "暂无ICQQEndpoint 实例" };
8
- return;
9
- }
10
- const result = await Promise.all(endpoints.map(async (endpoint) => {
11
- try {
12
- const base = {
13
- name: endpoint.$config.name,
14
- connected: endpoint.$connected || false,
15
- groupCount: endpoint.groups.size,
16
- friendCount: endpoint.friends.size,
17
- status: endpoint.$connected ? "online" : "offline",
18
- lastActivity: new Date().toISOString(),
19
- };
20
- // 尝试从守护进程获取详细状态
21
- if (endpoint.$connected && endpoint.ipc && !endpoint.ipc.closed) {
22
- try {
23
- const statusResp = await endpoint.ipc.request(Actions.GET_STATUS, {}, 5000);
24
- if (statusResp.ok && statusResp.data) {
25
- const stat = statusResp.data;
26
- base.receiveCount = stat.recv_msg_cnt ?? 0;
27
- base.sendCount = stat.sent_msg_cnt ?? 0;
28
- }
29
- }
30
- catch {
31
- // status 查询超时,忽略
32
- }
33
- }
34
- return base;
35
- }
36
- catch {
37
- return {
38
- name: endpoint.$config.name,
39
- connected: false,
40
- groupCount: 0,
41
- friendCount: 0,
42
- status: "error",
43
- error: "数据获取失败",
44
- };
45
- }
46
- }));
47
- ctx.body = {
48
- success: true,
49
- data: result,
50
- timestamp: new Date().toISOString(),
51
- };
52
- }
53
- catch (error) {
54
- ctx.status = 500;
55
- ctx.body = {
56
- success: false,
57
- error: "ICQQ_API_ERROR",
58
- message: "获取 Endpoint 数据失败",
59
- details: process.env.NODE_ENV === "development"
60
- ? error.message
61
- : undefined,
62
- timestamp: new Date().toISOString(),
63
- };
64
- }
65
- });
66
- }
67
- //# sourceMappingURL=routes.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"routes.js","sourceRoot":"","sources":["../../src/routes.ts"],"names":[],"mappings":"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"}
@@ -1,2 +0,0 @@
1
- export { toCanonicalSegments, fromCanonicalSegments } from 'zhin.js';
2
- //# sourceMappingURL=segment-mapper.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"segment-mapper.js","sourceRoot":"","sources":["../../src/segment-mapper.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,mBAAmB,EAAE,qBAAqB,EAAE,MAAM,SAAS,CAAC"}
@@ -1,23 +0,0 @@
1
- /**
2
- * ICQQ 场景管理工具注册
3
- *
4
- * 平台特有工具已迁移至 agent/tools/;本模块仅注册通用群管工具。
5
- */
6
- import { createSceneManagementTools } from 'zhin.js';
7
- import { setIcqqAgentDeps } from "../icqq-agent-deps.js";
8
- export function registerTools(toolService, icqq, pluginName) {
9
- const disposers = [];
10
- setIcqqAgentDeps({
11
- getEndpoint: (endpointId) => {
12
- const endpoint = icqq.endpoints.get(endpointId);
13
- if (!endpoint)
14
- throw new Error(`Endpoint ${endpointId} 不存在`);
15
- return endpoint;
16
- },
17
- getAdapter: () => icqq,
18
- });
19
- const sceneTools = createSceneManagementTools(icqq, "icqq");
20
- disposers.push(...sceneTools.map((t) => toolService.addTool(t, pluginName)));
21
- return () => disposers.forEach((d) => d());
22
- }
23
- //# sourceMappingURL=index.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/tools/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,OAAO,EAAE,0BAA0B,EAAoB,MAAM,SAAS,CAAC;AAGvE,OAAO,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AAEzD,MAAM,UAAU,aAAa,CAC3B,WAAwB,EACxB,IAAiB,EACjB,UAAkB;IAElB,MAAM,SAAS,GAAmB,EAAE,CAAC;IAErC,gBAAgB,CAAC;QACf,WAAW,EAAE,CAAC,UAAU,EAAE,EAAE;YAC1B,MAAM,QAAQ,GAAG,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC;YAChD,IAAI,CAAC,QAAQ;gBAAE,MAAM,IAAI,KAAK,CAAC,YAAY,UAAU,MAAM,CAAC,CAAC;YAC7D,OAAO,QAAQ,CAAC;QAClB,CAAC;QACD,UAAU,EAAE,GAAG,EAAE,CAAC,IAAI;KACvB,CAAC,CAAC;IAEH,MAAM,UAAU,GAAG,0BAA0B,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;IAC5D,SAAS,CAAC,IAAI,CAAC,GAAG,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,WAAW,CAAC,OAAO,CAAC,CAAC,EAAE,UAAU,CAAC,CAAC,CAAC,CAAC;IAE7E,OAAO,GAAG,EAAE,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC;AAC7C,CAAC"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/types.ts"],"names":[],"mappings":"AAAA;;;;GAIG"}
package/plugin.yml DELETED
@@ -1,3 +0,0 @@
1
- name: adapter-icqq
2
- description: ICQQ 适配器:QQ 群管理、好友操作、群文件、头衔、群公告、戳一戳、点赞、精华、签到、邀请
3
- version: 1.0.71
package/src/adapter.ts DELETED
@@ -1,151 +0,0 @@
1
- /**
2
- * ICQQ 适配器 — 通过 @icqqjs/cli 守护进程 IPC 管理 Endpoint 实例
3
- */
4
- import { formatCompact, Adapter, Plugin, OUTBOUND_RICH_SEGMENT_POLICY_IM_FULL, ONEBOT_KEYBOARD_AI_OUTBOUND_EXTENSION } from 'zhin.js';
5
- import { IcqqEndpoint } from "./endpoint.js";
6
- import type { IcqqEndpointConfig, IpcMemberInfo } from "./types.js";
7
- import { Actions } from "./protocol.js";
8
-
9
- export class IcqqAdapter extends Adapter<IcqqEndpoint> {
10
- static override readonly capabilities = ['inbound', 'outbound'] as const;
11
- static override outboundRichSegmentPolicy = OUTBOUND_RICH_SEGMENT_POLICY_IM_FULL;
12
- static override interactivePolicy = 'text' as const;
13
- static override aiOutboundCapabilities = {
14
- mentions: true,
15
- richSegments: ['qrcode', 'html', 'markdown', 'tts'],
16
- interactive: 'text' as const,
17
- };
18
- static override aiOutboundExtensions = [ONEBOT_KEYBOARD_AI_OUTBOUND_EXTENSION];
19
-
20
- constructor(plugin: Plugin) {
21
- super(plugin, "icqq", []);
22
- }
23
-
24
- getOutboundMediaCapabilities() {
25
- return {
26
- image: true,
27
- audio: true,
28
- video: true,
29
- file: true,
30
- maxAttachmentBytes: 20 * 1024 * 1024,
31
- };
32
- }
33
-
34
- createEndpoint(config: IcqqEndpointConfig): IcqqEndpoint {
35
- return new IcqqEndpoint(this, config);
36
- }
37
-
38
- async start(): Promise<void> {
39
- await super.start();
40
- }
41
-
42
- async stop(): Promise<void> {
43
- await super.stop();
44
- this.logger.debug(formatCompact({ stop: true }));
45
- }
46
-
47
- // ── ISceneManagement 标准群管方法(通过 IPC) ─────────────────────
48
-
49
- private getEndpoint(endpointId: string): IcqqEndpoint {
50
- const endpoint = this.endpoints.get(endpointId);
51
- if (!endpoint) throw new Error(`Endpoint ${endpointId} 不存在`);
52
- return endpoint;
53
- }
54
-
55
- async removeMember(endpointId: string, sceneId: string, userId: string) {
56
- const endpoint = this.getEndpoint(endpointId);
57
- const resp = await endpoint.ipc.request(Actions.GROUP_KICK, {
58
- group_id: Number(sceneId),
59
- user_id: Number(userId),
60
- reject_add_request: false,
61
- });
62
- if (!resp.ok) throw new Error(resp.error ?? "踢人失败");
63
- return true;
64
- }
65
-
66
- async muteMember(
67
- endpointId: string,
68
- sceneId: string,
69
- userId: string,
70
- duration = 600,
71
- ) {
72
- const endpoint = this.getEndpoint(endpointId);
73
- const resp = await endpoint.ipc.request(Actions.GROUP_MUTE, {
74
- group_id: Number(sceneId),
75
- user_id: Number(userId),
76
- duration,
77
- });
78
- if (!resp.ok) throw new Error(resp.error ?? "禁言失败");
79
- return true;
80
- }
81
-
82
- async setSceneMuted(endpointId: string, sceneId: string, enable = true) {
83
- const endpoint = this.getEndpoint(endpointId);
84
- const resp = await endpoint.ipc.request(Actions.GROUP_MUTE_ALL, {
85
- group_id: Number(sceneId),
86
- enable,
87
- });
88
- if (!resp.ok) throw new Error(resp.error ?? "全员禁言失败");
89
- return true;
90
- }
91
-
92
- async setModerator(
93
- endpointId: string,
94
- sceneId: string,
95
- userId: string,
96
- enable = true,
97
- ) {
98
- const endpoint = this.getEndpoint(endpointId);
99
- const resp = await endpoint.ipc.request(Actions.SET_GROUP_ADMIN, {
100
- group_id: Number(sceneId),
101
- user_id: Number(userId),
102
- enable,
103
- });
104
- if (!resp.ok) throw new Error(resp.error ?? "设置管理员失败");
105
- return true;
106
- }
107
-
108
- async setMemberNickname(
109
- endpointId: string,
110
- sceneId: string,
111
- userId: string,
112
- nickname: string,
113
- ) {
114
- const endpoint = this.getEndpoint(endpointId);
115
- const resp = await endpoint.ipc.request(Actions.SET_GROUP_CARD, {
116
- group_id: Number(sceneId),
117
- user_id: Number(userId),
118
- card: nickname,
119
- });
120
- if (!resp.ok) throw new Error(resp.error ?? "设置群名片失败");
121
- return true;
122
- }
123
-
124
- async renameScene(endpointId: string, sceneId: string, name: string) {
125
- const endpoint = this.getEndpoint(endpointId);
126
- const resp = await endpoint.ipc.request(Actions.SET_GROUP_NAME, {
127
- group_id: Number(sceneId),
128
- name,
129
- });
130
- if (!resp.ok) throw new Error(resp.error ?? "设置群名失败");
131
- return true;
132
- }
133
-
134
- async listMembers(endpointId: string, sceneId: string) {
135
- const endpoint = this.getEndpoint(endpointId);
136
- const resp = await endpoint.ipc.request(Actions.LIST_GROUP_MEMBERS, {
137
- group_id: Number(sceneId),
138
- });
139
- if (!resp.ok) throw new Error(resp.error ?? "获取成员列表失败");
140
- const raw = resp.data as IpcMemberInfo[];
141
- const members = raw.map((m) => ({
142
- user_id: m.user_id,
143
- nickname: m.nickname,
144
- card: m.card,
145
- role: m.role,
146
- title: m.title,
147
- }));
148
- return { members, count: members.length };
149
- }
150
-
151
- }
package/src/get-msg.ts DELETED
@@ -1,56 +0,0 @@
1
- import type { QuotedMessagePayload } from "zhin.js";
2
- import { parseCqMessage } from "./cq-message.js";
3
- import { extractForwardResidFromGetMsg } from "./forward-msg.js";
4
- import {
5
- icqqElementsToSegments,
6
- type IcqqMessageElement,
7
- } from "./icqq-inbound.js";
8
-
9
- export function parseIcqqGetMsgResponse(
10
- messageId: string,
11
- data: unknown,
12
- ): QuotedMessagePayload {
13
- const record =
14
- data && typeof data === "object"
15
- ? (data as Record<string, unknown>)
16
- : {};
17
- let content: QuotedMessagePayload["content"] = [];
18
- if (Array.isArray(record.message)) {
19
- content =
20
- icqqElementsToSegments(record.message as IcqqMessageElement[]) ?? [];
21
- } else if (typeof record.raw_message === "string" && record.raw_message) {
22
- content = parseCqMessage(record.raw_message);
23
- } else if (typeof record.message === "string" && record.message) {
24
- content = parseCqMessage(record.message);
25
- }
26
-
27
- const forwardResid = extractForwardResidFromGetMsg(record);
28
- if (forwardResid && Array.isArray(content)) {
29
- const hasForward = content.some((s) => s.type === "forward");
30
- if (!hasForward) {
31
- content = [
32
- { type: "forward", data: { id: forwardResid, resid: forwardResid } },
33
- ...content,
34
- ];
35
- }
36
- }
37
-
38
- const senderRaw = record.sender;
39
- let sender: QuotedMessagePayload["sender"];
40
- if (senderRaw && typeof senderRaw === "object") {
41
- const s = senderRaw as Record<string, unknown>;
42
- sender = {
43
- id: String(s.user_id ?? s.uid ?? s.uin ?? ""),
44
- name: String(s.nickname ?? s.name ?? ""),
45
- };
46
- }
47
-
48
- return {
49
- messageId,
50
- sender,
51
- content,
52
- raw:
53
- typeof record.raw_message === "string" ? record.raw_message : undefined,
54
- time: typeof record.time === "number" ? record.time : undefined,
55
- };
56
- }
@@ -1,196 +0,0 @@
1
- /**
2
- * 将 icqq 守护进程 IPC 的 system.login.* 事件桥接到 core LoginAssist。
3
- *
4
- * 推送契约(@icqqjs/cli IpcEvent):
5
- * { id: "*", event: "system.login.auth", data: { url, device } }
6
- * 须在 endpoint.handleEvent 中按 event.event 先行处理(非 OneBot post_type)。
7
- *
8
- * 续传契约(LoginIpcActions ↔ LoginFlow)见 login-ipc-contract.ts。
9
- */
10
- import type { LoginAssist, LoginAssistType } from '@zhin.js/core';
11
- import type { IcqqEndpoint } from './endpoint.js';
12
- import {
13
- LoginIpcActions,
14
- type IcqqLoginDeviceInfo,
15
- } from './login-ipc-contract.js';
16
-
17
- const activeByEndpoint = new Set<string>();
18
-
19
- function asRecord(value: unknown): Record<string, unknown> | null {
20
- return value && typeof value === 'object' && !Array.isArray(value)
21
- ? (value as Record<string, unknown>)
22
- : null;
23
- }
24
-
25
- function resolveQrcodeImage(data: Record<string, unknown>): string | undefined {
26
- const image = data.image;
27
- if (image && typeof image === 'object') {
28
- const buf = image as { type?: string; data?: string };
29
- if (buf.type === 'Buffer' && typeof buf.data === 'string') {
30
- return `data:image/png;base64,${buf.data}`;
31
- }
32
- }
33
- if (typeof data.url === 'string' && data.url.startsWith('data:image')) {
34
- return data.url;
35
- }
36
- return undefined;
37
- }
38
-
39
- function mapLoginEvent(
40
- eventName: string,
41
- data: Record<string, unknown>,
42
- ): { type: LoginAssistType; payload: Record<string, unknown> } | null {
43
- switch (eventName) {
44
- case 'system.login.qrcode':
45
- return {
46
- type: 'qrcode',
47
- payload: {
48
- message: '请使用手机 QQ 扫码登录',
49
- image: resolveQrcodeImage(data),
50
- },
51
- };
52
- case 'system.login.slider':
53
- return {
54
- type: 'slider',
55
- payload: {
56
- message: '请完成滑块验证并提交 ticket',
57
- url: String(data.url ?? ''),
58
- },
59
- };
60
- case 'system.login.device':
61
- return {
62
- type: 'device',
63
- payload: {
64
- message: data.phone
65
- ? `请完成设备锁验证(密保手机 ${String(data.phone)})`
66
- : '请完成设备锁验证',
67
- url: String(data.url ?? ''),
68
- phone: data.phone,
69
- },
70
- };
71
- case 'system.login.auth':
72
- return {
73
- type: 'auth',
74
- payload: {
75
- message: '请在浏览器完成身份验证(需使用下方设备信息)',
76
- url: String(data.url ?? ''),
77
- device: data.device as IcqqLoginDeviceInfo | undefined,
78
- },
79
- };
80
- }
81
- return null;
82
- }
83
-
84
- /** 对齐 @icqqjs/cli LoginFlow.handleSubmit → Client 方法 */
85
- async function continueLoginAfterAssist(
86
- endpoint: IcqqEndpoint,
87
- loginType: LoginAssistType,
88
- value: string | Record<string, unknown>,
89
- ): Promise<void> {
90
- if (!endpoint.ipc || endpoint.ipc.closed) return;
91
-
92
- try {
93
- if (loginType === 'slider') {
94
- const ticket =
95
- typeof value === 'string'
96
- ? value.trim()
97
- : typeof value === 'object' && value !== null
98
- ? String((value as { ticket?: string }).ticket ?? '').trim()
99
- : '';
100
- if (!ticket) return;
101
- await endpoint.ipc.request(LoginIpcActions.SUBMIT_SLIDER, { ticket });
102
- return;
103
- }
104
-
105
- if (loginType === 'sms') {
106
- const code = typeof value === 'string' ? value.trim() : '';
107
- if (!code) return;
108
- await endpoint.ipc.request(LoginIpcActions.SUBMIT_SMS_CODE, { code });
109
- return;
110
- }
111
-
112
- if (loginType === 'device') {
113
- if (
114
- typeof value === 'object' &&
115
- value !== null &&
116
- (value as { action?: string }).action === 'sms'
117
- ) {
118
- await endpoint.ipc.request(LoginIpcActions.SEND_SMS_CODE, {});
119
- return;
120
- }
121
- if (typeof value === 'string' && value.trim()) {
122
- await endpoint.ipc.request(LoginIpcActions.SUBMIT_SMS_CODE, {
123
- code: value.trim(),
124
- });
125
- return;
126
- }
127
- }
128
-
129
- // qrcode / device 链接确认 / auth 237 确认 → client.login()
130
- await endpoint.ipc.request(LoginIpcActions.LOGIN, {});
131
- } catch (err) {
132
- endpoint.logger.warn(
133
- `登录辅助提交后 IPC 续传失败:${
134
- err instanceof Error ? err.message : String(err)
135
- }(action 须与 @icqqjs/cli action-catalog 一致)`,
136
- );
137
- }
138
- }
139
-
140
- export function handleIcqqLoginIpcEvent(
141
- endpoint: IcqqEndpoint,
142
- eventName: string,
143
- rawData: unknown,
144
- ): void {
145
- if (!eventName.startsWith('system.login.')) return;
146
-
147
- const root = endpoint.adapter.plugin.root;
148
- const loginAssist = root.inject('loginAssist') as LoginAssist | undefined;
149
- if (!loginAssist) {
150
- endpoint.logger.debug(`收到 ${eventName},但 loginAssist 未启用`);
151
- return;
152
- }
153
-
154
- if (eventName === 'system.login.error') {
155
- const data = asRecord(rawData);
156
- endpoint.logger.warn(
157
- `icqq 登录错误:${String(data?.message ?? 'unknown')}${
158
- data?.code != null ? ` [code=${String(data.code)}]` : ''
159
- }`,
160
- );
161
- return;
162
- }
163
-
164
- const data = asRecord(rawData);
165
- if (!data) return;
166
-
167
- const mapped = mapLoginEvent(eventName, data);
168
- if (!mapped) return;
169
-
170
- const guardKey = endpoint.$id;
171
- if (activeByEndpoint.has(guardKey)) {
172
- endpoint.logger.debug(`跳过重复登录待办:${eventName}`);
173
- return;
174
- }
175
- activeByEndpoint.add(guardKey);
176
-
177
- endpoint.logger.info(`icqq 登录待办:${mapped.type}(${eventName})`);
178
-
179
- void loginAssist
180
- .waitForInput('icqq', endpoint.$id, mapped.type, mapped.payload)
181
- .then((value) => continueLoginAfterAssist(endpoint, mapped.type, value))
182
- .catch((err) => {
183
- if (err instanceof Error && err.message !== 'cancelled') {
184
- endpoint.logger.warn(`登录辅助已取消或失败:${err.message}`);
185
- }
186
- })
187
- .finally(() => {
188
- activeByEndpoint.delete(guardKey);
189
- });
190
- }
191
-
192
- export function disposeIcqqLoginAssistBridge(endpointId: string): void {
193
- activeByEndpoint.delete(endpointId);
194
- }
195
-
196
- export type { IcqqLoginDeviceInfo } from './login-ipc-contract.js';