@workclaw/openclaw-workchat 1.0.3 → 1.0.4
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/index.js +9 -41
- package/package.json +1 -1
- package/src/auth/accounts.ts +5 -16
- package/src/auth/bind-agent.ts +22 -40
- package/src/auth/login-qr.ts +3 -1
package/index.js
CHANGED
|
@@ -373,23 +373,9 @@ async function removeWorkChatAccountBinding(accountId) {
|
|
|
373
373
|
logger.warn(`removeWorkChatAccountBinding: allowFrom cleanup failed: ${String(err)}`);
|
|
374
374
|
}
|
|
375
375
|
try {
|
|
376
|
-
|
|
377
|
-
const cfg = loadConfig();
|
|
378
|
-
const channels = cfg.channels ?? {};
|
|
379
|
-
const section = channels["openclaw-workchat"];
|
|
380
|
-
if (section?.accounts?.[accountId] !== void 0) {
|
|
381
|
-
const accounts = { ...section.accounts ?? {} };
|
|
382
|
-
delete accounts[accountId];
|
|
383
|
-
await writeConfigFile({
|
|
384
|
-
...cfg,
|
|
385
|
-
channels: {
|
|
386
|
-
...channels,
|
|
387
|
-
"openclaw-workchat": { ...section, accounts }
|
|
388
|
-
}
|
|
389
|
-
});
|
|
390
|
-
}
|
|
376
|
+
await triggerWorkChatChannelReload();
|
|
391
377
|
} catch (err) {
|
|
392
|
-
logger.warn(`removeWorkChatAccountBinding:
|
|
378
|
+
logger.warn(`removeWorkChatAccountBinding: channel reload trigger failed: ${String(err)}`);
|
|
393
379
|
}
|
|
394
380
|
}
|
|
395
381
|
async function pruneStaleWorkChatAccounts(keepAgentId) {
|
|
@@ -26883,30 +26869,6 @@ __export(bind_agent_exports, {
|
|
|
26883
26869
|
bindAgentToAccountFromBinding: () => bindAgentToAccountFromBinding
|
|
26884
26870
|
});
|
|
26885
26871
|
async function bindAgentToAccount(accountId, agentId, userId) {
|
|
26886
|
-
const { loadConfig, writeConfigFile } = await import("openclaw/plugin-sdk/config-runtime");
|
|
26887
|
-
const raw = loadConfig();
|
|
26888
|
-
const channels = raw.channels ?? {};
|
|
26889
|
-
const section = channels["openclaw-workchat"] ?? {};
|
|
26890
|
-
const accounts = { ...section.accounts ?? {} };
|
|
26891
|
-
accounts[accountId] = {
|
|
26892
|
-
...accounts[accountId] ?? {},
|
|
26893
|
-
enabled: true,
|
|
26894
|
-
agentId,
|
|
26895
|
-
...userId ? { userId } : {}
|
|
26896
|
-
};
|
|
26897
|
-
const updated = {
|
|
26898
|
-
...raw,
|
|
26899
|
-
channels: {
|
|
26900
|
-
...channels,
|
|
26901
|
-
"openclaw-workchat": {
|
|
26902
|
-
...section,
|
|
26903
|
-
accounts,
|
|
26904
|
-
...userId && !section.userId ? { userId } : {},
|
|
26905
|
-
channelConfigUpdatedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
26906
|
-
}
|
|
26907
|
-
}
|
|
26908
|
-
};
|
|
26909
|
-
await writeConfigFile(updated);
|
|
26910
26872
|
if (userId) {
|
|
26911
26873
|
try {
|
|
26912
26874
|
const { registerUserInFrameworkStore: registerUserInFrameworkStore2 } = await Promise.resolve().then(() => (init_pairing(), pairing_exports));
|
|
@@ -26915,8 +26877,14 @@ async function bindAgentToAccount(accountId, agentId, userId) {
|
|
|
26915
26877
|
logger.warn(`bindAgentToAccount: allowFrom registration failed: ${String(err)}`);
|
|
26916
26878
|
}
|
|
26917
26879
|
}
|
|
26880
|
+
try {
|
|
26881
|
+
const { triggerWorkChatChannelReload: triggerWorkChatChannelReload2 } = await Promise.resolve().then(() => (init_accounts(), accounts_exports));
|
|
26882
|
+
await triggerWorkChatChannelReload2();
|
|
26883
|
+
} catch (err) {
|
|
26884
|
+
logger.warn(`bindAgentToAccount: channel reload trigger failed: ${String(err)}`);
|
|
26885
|
+
}
|
|
26918
26886
|
logger.info(
|
|
26919
|
-
`bindAgentToAccount: accountId=${accountId} agentId=${agentId} userId=${userId || "(none)"} (apiKey NOT written \u2014 env-injected)`
|
|
26887
|
+
`bindAgentToAccount: accountId=${accountId} agentId=${agentId} userId=${userId || "(none)"} (private-dir only; apiKey NOT written \u2014 env-injected)`
|
|
26920
26888
|
);
|
|
26921
26889
|
}
|
|
26922
26890
|
var bindAgentToAccountFromBinding;
|
package/package.json
CHANGED
package/src/auth/accounts.ts
CHANGED
|
@@ -141,24 +141,13 @@ export async function removeWorkChatAccountBinding(accountId: string): Promise<v
|
|
|
141
141
|
logger.warn(`removeWorkChatAccountBinding: allowFrom cleanup failed: ${String(err)}`);
|
|
142
142
|
}
|
|
143
143
|
|
|
144
|
+
// Account entries no longer live in openclaw.json (weixin-style private-dir
|
|
145
|
+
// ownership), so there is no shared config to clean up here — the channel
|
|
146
|
+
// reload bump below lets the gateway drop the removed account.
|
|
144
147
|
try {
|
|
145
|
-
|
|
146
|
-
const cfg = loadConfig();
|
|
147
|
-
const channels = (cfg.channels ?? {}) as Record<string, any>;
|
|
148
|
-
const section = channels["openclaw-workchat"];
|
|
149
|
-
if (section?.accounts?.[accountId] !== undefined) {
|
|
150
|
-
const accounts = { ...(section.accounts ?? {}) };
|
|
151
|
-
delete accounts[accountId];
|
|
152
|
-
await writeConfigFile({
|
|
153
|
-
...cfg,
|
|
154
|
-
channels: {
|
|
155
|
-
...channels,
|
|
156
|
-
"openclaw-workchat": { ...section, accounts },
|
|
157
|
-
},
|
|
158
|
-
} as import("openclaw/plugin-sdk").OpenClawConfig);
|
|
159
|
-
}
|
|
148
|
+
await triggerWorkChatChannelReload();
|
|
160
149
|
} catch (err) {
|
|
161
|
-
logger.warn(`removeWorkChatAccountBinding:
|
|
150
|
+
logger.warn(`removeWorkChatAccountBinding: channel reload trigger failed: ${String(err)}`);
|
|
162
151
|
}
|
|
163
152
|
}
|
|
164
153
|
|
package/src/auth/bind-agent.ts
CHANGED
|
@@ -1,53 +1,26 @@
|
|
|
1
1
|
import { logger } from "../util/logger.js";
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
|
-
*
|
|
5
|
-
* channels.openclaw-workchat.accounts of openclaw.json so inbound
|
|
6
|
-
* AGENT_MESSAGE frames route to the right account and outbound sends find
|
|
7
|
-
* the agent.
|
|
4
|
+
* Complete the binding on the plugin side.
|
|
8
5
|
*
|
|
9
|
-
*
|
|
10
|
-
*
|
|
11
|
-
*
|
|
12
|
-
*
|
|
13
|
-
* WORKCHAT_API_KEY / WORKCHAT_APP_SECRET env injection.
|
|
6
|
+
* The account payload (agentId/userId) lives exclusively in the plugin's
|
|
7
|
+
* private state dir (`state/openclaw-workchat/accounts/`) — weixin-style. The
|
|
8
|
+
* caller (binding listener / monitor INIT_AGENT handling) persists it via
|
|
9
|
+
* saveWorkChatAccount + registerWorkChatAccountId before calling this.
|
|
14
10
|
*
|
|
15
|
-
*
|
|
16
|
-
*
|
|
11
|
+
* This function only bumps `channelConfigUpdatedAt` in openclaw.json so the
|
|
12
|
+
* gateway reloads config from disk and restarts the channel with the fresh
|
|
13
|
+
* private-dir account data. Writing account entries into
|
|
14
|
+
* channels.openclaw-workchat.accounts here would race the desktop configSync
|
|
15
|
+
* (which rebuilds that field) and orphan the credentials/
|
|
16
|
+
* <account>-allowFrom.json files — the gateway's startup migration treats
|
|
17
|
+
* those as a fatal unresolved state.
|
|
17
18
|
*/
|
|
18
19
|
export async function bindAgentToAccount(
|
|
19
20
|
accountId: string,
|
|
20
21
|
agentId: string,
|
|
21
22
|
userId?: string,
|
|
22
23
|
): Promise<void> {
|
|
23
|
-
const { loadConfig, writeConfigFile } = await import("openclaw/plugin-sdk/config-runtime");
|
|
24
|
-
const raw = loadConfig() as Record<string, any>;
|
|
25
|
-
const channels = (raw.channels ?? {}) as Record<string, any>;
|
|
26
|
-
const section = (channels["openclaw-workchat"] ?? {}) as Record<string, any>;
|
|
27
|
-
const accounts = { ...(section.accounts ?? {}) };
|
|
28
|
-
|
|
29
|
-
accounts[accountId] = {
|
|
30
|
-
...(accounts[accountId] ?? {}),
|
|
31
|
-
enabled: true,
|
|
32
|
-
agentId,
|
|
33
|
-
...(userId ? { userId } : {}),
|
|
34
|
-
};
|
|
35
|
-
|
|
36
|
-
const updated = {
|
|
37
|
-
...raw,
|
|
38
|
-
channels: {
|
|
39
|
-
...channels,
|
|
40
|
-
"openclaw-workchat": {
|
|
41
|
-
...section,
|
|
42
|
-
accounts,
|
|
43
|
-
...(userId && !section.userId ? { userId } : {}),
|
|
44
|
-
channelConfigUpdatedAt: new Date().toISOString(),
|
|
45
|
-
},
|
|
46
|
-
},
|
|
47
|
-
} as Record<string, any>;
|
|
48
|
-
|
|
49
|
-
await writeConfigFile(updated as import("openclaw/plugin-sdk").OpenClawConfig);
|
|
50
|
-
|
|
51
24
|
// Persist the binding user in the framework allowFrom store so command
|
|
52
25
|
// authorization has an explicit source of truth (the inbound path also
|
|
53
26
|
// falls back to the account's userId, but writing it keeps parity with the
|
|
@@ -61,8 +34,17 @@ export async function bindAgentToAccount(
|
|
|
61
34
|
}
|
|
62
35
|
}
|
|
63
36
|
|
|
37
|
+
// Trigger the channel hot reload; account data itself stays in the private
|
|
38
|
+
// state dir (already persisted by the caller before this runs).
|
|
39
|
+
try {
|
|
40
|
+
const { triggerWorkChatChannelReload } = await import("./accounts.js");
|
|
41
|
+
await triggerWorkChatChannelReload();
|
|
42
|
+
} catch (err) {
|
|
43
|
+
logger.warn(`bindAgentToAccount: channel reload trigger failed: ${String(err)}`);
|
|
44
|
+
}
|
|
45
|
+
|
|
64
46
|
logger.info(
|
|
65
|
-
`bindAgentToAccount: accountId=${accountId} agentId=${agentId} userId=${userId || "(none)"} (apiKey NOT written — env-injected)`,
|
|
47
|
+
`bindAgentToAccount: accountId=${accountId} agentId=${agentId} userId=${userId || "(none)"} (private-dir only; apiKey NOT written — env-injected)`,
|
|
66
48
|
);
|
|
67
49
|
}
|
|
68
50
|
|
package/src/auth/login-qr.ts
CHANGED
|
@@ -427,7 +427,9 @@ async function handleListenerFrame(sessionKey: string, data: string, ws: WebSock
|
|
|
427
427
|
...(userId ? { userId } : {}),
|
|
428
428
|
});
|
|
429
429
|
registerWorkChatAccountId(accountId);
|
|
430
|
-
//
|
|
430
|
+
// Complete the binding: account data is already in the private state
|
|
431
|
+
// dir; this call registers the allowFrom user and triggers the channel
|
|
432
|
+
// hot reload.
|
|
431
433
|
const { bindAgentToAccountFromBinding } = await import("./bind-agent.js");
|
|
432
434
|
await bindAgentToAccountFromBinding(accountId, agentId, userId);
|
|
433
435
|
logger.info(`binding listener: account=${accountId} agent=${agentId} persisted`);
|