@tencent-connect/openclaw-qqbot 1.6.5-alpha.0 → 1.6.5-alpha.1
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.
- package/dist/src/admin-resolver.js +9 -11
- package/openclaw.plugin.json +1 -0
- package/package.json +5 -20
- package/scripts/postinstall-link-sdk.js +66 -0
- package/src/admin-resolver.ts +10 -11
- package/clawdbot.plugin.json +0 -16
- package/moltbot.plugin.json +0 -16
|
@@ -129,26 +129,24 @@ export function sendStartupGreetings(ctx, trigger) {
|
|
|
129
129
|
return;
|
|
130
130
|
}
|
|
131
131
|
const upgradeTargetOpenId = loadUpgradeGreetingTargetOpenId(ctx.accountId, ctx.appId, ctx.log);
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
132
|
+
// 没有 upgrade-greeting-target 文件 → 不是通过 /bot-upgrade 触发的升级
|
|
133
|
+
// (console 手动重启、脚本升级等场景),静默更新 marker 不发消息
|
|
134
|
+
if (!upgradeTargetOpenId) {
|
|
135
|
+
markStartupGreetingSent(ctx.accountId, ctx.appId, plan.version);
|
|
136
|
+
ctx.log?.info(`[qqbot:${ctx.accountId}] Version changed but no upgrade-greeting-target, silently updating marker (trigger=${trigger})`);
|
|
136
137
|
return;
|
|
137
138
|
}
|
|
138
139
|
try {
|
|
139
|
-
|
|
140
|
-
ctx.log?.info(`[qqbot:${ctx.accountId}] Sending startup greeting to ${receiverType} (trigger=${trigger}): "${plan.greeting}"`);
|
|
140
|
+
ctx.log?.info(`[qqbot:${ctx.accountId}] Sending startup greeting to upgrade-requester (trigger=${trigger}): "${plan.greeting}"`);
|
|
141
141
|
const token = await getAccessToken(ctx.appId, ctx.clientSecret);
|
|
142
142
|
const GREETING_TIMEOUT_MS = 10_000;
|
|
143
143
|
await Promise.race([
|
|
144
|
-
sendProactiveC2CMessage(token,
|
|
144
|
+
sendProactiveC2CMessage(token, upgradeTargetOpenId, plan.greeting),
|
|
145
145
|
new Promise((_, reject) => setTimeout(() => reject(new Error("Startup greeting send timeout (10s)")), GREETING_TIMEOUT_MS)),
|
|
146
146
|
]);
|
|
147
147
|
markStartupGreetingSent(ctx.accountId, ctx.appId, plan.version);
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
}
|
|
151
|
-
ctx.log?.info(`[qqbot:${ctx.accountId}] Sent startup greeting to ${receiverType}: ${targetOpenId}`);
|
|
148
|
+
clearUpgradeGreetingTargetOpenId(ctx.accountId, ctx.appId);
|
|
149
|
+
ctx.log?.info(`[qqbot:${ctx.accountId}] Sent startup greeting to upgrade-requester: ${upgradeTargetOpenId}`);
|
|
152
150
|
}
|
|
153
151
|
catch (err) {
|
|
154
152
|
const message = err instanceof Error ? err.message : String(err);
|
package/openclaw.plugin.json
CHANGED
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
"name": "OpenClaw QQ Bot",
|
|
4
4
|
"description": "QQ Bot channel plugin with message support, cron jobs, and proactive messaging",
|
|
5
5
|
"channels": ["qqbot"],
|
|
6
|
+
"extensions": ["./dist/index.js"],
|
|
6
7
|
"skills": ["skills/qqbot-channel", "skills/qqbot-remind", "skills/qqbot-media"],
|
|
7
8
|
"capabilities": {
|
|
8
9
|
"proactiveMessaging": true,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@tencent-connect/openclaw-qqbot",
|
|
3
|
-
"version": "1.6.5-alpha.
|
|
3
|
+
"version": "1.6.5-alpha.1",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"types": "dist/index.d.ts",
|
|
@@ -16,32 +16,19 @@
|
|
|
16
16
|
"scripts",
|
|
17
17
|
"index.ts",
|
|
18
18
|
"tsconfig.json",
|
|
19
|
-
"openclaw.plugin.json"
|
|
20
|
-
"clawdbot.plugin.json",
|
|
21
|
-
"moltbot.plugin.json"
|
|
19
|
+
"openclaw.plugin.json"
|
|
22
20
|
],
|
|
23
|
-
"clawdbot": {
|
|
24
|
-
"id": "openclaw-qqbot",
|
|
25
|
-
"extensions": [
|
|
26
|
-
"./index.ts"
|
|
27
|
-
]
|
|
28
|
-
},
|
|
29
|
-
"moltbot": {
|
|
30
|
-
"id": "openclaw-qqbot",
|
|
31
|
-
"extensions": [
|
|
32
|
-
"./index.ts"
|
|
33
|
-
]
|
|
34
|
-
},
|
|
35
21
|
"openclaw": {
|
|
36
22
|
"id": "openclaw-qqbot",
|
|
37
23
|
"extensions": [
|
|
38
|
-
"./index.
|
|
24
|
+
"./dist/index.js"
|
|
39
25
|
]
|
|
40
26
|
},
|
|
41
27
|
"scripts": {
|
|
42
28
|
"build": "tsc || true",
|
|
43
29
|
"dev": "tsc --watch",
|
|
44
|
-
"prepack": "npm install --omit=dev"
|
|
30
|
+
"prepack": "npm install --omit=dev",
|
|
31
|
+
"postinstall": "node scripts/postinstall-link-sdk.js 2>/dev/null || true"
|
|
45
32
|
},
|
|
46
33
|
"dependencies": {
|
|
47
34
|
"mpg123-decoder": "^1.0.3",
|
|
@@ -59,8 +46,6 @@
|
|
|
59
46
|
"typescript": "^5.9.3"
|
|
60
47
|
},
|
|
61
48
|
"peerDependencies": {
|
|
62
|
-
"clawdbot": "*",
|
|
63
|
-
"moltbot": "*",
|
|
64
49
|
"openclaw": "*"
|
|
65
50
|
},
|
|
66
51
|
"homepage": "https://github.com/tencent-connect/openclaw-qqbot",
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
// When installed as an openclaw extension under ~/.openclaw/extensions/,
|
|
4
|
+
// the plugin needs access to `openclaw/plugin-sdk` at runtime.
|
|
5
|
+
// openclaw's jiti loader resolves this via alias by walking up from the plugin
|
|
6
|
+
// path to find the openclaw package root — but ~/.openclaw/extensions/ is not
|
|
7
|
+
// under the openclaw package tree, so the alias lookup fails.
|
|
8
|
+
//
|
|
9
|
+
// This script creates a symlink from the plugin's node_modules/openclaw to the
|
|
10
|
+
// globally installed openclaw package, allowing Node's native ESM resolver
|
|
11
|
+
// (used by jiti with tryNative:true for .js files) to find `openclaw/plugin-sdk`.
|
|
12
|
+
|
|
13
|
+
import { existsSync, symlinkSync, mkdirSync, readlinkSync } from "node:fs";
|
|
14
|
+
import { dirname, join, resolve } from "node:path";
|
|
15
|
+
import { fileURLToPath } from "node:url";
|
|
16
|
+
import { execSync } from "node:child_process";
|
|
17
|
+
|
|
18
|
+
const __dirname = dirname(fileURLToPath(import.meta.url));
|
|
19
|
+
const pluginRoot = resolve(__dirname, "..");
|
|
20
|
+
|
|
21
|
+
// Only run when installed under .openclaw/extensions/
|
|
22
|
+
if (!pluginRoot.includes(".openclaw") && !pluginRoot.includes("extensions")) {
|
|
23
|
+
process.exit(0);
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
const linkTarget = join(pluginRoot, "node_modules", "openclaw");
|
|
27
|
+
|
|
28
|
+
// Already linked or exists
|
|
29
|
+
if (existsSync(linkTarget)) {
|
|
30
|
+
process.exit(0);
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
// Find the global openclaw installation
|
|
34
|
+
let openclawRoot = null;
|
|
35
|
+
try {
|
|
36
|
+
// Try require.resolve from global context
|
|
37
|
+
const globalRoot = execSync("npm root -g", { encoding: "utf-8" }).trim();
|
|
38
|
+
const candidate = join(globalRoot, "openclaw");
|
|
39
|
+
if (existsSync(join(candidate, "package.json"))) {
|
|
40
|
+
openclawRoot = candidate;
|
|
41
|
+
}
|
|
42
|
+
} catch {}
|
|
43
|
+
|
|
44
|
+
if (!openclawRoot) {
|
|
45
|
+
try {
|
|
46
|
+
// Try resolving from the openclaw CLI binary
|
|
47
|
+
const bin = execSync("which openclaw", { encoding: "utf-8" }).trim();
|
|
48
|
+
// bin is typically <prefix>/bin/openclaw -> ../lib/node_modules/openclaw/...
|
|
49
|
+
const candidate = resolve(dirname(bin), "..", "lib", "node_modules", "openclaw");
|
|
50
|
+
if (existsSync(join(candidate, "package.json"))) {
|
|
51
|
+
openclawRoot = candidate;
|
|
52
|
+
}
|
|
53
|
+
} catch {}
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
if (!openclawRoot) {
|
|
57
|
+
// Not fatal — plugin may work if openclaw loads it with proper alias resolution
|
|
58
|
+
process.exit(0);
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
try {
|
|
62
|
+
mkdirSync(join(pluginRoot, "node_modules"), { recursive: true });
|
|
63
|
+
symlinkSync(openclawRoot, linkTarget, "junction");
|
|
64
|
+
} catch {
|
|
65
|
+
// Silently ignore — symlink creation may fail on some systems
|
|
66
|
+
}
|
package/src/admin-resolver.ts
CHANGED
|
@@ -152,27 +152,26 @@ export function sendStartupGreetings(ctx: AdminResolverContext, trigger: "READY"
|
|
|
152
152
|
}
|
|
153
153
|
|
|
154
154
|
const upgradeTargetOpenId = loadUpgradeGreetingTargetOpenId(ctx.accountId, ctx.appId, ctx.log);
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
155
|
+
|
|
156
|
+
// 没有 upgrade-greeting-target 文件 → 不是通过 /bot-upgrade 触发的升级
|
|
157
|
+
// (console 手动重启、脚本升级等场景),静默更新 marker 不发消息
|
|
158
|
+
if (!upgradeTargetOpenId) {
|
|
159
|
+
markStartupGreetingSent(ctx.accountId, ctx.appId, plan.version);
|
|
160
|
+
ctx.log?.info(`[qqbot:${ctx.accountId}] Version changed but no upgrade-greeting-target, silently updating marker (trigger=${trigger})`);
|
|
159
161
|
return;
|
|
160
162
|
}
|
|
161
163
|
|
|
162
164
|
try {
|
|
163
|
-
|
|
164
|
-
ctx.log?.info(`[qqbot:${ctx.accountId}] Sending startup greeting to ${receiverType} (trigger=${trigger}): "${plan.greeting}"`);
|
|
165
|
+
ctx.log?.info(`[qqbot:${ctx.accountId}] Sending startup greeting to upgrade-requester (trigger=${trigger}): "${plan.greeting}"`);
|
|
165
166
|
const token = await getAccessToken(ctx.appId, ctx.clientSecret);
|
|
166
167
|
const GREETING_TIMEOUT_MS = 10_000;
|
|
167
168
|
await Promise.race([
|
|
168
|
-
sendProactiveC2CMessage(token,
|
|
169
|
+
sendProactiveC2CMessage(token, upgradeTargetOpenId, plan.greeting),
|
|
169
170
|
new Promise((_, reject) => setTimeout(() => reject(new Error("Startup greeting send timeout (10s)")), GREETING_TIMEOUT_MS)),
|
|
170
171
|
]);
|
|
171
172
|
markStartupGreetingSent(ctx.accountId, ctx.appId, plan.version);
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
}
|
|
175
|
-
ctx.log?.info(`[qqbot:${ctx.accountId}] Sent startup greeting to ${receiverType}: ${targetOpenId}`);
|
|
173
|
+
clearUpgradeGreetingTargetOpenId(ctx.accountId, ctx.appId);
|
|
174
|
+
ctx.log?.info(`[qqbot:${ctx.accountId}] Sent startup greeting to upgrade-requester: ${upgradeTargetOpenId}`);
|
|
176
175
|
} catch (err) {
|
|
177
176
|
const message = err instanceof Error ? err.message : String(err);
|
|
178
177
|
markStartupGreetingFailed(ctx.accountId, ctx.appId, plan.version, message);
|
package/clawdbot.plugin.json
DELETED
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"id": "openclaw-qqbot",
|
|
3
|
-
"name": "OpenClaw QQ Bot",
|
|
4
|
-
"description": "QQ Bot channel plugin with message support, cron jobs, and proactive messaging",
|
|
5
|
-
"channels": ["qqbot"],
|
|
6
|
-
"skills": ["skills/qqbot-channel", "skills/qqbot-remind", "skills/qqbot-media"],
|
|
7
|
-
"capabilities": {
|
|
8
|
-
"proactiveMessaging": true,
|
|
9
|
-
"cronJobs": true
|
|
10
|
-
},
|
|
11
|
-
"configSchema": {
|
|
12
|
-
"type": "object",
|
|
13
|
-
"additionalProperties": false,
|
|
14
|
-
"properties": {}
|
|
15
|
-
}
|
|
16
|
-
}
|
package/moltbot.plugin.json
DELETED
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"id": "openclaw-qqbot",
|
|
3
|
-
"name": "OpenClaw QQ Bot",
|
|
4
|
-
"description": "QQ Bot channel plugin with message support, cron jobs, and proactive messaging",
|
|
5
|
-
"channels": ["qqbot"],
|
|
6
|
-
"skills": ["skills/qqbot-channel", "skills/qqbot-remind", "skills/qqbot-media"],
|
|
7
|
-
"capabilities": {
|
|
8
|
-
"proactiveMessaging": true,
|
|
9
|
-
"cronJobs": true
|
|
10
|
-
},
|
|
11
|
-
"configSchema": {
|
|
12
|
-
"type": "object",
|
|
13
|
-
"additionalProperties": false,
|
|
14
|
-
"properties": {}
|
|
15
|
-
}
|
|
16
|
-
}
|