@feihan-im/openclaw-plugin 0.1.15 → 0.1.17
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/README.en.md +12 -7
- package/README.md +12 -7
- package/dist/index.cjs +40 -39
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +40 -39
- package/dist/index.js.map +1 -1
- package/dist/setup-entry.cjs +40 -39
- package/dist/setup-entry.cjs.map +1 -1
- package/dist/setup-entry.js +40 -39
- package/dist/setup-entry.js.map +1 -1
- package/openclaw.plugin.json +9 -9
- package/package.json +1 -1
- package/src/channel.ts +45 -40
- package/src/config.test.ts +18 -10
- package/src/config.ts +1 -2
- package/src/index.test.ts +1 -1
- package/src/types.ts +0 -6
package/src/channel.ts
CHANGED
|
@@ -5,12 +5,15 @@ import {
|
|
|
5
5
|
createChatChannelPlugin,
|
|
6
6
|
createChannelPluginBase,
|
|
7
7
|
} from "openclaw/plugin-sdk/core";
|
|
8
|
+
import { createHybridChannelConfigBase } from "openclaw/plugin-sdk/channel-config-helpers";
|
|
8
9
|
import type { OpenClawConfig } from "openclaw/plugin-sdk/core";
|
|
9
10
|
import { listAccountIds, resolveAccountConfig } from "./config.js";
|
|
10
11
|
import { sendText } from "./messaging/outbound.js";
|
|
11
12
|
import { parseTarget } from "./targets.js";
|
|
12
13
|
import type { FeihanAccountConfig } from "./types.js";
|
|
13
14
|
|
|
15
|
+
const BASE_FIELDS = ["appId", "appSecret", "backendUrl", "enabled", "enableEncryption", "requestTimeout"];
|
|
16
|
+
|
|
14
17
|
export const base = createChannelPluginBase<FeihanAccountConfig>({
|
|
15
18
|
id: "feihan",
|
|
16
19
|
|
|
@@ -28,37 +31,42 @@ export const base = createChannelPluginBase<FeihanAccountConfig>({
|
|
|
28
31
|
},
|
|
29
32
|
|
|
30
33
|
config: {
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
34
|
+
...createHybridChannelConfigBase<FeihanAccountConfig>({
|
|
35
|
+
sectionKey: "feihan",
|
|
36
|
+
listAccountIds: (cfg) => listAccountIds(cfg),
|
|
37
|
+
resolveAccount: (cfg, accountId) =>
|
|
38
|
+
resolveAccountConfig(cfg, accountId ?? undefined),
|
|
39
|
+
defaultAccountId: () => "default",
|
|
40
|
+
inspectAccount(cfg, accountId) {
|
|
41
|
+
const resolved = resolveAccountConfig(cfg, accountId ?? undefined);
|
|
42
|
+
const hasConfig = Boolean(
|
|
43
|
+
resolved.appId && resolved.appSecret && resolved.backendUrl,
|
|
44
|
+
);
|
|
45
|
+
return {
|
|
46
|
+
enabled: resolved.enabled,
|
|
47
|
+
configured: hasConfig,
|
|
48
|
+
tokenStatus: hasConfig ? "available" : "missing",
|
|
49
|
+
};
|
|
50
|
+
},
|
|
51
|
+
clearBaseFields: BASE_FIELDS,
|
|
52
|
+
}),
|
|
45
53
|
},
|
|
46
54
|
|
|
47
55
|
setup: {
|
|
48
56
|
validateInput: ({ input }) => {
|
|
49
57
|
const missing: string[] = [];
|
|
50
|
-
if (!input.appToken) missing.push("--app-token (App ID)");
|
|
51
|
-
if (!input.token) missing.push("--token (App Secret)");
|
|
52
|
-
if (!input.url) missing.push("--url (
|
|
58
|
+
if (!input.appToken) missing.push("--app-token (App ID from Admin Console)");
|
|
59
|
+
if (!input.token) missing.push("--token (App Secret from Admin Console)");
|
|
60
|
+
if (!input.url) missing.push("--url (your Feihan server address)");
|
|
53
61
|
if (missing.length > 0) {
|
|
54
62
|
return [
|
|
55
63
|
`Missing required flags: ${missing.join(", ")}`,
|
|
56
64
|
"",
|
|
57
|
-
"
|
|
65
|
+
"Usage:",
|
|
58
66
|
` openclaw channels add --channel feihan --app-token <APP_ID> --token <APP_SECRET> --url <BACKEND_URL>`,
|
|
59
67
|
"",
|
|
60
|
-
"
|
|
61
|
-
"
|
|
68
|
+
"You can find App ID and App Secret in:",
|
|
69
|
+
" Feihan Admin Console → Workplace → App Management → App Details",
|
|
62
70
|
].join("\n");
|
|
63
71
|
}
|
|
64
72
|
return null;
|
|
@@ -76,21 +84,15 @@ export const base = createChannelPluginBase<FeihanAccountConfig>({
|
|
|
76
84
|
const appSecret = input.token;
|
|
77
85
|
const backendUrl = input.url;
|
|
78
86
|
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
} else {
|
|
89
|
-
// Single-account: write at top level
|
|
90
|
-
if (appId) section.appId = appId;
|
|
91
|
-
if (appSecret) section.appSecret = appSecret;
|
|
92
|
-
if (backendUrl) section.backendUrl = backendUrl;
|
|
93
|
-
}
|
|
87
|
+
const id = accountId || "default";
|
|
88
|
+
|
|
89
|
+
if (!section.accounts) section.accounts = {};
|
|
90
|
+
const accounts = section.accounts as Record<string, Record<string, unknown>>;
|
|
91
|
+
if (!accounts[id]) accounts[id] = {};
|
|
92
|
+
const account = accounts[id];
|
|
93
|
+
if (appId) account.appId = appId;
|
|
94
|
+
if (appSecret) account.appSecret = appSecret;
|
|
95
|
+
if (backendUrl) account.backendUrl = backendUrl;
|
|
94
96
|
|
|
95
97
|
return updated as OpenClawConfig;
|
|
96
98
|
},
|
|
@@ -117,7 +119,8 @@ export const base = createChannelPluginBase<FeihanAccountConfig>({
|
|
|
117
119
|
preferredEnvVar: "FEIHAN_APP_ID",
|
|
118
120
|
envPrompt: "Use FEIHAN_APP_ID from environment?",
|
|
119
121
|
keepPrompt: "Keep current App ID?",
|
|
120
|
-
inputPrompt:
|
|
122
|
+
inputPrompt:
|
|
123
|
+
"Enter App ID (from Feihan Admin Console → Workplace → App Management → App Details):",
|
|
121
124
|
inspect: ({ cfg, accountId }) => {
|
|
122
125
|
const resolved = resolveAccountConfig(cfg, accountId ?? undefined);
|
|
123
126
|
return {
|
|
@@ -133,7 +136,8 @@ export const base = createChannelPluginBase<FeihanAccountConfig>({
|
|
|
133
136
|
preferredEnvVar: "FEIHAN_APP_SECRET",
|
|
134
137
|
envPrompt: "Use FEIHAN_APP_SECRET from environment?",
|
|
135
138
|
keepPrompt: "Keep current App Secret?",
|
|
136
|
-
inputPrompt:
|
|
139
|
+
inputPrompt:
|
|
140
|
+
"Enter App Secret (from the same App Details page, keep this value confidential):",
|
|
137
141
|
inspect: ({ cfg, accountId }) => {
|
|
138
142
|
const resolved = resolveAccountConfig(cfg, accountId ?? undefined);
|
|
139
143
|
return {
|
|
@@ -145,11 +149,12 @@ export const base = createChannelPluginBase<FeihanAccountConfig>({
|
|
|
145
149
|
{
|
|
146
150
|
inputKey: "url",
|
|
147
151
|
providerHint: "feihan",
|
|
148
|
-
credentialLabel: "
|
|
152
|
+
credentialLabel: "Feihan Server URL",
|
|
149
153
|
preferredEnvVar: "FEIHAN_BACKEND_URL",
|
|
150
154
|
envPrompt: "Use FEIHAN_BACKEND_URL from environment?",
|
|
151
|
-
keepPrompt: "Keep current
|
|
152
|
-
inputPrompt:
|
|
155
|
+
keepPrompt: "Keep current Feihan Server URL?",
|
|
156
|
+
inputPrompt:
|
|
157
|
+
"Enter your Feihan server address (e.g. http://192.168.10.10:21000):",
|
|
153
158
|
inspect: ({ cfg, accountId }) => {
|
|
154
159
|
const resolved = resolveAccountConfig(cfg, accountId ?? undefined);
|
|
155
160
|
return {
|
package/src/config.test.ts
CHANGED
|
@@ -16,8 +16,8 @@ describe("listAccountIds", () => {
|
|
|
16
16
|
expect(listAccountIds(undefined)).toEqual([]);
|
|
17
17
|
});
|
|
18
18
|
|
|
19
|
-
it("returns ['default'] for
|
|
20
|
-
const cfg = { channels: { feihan: { appId: "app_1" } } };
|
|
19
|
+
it("returns ['default'] for single-account config", () => {
|
|
20
|
+
const cfg = { channels: { feihan: { accounts: { default: { appId: "app_1" } } } } };
|
|
21
21
|
expect(listAccountIds(cfg)).toEqual(["default"]);
|
|
22
22
|
});
|
|
23
23
|
|
|
@@ -48,13 +48,17 @@ describe("listAccountIds", () => {
|
|
|
48
48
|
});
|
|
49
49
|
|
|
50
50
|
describe("resolveAccountConfig", () => {
|
|
51
|
-
it("resolves
|
|
51
|
+
it("resolves default account with defaults applied", () => {
|
|
52
52
|
const cfg = {
|
|
53
53
|
channels: {
|
|
54
54
|
feihan: {
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
55
|
+
accounts: {
|
|
56
|
+
default: {
|
|
57
|
+
appId: "app_1",
|
|
58
|
+
appSecret: "secret_1",
|
|
59
|
+
backendUrl: "https://your-backend-url.com",
|
|
60
|
+
},
|
|
61
|
+
},
|
|
58
62
|
},
|
|
59
63
|
},
|
|
60
64
|
};
|
|
@@ -118,7 +122,7 @@ describe("resolveAccountConfig", () => {
|
|
|
118
122
|
it("config values take precedence over env vars", () => {
|
|
119
123
|
process.env.FEIHAN_APP_ID = "env_app";
|
|
120
124
|
const cfg = {
|
|
121
|
-
channels: { feihan: { appId: "config_app", appSecret: "s", backendUrl: "http://x" } },
|
|
125
|
+
channels: { feihan: { accounts: { default: { appId: "config_app", appSecret: "s", backendUrl: "http://x" } } } },
|
|
122
126
|
};
|
|
123
127
|
try {
|
|
124
128
|
const account = resolveAccountConfig(cfg);
|
|
@@ -205,9 +209,13 @@ describe("resolveAndValidateAccountConfig", () => {
|
|
|
205
209
|
const cfg = {
|
|
206
210
|
channels: {
|
|
207
211
|
feihan: {
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
212
|
+
accounts: {
|
|
213
|
+
default: {
|
|
214
|
+
appId: "app_1",
|
|
215
|
+
appSecret: "secret_1",
|
|
216
|
+
backendUrl: "https://your-backend-url.com",
|
|
217
|
+
},
|
|
218
|
+
},
|
|
211
219
|
},
|
|
212
220
|
},
|
|
213
221
|
};
|
package/src/config.ts
CHANGED
|
@@ -45,7 +45,6 @@ export function listAccountIds(cfg: unknown): string[] {
|
|
|
45
45
|
return [];
|
|
46
46
|
}
|
|
47
47
|
if (ch.accounts) return Object.keys(ch.accounts);
|
|
48
|
-
if (ch.appId) return ["default"];
|
|
49
48
|
// env var fallback
|
|
50
49
|
if (process.env[`${ENV_PREFIX}APP_ID`]) return ["default"];
|
|
51
50
|
return [];
|
|
@@ -59,7 +58,7 @@ export function resolveAccountConfig(
|
|
|
59
58
|
const id = accountId ?? "default";
|
|
60
59
|
const envConfig = readEnvConfig();
|
|
61
60
|
|
|
62
|
-
const raw = ch?.accounts?.[id]
|
|
61
|
+
const raw = ch?.accounts?.[id];
|
|
63
62
|
|
|
64
63
|
return {
|
|
65
64
|
accountId: id,
|
package/src/index.test.ts
CHANGED
|
@@ -151,7 +151,7 @@ describe("service start — config validation", () => {
|
|
|
151
151
|
it("connects valid accounts normally", async () => {
|
|
152
152
|
const api = createMockApi({
|
|
153
153
|
channels: {
|
|
154
|
-
feihan: { appId: "a", appSecret: "s", backendUrl: "https://ok.io" },
|
|
154
|
+
feihan: { accounts: { default: { appId: "a", appSecret: "s", backendUrl: "https://ok.io" } } },
|
|
155
155
|
},
|
|
156
156
|
});
|
|
157
157
|
entry.default.registerFull(api);
|
package/src/types.ts
CHANGED
|
@@ -23,12 +23,6 @@ export interface FeihanRawAccountConfig {
|
|
|
23
23
|
}
|
|
24
24
|
|
|
25
25
|
export interface FeihanChannelConfig {
|
|
26
|
-
appId?: string;
|
|
27
|
-
appSecret?: string;
|
|
28
|
-
backendUrl?: string;
|
|
29
|
-
enabled?: boolean;
|
|
30
|
-
enableEncryption?: boolean;
|
|
31
|
-
requestTimeout?: number;
|
|
32
26
|
accounts?: Record<string, FeihanRawAccountConfig>;
|
|
33
27
|
}
|
|
34
28
|
|