@zzedbot/yunzhijia 1.0.11 → 1.0.13
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.
Potentially problematic release.
This version of @zzedbot/yunzhijia might be problematic. Click here for more details.
- package/package.json +4 -5
- package/src/config.ts +40 -20
- package/dist/channel.d.ts +0 -45
- package/dist/channel.js +0 -228
- package/dist/config.d.ts +0 -3
- package/dist/config.js +0 -27
- package/dist/http.d.ts +0 -6
- package/dist/http.js +0 -214
- package/dist/index.d.ts +0 -1
- package/dist/index.js +0 -5
- package/dist/plugin-fixed.d.ts +0 -3
- package/dist/plugin-fixed.js +0 -106
- package/dist/plugin-simple.d.ts +0 -2
- package/dist/plugin-simple.js +0 -104
- package/dist/plugin.d.ts +0 -2
- package/dist/plugin.js +0 -272
- package/dist/receiver.d.ts +0 -17
- package/dist/receiver.js +0 -110
- package/dist/runtime.d.ts +0 -3
- package/dist/runtime.js +0 -16
- package/dist/test.d.ts +0 -4
- package/dist/test.js +0 -76
- package/dist/types.d.ts +0 -53
- package/dist/types.js +0 -2
- package/dist/utils.d.ts +0 -34
- package/dist/utils.js +0 -108
- package/dist/webhook.d.ts +0 -9
- package/dist/webhook.js +0 -42
package/dist/test.js
DELETED
|
@@ -1,76 +0,0 @@
|
|
|
1
|
-
import { YunzhijiaChannel } from './channel';
|
|
2
|
-
// 测试签名验证功能
|
|
3
|
-
function testSignature() {
|
|
4
|
-
console.log('Testing signature verification...');
|
|
5
|
-
// 这里我们使用测试参数来验证签名逻辑
|
|
6
|
-
const testSecret = 'test-secret';
|
|
7
|
-
const testMessage = {
|
|
8
|
-
robotId: 'test-robotId',
|
|
9
|
-
robotName: 'test-robotName',
|
|
10
|
-
operatorOpenid: 'test-userId',
|
|
11
|
-
operatorName: 'test-userName',
|
|
12
|
-
time: Date.now(),
|
|
13
|
-
msgId: 'test-msgId',
|
|
14
|
-
content: '你好,你能做什么呢?'
|
|
15
|
-
};
|
|
16
|
-
// 构建摘要信息
|
|
17
|
-
const summaryInfo = [
|
|
18
|
-
testMessage.robotId,
|
|
19
|
-
testMessage.robotName,
|
|
20
|
-
testMessage.operatorOpenid,
|
|
21
|
-
testMessage.operatorName,
|
|
22
|
-
testMessage.time.toString(),
|
|
23
|
-
testMessage.msgId,
|
|
24
|
-
testMessage.content
|
|
25
|
-
].join(',');
|
|
26
|
-
// 使用HmacSHA1算法计算签名
|
|
27
|
-
const crypto = require('crypto');
|
|
28
|
-
const hmac = crypto.createHmac('sha1', testSecret);
|
|
29
|
-
hmac.update(summaryInfo);
|
|
30
|
-
const expectedSignature = hmac.digest('base64');
|
|
31
|
-
console.log('Expected signature for test:', expectedSignature);
|
|
32
|
-
console.log('Test message summary info:', summaryInfo);
|
|
33
|
-
}
|
|
34
|
-
// 创建一个简单的测试实例
|
|
35
|
-
async function testChannel() {
|
|
36
|
-
console.log('Testing Yunzhijia Channel...');
|
|
37
|
-
const config = {
|
|
38
|
-
appSecret: '698766b5e4b0674aec38f798',
|
|
39
|
-
webhookUrl: 'https://www.yunzhijia.com/gateway/robot/webhook/send?yzjtype=12&yzjtoken=eb2ce932214c48b2a604cc7d4d6034b2',
|
|
40
|
-
receiveEndpoint: '/receive'
|
|
41
|
-
};
|
|
42
|
-
const channel = new YunzhijiaChannel(config);
|
|
43
|
-
// 不启动服务器,只测试类的功能
|
|
44
|
-
console.log('Yunzhijia Channel created successfully!');
|
|
45
|
-
// 测试消息处理
|
|
46
|
-
const mockMessage = {
|
|
47
|
-
type: 2,
|
|
48
|
-
robotId: 'test-robot-id',
|
|
49
|
-
robotName: 'Test Robot',
|
|
50
|
-
operatorOpenid: 'test-user-openid',
|
|
51
|
-
operatorName: 'Test User',
|
|
52
|
-
time: Date.now(),
|
|
53
|
-
msgId: 'test-message-id',
|
|
54
|
-
content: 'Hello, this is a test message!'
|
|
55
|
-
};
|
|
56
|
-
console.log('Mock message processed.');
|
|
57
|
-
// 测试会话管理
|
|
58
|
-
await channel['updateSession']('test-session-id', mockMessage);
|
|
59
|
-
console.log('Session updated.');
|
|
60
|
-
// 测试OpenClaw处理模拟
|
|
61
|
-
const response = await channel['simulateOpenClawProcessing']('Hello, how are you?');
|
|
62
|
-
console.log('OpenClaw simulation response:', response);
|
|
63
|
-
}
|
|
64
|
-
// 运行测试
|
|
65
|
-
async function runTests() {
|
|
66
|
-
console.log('Running Yunzhijia Channel tests...\n');
|
|
67
|
-
testSignature();
|
|
68
|
-
console.log('');
|
|
69
|
-
await testChannel();
|
|
70
|
-
console.log('\nAll tests completed!');
|
|
71
|
-
}
|
|
72
|
-
// 如果直接运行此文件,则执行测试
|
|
73
|
-
if (typeof require !== 'undefined' && require.main === module) {
|
|
74
|
-
runTests().catch(console.error);
|
|
75
|
-
}
|
|
76
|
-
export { testSignature, testChannel, runTests };
|
package/dist/types.d.ts
DELETED
|
@@ -1,53 +0,0 @@
|
|
|
1
|
-
import type { ChannelId } from "openclaw/plugin-sdk";
|
|
2
|
-
export type YunzhiJiaChannelId = ChannelId<"yunzhijia">;
|
|
3
|
-
export interface YunzhiJiaAccountConfig {
|
|
4
|
-
/** Webhook token for sending messages */
|
|
5
|
-
webhookToken?: string;
|
|
6
|
-
/** App secret for signature verification */
|
|
7
|
-
appSecret?: string;
|
|
8
|
-
/** Account name (optional) */
|
|
9
|
-
name?: string;
|
|
10
|
-
/** Whether this account is enabled */
|
|
11
|
-
enabled?: boolean;
|
|
12
|
-
/** Whether to require @mention to trigger the bot */
|
|
13
|
-
requireMention?: boolean;
|
|
14
|
-
/** Allowlist for direct messages */
|
|
15
|
-
allowFrom?: Array<string | number>;
|
|
16
|
-
/** Group policy configuration */
|
|
17
|
-
groups?: Record<string, {
|
|
18
|
-
requireMention?: boolean;
|
|
19
|
-
}>;
|
|
20
|
-
/** Whether to skip signature verification (for testing/development) */
|
|
21
|
-
skipSignatureVerification?: boolean;
|
|
22
|
-
}
|
|
23
|
-
export interface YunzhiJiaConfig {
|
|
24
|
-
/** Default account configuration */
|
|
25
|
-
webhookToken?: string;
|
|
26
|
-
appSecret?: string;
|
|
27
|
-
enabled?: boolean;
|
|
28
|
-
name?: string;
|
|
29
|
-
requireMention?: boolean;
|
|
30
|
-
allowFrom?: Array<string | number>;
|
|
31
|
-
groups?: Record<string, {
|
|
32
|
-
requireMention?: boolean;
|
|
33
|
-
}>;
|
|
34
|
-
/** Multiple account support */
|
|
35
|
-
accounts?: Record<string, YunzhiJiaAccountConfig>;
|
|
36
|
-
}
|
|
37
|
-
export interface ResolvedYunzhiJiaAccount {
|
|
38
|
-
accountId: string;
|
|
39
|
-
config: YunzhiJiaAccountConfig;
|
|
40
|
-
name: string;
|
|
41
|
-
enabled: boolean;
|
|
42
|
-
configured: boolean;
|
|
43
|
-
}
|
|
44
|
-
export interface YunzhiJiaIncomingMessage {
|
|
45
|
-
type: number;
|
|
46
|
-
robotId: string;
|
|
47
|
-
robotName: string;
|
|
48
|
-
operatorOpenid: string;
|
|
49
|
-
operatorName: string;
|
|
50
|
-
time: number;
|
|
51
|
-
msgId: string;
|
|
52
|
-
content: string;
|
|
53
|
-
}
|
package/dist/types.js
DELETED
package/dist/utils.d.ts
DELETED
|
@@ -1,34 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Verify YunzhiJia webhook signature using HmacSHA1 + Base64 (as per YunzhiJia documentation)
|
|
3
|
-
* Note: YunzhiJia documentation shows HmacSHA1 + Base64, but some implementations may use SHA256 + hex
|
|
4
|
-
* We'll implement both and allow configuration to choose
|
|
5
|
-
*/
|
|
6
|
-
export declare function verifySignature(body: string, signature: string, appSecret: string, skipSignatureVerification?: boolean): boolean;
|
|
7
|
-
/**
|
|
8
|
-
* Format message for YunzhiJia webhook
|
|
9
|
-
*/
|
|
10
|
-
export declare function formatYunzhiJiaMessage(content: string): Record<string, unknown>;
|
|
11
|
-
/**
|
|
12
|
-
* Extract user info from YunzhiJia webhook payload
|
|
13
|
-
*/
|
|
14
|
-
export declare function extractUserInfo(payload: Record<string, unknown>): {
|
|
15
|
-
userId: string;
|
|
16
|
-
userName: string;
|
|
17
|
-
messageId: string;
|
|
18
|
-
content: string;
|
|
19
|
-
robotId: string;
|
|
20
|
-
robotName: string;
|
|
21
|
-
time: number;
|
|
22
|
-
};
|
|
23
|
-
/**
|
|
24
|
-
* Check if bot is mentioned in the message content
|
|
25
|
-
*/
|
|
26
|
-
export declare function isBotMentioned(content: string, robotName: string): boolean;
|
|
27
|
-
/**
|
|
28
|
-
* Extract clean content by removing bot mention
|
|
29
|
-
*/
|
|
30
|
-
export declare function extractCleanContent(content: string, robotName: string): string;
|
|
31
|
-
/**
|
|
32
|
-
* Create session key from sessionId and robotId
|
|
33
|
-
*/
|
|
34
|
-
export declare function createSessionKey(sessionId: string, robotId: string): string;
|
package/dist/utils.js
DELETED
|
@@ -1,108 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.verifySignature = verifySignature;
|
|
4
|
-
exports.formatYunzhiJiaMessage = formatYunzhiJiaMessage;
|
|
5
|
-
exports.extractUserInfo = extractUserInfo;
|
|
6
|
-
exports.isBotMentioned = isBotMentioned;
|
|
7
|
-
exports.extractCleanContent = extractCleanContent;
|
|
8
|
-
exports.createSessionKey = createSessionKey;
|
|
9
|
-
const node_crypto_1 = require("node:crypto");
|
|
10
|
-
/**
|
|
11
|
-
* Verify YunzhiJia webhook signature using HmacSHA1 + Base64 (as per YunzhiJia documentation)
|
|
12
|
-
* Note: YunzhiJia documentation shows HmacSHA1 + Base64, but some implementations may use SHA256 + hex
|
|
13
|
-
* We'll implement both and allow configuration to choose
|
|
14
|
-
*/
|
|
15
|
-
function verifySignature(body, signature, appSecret, skipSignatureVerification) {
|
|
16
|
-
// Explicitly skip signature verification if configured
|
|
17
|
-
if (skipSignatureVerification) {
|
|
18
|
-
return true;
|
|
19
|
-
}
|
|
20
|
-
// If no app secret configured, skip verification (for testing)
|
|
21
|
-
if (!appSecret) {
|
|
22
|
-
return true;
|
|
23
|
-
}
|
|
24
|
-
// Parse the JSON body to extract fields for signature calculation
|
|
25
|
-
try {
|
|
26
|
-
const payload = JSON.parse(body);
|
|
27
|
-
const summaryInfo = [
|
|
28
|
-
payload.robotId,
|
|
29
|
-
payload.robotName,
|
|
30
|
-
payload.operatorOpenid,
|
|
31
|
-
payload.operatorName,
|
|
32
|
-
payload.time?.toString(),
|
|
33
|
-
payload.msgId,
|
|
34
|
-
payload.content
|
|
35
|
-
].join(",");
|
|
36
|
-
// Try HmacSHA1 + Base64 first (as per YunzhiJia documentation)
|
|
37
|
-
const hmacSha1 = createHmac('sha1', appSecret);
|
|
38
|
-
hmacSha1.update(summaryInfo);
|
|
39
|
-
const expectedSignatureBase64 = hmacSha1.digest('base64');
|
|
40
|
-
if (signature === expectedSignatureBase64) {
|
|
41
|
-
return true;
|
|
42
|
-
}
|
|
43
|
-
// Fallback to SHA256 + hex (current implementation)
|
|
44
|
-
const expectedSignatureSha256 = (0, node_crypto_1.createHash)("sha256")
|
|
45
|
-
.update(body + appSecret)
|
|
46
|
-
.digest("hex");
|
|
47
|
-
return signature === expectedSignatureSha256;
|
|
48
|
-
}
|
|
49
|
-
catch (error) {
|
|
50
|
-
console.error("Error parsing payload for signature verification:", error);
|
|
51
|
-
return false;
|
|
52
|
-
}
|
|
53
|
-
}
|
|
54
|
-
/**
|
|
55
|
-
* Create HMAC hash (Node.js compatible)
|
|
56
|
-
*/
|
|
57
|
-
function createHmac(algorithm, key) {
|
|
58
|
-
const crypto = require('node:crypto');
|
|
59
|
-
return crypto.createHmac(algorithm, key);
|
|
60
|
-
}
|
|
61
|
-
/**
|
|
62
|
-
* Format message for YunzhiJia webhook
|
|
63
|
-
*/
|
|
64
|
-
function formatYunzhiJiaMessage(content) {
|
|
65
|
-
return {
|
|
66
|
-
content: content,
|
|
67
|
-
};
|
|
68
|
-
}
|
|
69
|
-
/**
|
|
70
|
-
* Extract user info from YunzhiJia webhook payload
|
|
71
|
-
*/
|
|
72
|
-
function extractUserInfo(payload) {
|
|
73
|
-
return {
|
|
74
|
-
userId: String(payload.operatorOpenid ?? "unknown"),
|
|
75
|
-
userName: String(payload.operatorName ?? "Unknown User"),
|
|
76
|
-
messageId: String(payload.msgId ?? Date.now().toString()),
|
|
77
|
-
content: String(payload.content ?? ""),
|
|
78
|
-
robotId: String(payload.robotId ?? "unknown"),
|
|
79
|
-
robotName: String(payload.robotName ?? "YunzhiJia Bot"),
|
|
80
|
-
time: Number(payload.time ?? Date.now()),
|
|
81
|
-
};
|
|
82
|
-
}
|
|
83
|
-
/**
|
|
84
|
-
* Check if bot is mentioned in the message content
|
|
85
|
-
*/
|
|
86
|
-
function isBotMentioned(content, robotName) {
|
|
87
|
-
// YunzhiJia mentions are typically in the format "@BotName"
|
|
88
|
-
const mentionPattern = new RegExp(`@${robotName.replace(/[.*+?^${}()|[\]\\]/g, '\\$&')}`, 'i');
|
|
89
|
-
return mentionPattern.test(content) || content.includes('@ALL') || content.includes('@all');
|
|
90
|
-
}
|
|
91
|
-
/**
|
|
92
|
-
* Extract clean content by removing bot mention
|
|
93
|
-
*/
|
|
94
|
-
function extractCleanContent(content, robotName) {
|
|
95
|
-
// Remove bot mention patterns
|
|
96
|
-
const cleaned = content
|
|
97
|
-
.replace(new RegExp(`@${robotName.replace(/[.*+?^${}()|[\]\\]/g, '\\$&')}`, 'gi'), '')
|
|
98
|
-
.replace(/@ALL/gi, '')
|
|
99
|
-
.replace(/@all/gi, '')
|
|
100
|
-
.trim();
|
|
101
|
-
return cleaned || content; // Return original if nothing was cleaned
|
|
102
|
-
}
|
|
103
|
-
/**
|
|
104
|
-
* Create session key from sessionId and robotId
|
|
105
|
-
*/
|
|
106
|
-
function createSessionKey(sessionId, robotId) {
|
|
107
|
-
return `yunzhijia:${robotId}:${sessionId}`;
|
|
108
|
-
}
|
package/dist/webhook.d.ts
DELETED
|
@@ -1,9 +0,0 @@
|
|
|
1
|
-
import type { YunzhiJiaAccountConfig } from "./types.js";
|
|
2
|
-
/**
|
|
3
|
-
* Send message to YunzhiJia webhook
|
|
4
|
-
*/
|
|
5
|
-
export declare function sendToYunzhiJiaWebhook(content: string, accountConfig: YunzhiJiaAccountConfig): Promise<void>;
|
|
6
|
-
/**
|
|
7
|
-
* Send media to YunzhiJia (placeholder - YunzhiJia may not support media directly)
|
|
8
|
-
*/
|
|
9
|
-
export declare function sendMediaToYunzhiJia(content: string, mediaUrl: string, accountConfig: YunzhiJiaAccountConfig): Promise<void>;
|
package/dist/webhook.js
DELETED
|
@@ -1,42 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.sendToYunzhiJiaWebhook = sendToYunzhiJiaWebhook;
|
|
4
|
-
exports.sendMediaToYunzhiJia = sendMediaToYunzhiJia;
|
|
5
|
-
/**
|
|
6
|
-
* Send message to YunzhiJia webhook
|
|
7
|
-
*/
|
|
8
|
-
async function sendToYunzhiJiaWebhook(content, accountConfig) {
|
|
9
|
-
if (!accountConfig.webhookToken) {
|
|
10
|
-
throw new Error("webhookToken is required");
|
|
11
|
-
}
|
|
12
|
-
const webhookUrl = `https://www.yunzhijia.com/gateway/robot/webhook/send?yzjtype=12&yzjtoken=${accountConfig.webhookToken}`;
|
|
13
|
-
const message = {
|
|
14
|
-
content: content,
|
|
15
|
-
};
|
|
16
|
-
try {
|
|
17
|
-
// Use the runtime's fetch implementation for proper error handling and proxy support
|
|
18
|
-
const response = await fetch(webhookUrl, {
|
|
19
|
-
method: 'POST',
|
|
20
|
-
headers: {
|
|
21
|
-
"Content-Type": "application/json",
|
|
22
|
-
},
|
|
23
|
-
body: JSON.stringify(message),
|
|
24
|
-
timeout: 10000,
|
|
25
|
-
});
|
|
26
|
-
if (!response.ok) {
|
|
27
|
-
throw new Error(`HTTP ${response.status}: ${response.statusText}`);
|
|
28
|
-
}
|
|
29
|
-
}
|
|
30
|
-
catch (error) {
|
|
31
|
-
console.error("Failed to send message to YunzhiJia:", error);
|
|
32
|
-
throw error;
|
|
33
|
-
}
|
|
34
|
-
}
|
|
35
|
-
/**
|
|
36
|
-
* Send media to YunzhiJia (placeholder - YunzhiJia may not support media directly)
|
|
37
|
-
*/
|
|
38
|
-
async function sendMediaToYunzhiJia(content, mediaUrl, accountConfig) {
|
|
39
|
-
// For now, just send the content with media URL as text
|
|
40
|
-
const messageWithMedia = `${content}\n${mediaUrl}`;
|
|
41
|
-
await sendToYunzhiJiaWebhook(messageWithMedia, accountConfig);
|
|
42
|
-
}
|