@xmanrui/dsh-im 4.3.0 → 4.4.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.
- package/lib/client.js +951 -626
- package/lib/index.js +233 -233
- package/package.json +1 -1
- package/plugin-src/client/access-policy-settings.js +351 -0
- package/plugin-src/client/channel-card-meta.js +2 -1
- package/plugin-src/client/channels/dingtalk/api.js +5 -0
- package/plugin-src/client/channels/dingtalk/index.js +1 -0
- package/plugin-src/client/channels/feishu/api.js +5 -0
- package/plugin-src/client/channels/feishu/index.js +1 -0
- package/plugin-src/client/channels/qq/api.js +5 -0
- package/plugin-src/client/channels/qq/index.js +1 -0
- package/plugin-src/client/channels/shared/token-api.js +5 -0
- package/plugin-src/client/channels/shared/token-channel.js +1 -0
- package/plugin-src/client/channels/telegram/api.js +2 -17
- package/plugin-src/client/channels/telegram/index.js +0 -112
- package/plugin-src/client/channels/telegram/styles.js +0 -28
- package/plugin-src/client/channels/wecom/api.js +5 -0
- package/plugin-src/client/channels/wecom/index.js +1 -0
- package/plugin-src/client/channels/weixin/api.js +5 -0
- package/plugin-src/client/channels/weixin/index.js +1 -0
- package/plugin-src/client/channels/whatsapp/api.js +4 -10
- package/plugin-src/client/channels/whatsapp/index.js +1 -125
- package/plugin-src/client/channels/whatsapp/styles.js +0 -25
- package/plugin-src/client/delivery-settings.js +61 -9
- package/plugin-src/client/i18n.js +56 -1
- package/plugin-src/client/index.js +1 -0
- package/plugin-src/client/styles.js +50 -4
- package/plugin-src/host/channels/dingtalk/production.mjs +12 -1
- package/plugin-src/host/channels/dingtalk/rpc.mjs +11 -0
- package/plugin-src/host/channels/feishu/production.mjs +39 -1
- package/plugin-src/host/channels/feishu/rpc.mjs +19 -2
- package/plugin-src/host/channels/qq/production.mjs +12 -1
- package/plugin-src/host/channels/qq/rpc.mjs +11 -0
- package/plugin-src/host/channels/shared/access-policy-production.mjs +137 -0
- package/plugin-src/host/channels/shared/access-policy-rpc.mjs +17 -0
- package/plugin-src/host/channels/shared/production.mjs +15 -1
- package/plugin-src/host/channels/shared/rpc.mjs +9 -0
- package/plugin-src/host/channels/slack/production.mjs +12 -1
- package/plugin-src/host/channels/slack/rpc.mjs +10 -0
- package/plugin-src/host/channels/telegram/rpc.mjs +2 -49
- package/plugin-src/host/channels/wecom/production.mjs +12 -1
- package/plugin-src/host/channels/wecom/rpc.mjs +11 -0
- package/plugin-src/host/channels/weixin/production.mjs +12 -1
- package/plugin-src/host/channels/weixin/rpc.mjs +11 -0
- package/plugin-src/host/channels/whatsapp/production.mjs +16 -2
- package/plugin-src/host/channels/whatsapp/rpc.mjs +10 -15
- package/src/channels/dingtalk/dingtalk-bridge.mjs +61 -9
- package/src/channels/dingtalk/dingtalk-runtime.mjs +4 -0
- package/src/channels/discord/discord-runtime.mjs +29 -1
- package/src/channels/feishu/bridge.mjs +188 -80
- package/src/channels/feishu/feishu-runtime.mjs +4 -0
- package/src/channels/qq/qq-bridge.mjs +59 -17
- package/src/channels/qq/qq-runtime.mjs +20 -2
- package/src/channels/shared/access-policy.mjs +210 -0
- package/src/channels/shared/bot-workspace-store.mjs +176 -33
- package/src/channels/shared/command-permission.mjs +32 -0
- package/src/channels/shared/compact-command.mjs +5 -2
- package/src/channels/shared/i18n-en/shared-c.mjs +2 -0
- package/src/channels/shared/inbound-access.mjs +43 -0
- package/src/channels/shared/text-harness-bridge.mjs +47 -4
- package/src/channels/shared/workspace-command.mjs +10 -1
- package/src/channels/slack/slack-runtime.mjs +4 -0
- package/src/channels/telegram/telegram-runtime.mjs +5 -13
- package/src/channels/wecom/wecom-bridge.mjs +51 -4
- package/src/channels/wecom/wecom-runtime.mjs +4 -0
- package/src/channels/weixin/weixin-bridge.mjs +59 -16
- package/src/channels/weixin/weixin-runtime.mjs +4 -0
- package/src/channels/whatsapp/whatsapp-runtime.mjs +42 -20
package/lib/client.js
CHANGED
|
@@ -571,7 +571,7 @@ var React23 = __toESM(require("react"), 1);
|
|
|
571
571
|
// package.json
|
|
572
572
|
var package_default = {
|
|
573
573
|
name: "@xmanrui/dsh-im",
|
|
574
|
-
version: "4.
|
|
574
|
+
version: "4.4.0",
|
|
575
575
|
description: "\u628A\u4E5D\u79CD IM \u673A\u5668\u4EBA\u548C\u516C\u7F51 AI Office \u63A5\u5165\u672C\u673A DeepSeek Harness\u3002 Connect nine IM channels and a public AI Office to a local DeepSeek Harness.",
|
|
576
576
|
keywords: [
|
|
577
577
|
"deepseek-harness",
|
|
@@ -841,6 +841,62 @@ var EN = Object.freeze({
|
|
|
841
841
|
"IM\u673A\u5668\u4EBA": "IM bots",
|
|
842
842
|
"IM\u673A\u5668\u4EBA\u8BBE\u7F6E": "IM bot settings",
|
|
843
843
|
"\u66F4\u591A\u673A\u5668\u4EBA\u8BBE\u7F6E": "More bot settings",
|
|
844
|
+
"\u673A\u5668\u4EBA\u8BBE\u7F6E": "Bot settings",
|
|
845
|
+
"\u673A\u5668\u4EBA\u8BBE\u7F6E\u9875\u7B7E": "Bot settings tabs",
|
|
846
|
+
"\u6295\u9012\u8BBE\u7F6E": "Delivery settings",
|
|
847
|
+
"\u8BBF\u95EE\u8BBE\u7F6E": "Access settings",
|
|
848
|
+
"\u67E5\u770B\u8BBF\u95EE\u6743\u9650\u8BF4\u660E": "View access permission details",
|
|
849
|
+
"\u5141\u8BB8\u6240\u6709\u7528\u6237": "Allow all users",
|
|
850
|
+
"\u4EC5\u767D\u540D\u5355\u7528\u6237": "Allowlisted users only",
|
|
851
|
+
"\u9ED8\u8BA4\u547D\u4EE4\u6743\u9650": "Default command permission",
|
|
852
|
+
"\u547D\u4EE4\u6743\u9650": "Command permission",
|
|
853
|
+
"\u53EF\u4EE5\u6267\u884C\u547D\u4EE4": "Can run commands",
|
|
854
|
+
"\u4E0D\u53EF\u4EE5\u6267\u884C\u547D\u4EE4": "Cannot run commands",
|
|
855
|
+
"\u767D\u540D\u5355\u7528\u6237": "Allowlisted users",
|
|
856
|
+
"\u67E5\u770B\u767D\u540D\u5355\u8BF4\u660E": "View allowlist details",
|
|
857
|
+
"\u547D\u4EE4\u6743\u9650\u4F8B\u5916": "Command permission exceptions",
|
|
858
|
+
"\u5F53\u524D\u6CA1\u6709\u767D\u540D\u5355\u7528\u6237\uFF0C\u4FDD\u5B58\u540E\u666E\u901A\u7528\u6237\u5C06\u65E0\u6CD5\u4F7F\u7528\u673A\u5668\u4EBA\u3002": "There are currently no allowlisted users. After saving, regular users will not be able to use the bot.",
|
|
859
|
+
"\u65B0\u589E\u7528\u6237": "Add user",
|
|
860
|
+
"\u5C1A\u672A\u6DFB\u52A0\u7528\u6237": "No users added",
|
|
861
|
+
"\u5F53\u524D\u6E20\u9053\u4E0D\u652F\u6301\u7FA4\u804A": "Group chat is not supported by this channel",
|
|
862
|
+
"\u539F\u6240\u6709\u8005\u6216\u626B\u7801\u63A5\u5165\u8005\u59CB\u7EC8\u53EF\u4EE5\u8BBF\u95EE\u5E76\u6267\u884C\u547D\u4EE4\uFF1B\u4EE5\u4E0B\u8BBE\u7F6E\u4EC5\u7EA6\u675F\u5176\u4ED6\u7528\u6237\u3002": "The original owner or QR-code operator can always access the bot and run commands; the settings below apply only to other users.",
|
|
863
|
+
"\u6B64\u533A\u57DF\u65E0\u9700\u914D\u7F6E\uFF0C\u4FDD\u5B58\u79C1\u804A\u8BBE\u7F6E\u65F6\u4F1A\u4FDD\u7559\u73B0\u6709\u7FA4\u804A\u7B56\u7565\u3002": "No setup is needed here. Saving direct-message settings keeps the existing group policy.",
|
|
864
|
+
"\u8BBF\u95EE\u8BBE\u7F6E\u5DF2\u4FDD\u5B58\u3002": "Access settings saved.",
|
|
865
|
+
"\u8BBF\u95EE\u8BBE\u7F6E\u6682\u4E0D\u53EF\u7528\u3002": "Access settings are currently unavailable.",
|
|
866
|
+
"\u8BBF\u95EE\u8BBE\u7F6E\u4FDD\u5B58\u5931\u8D25\uFF0C\u8BF7\u7A0D\u540E\u91CD\u8BD5\u3002": "Could not save access settings. Try again later.",
|
|
867
|
+
"\u670D\u52A1\u6CA1\u6709\u8FD4\u56DE\u5DF2\u4FDD\u5B58\u7684\u8BBF\u95EE\u7B56\u7565\uFF0C\u8BF7\u5237\u65B0\u540E\u91CD\u8BD5\u3002": "The service did not return the saved access policy. Refresh and try again.",
|
|
868
|
+
"\u8BBF\u95EE\u7B56\u7565\u5C1A\u672A\u5C31\u7EEA\uFF0C\u8BF7\u8FD4\u56DE\u673A\u5668\u4EBA\u5217\u8868\u5237\u65B0\u540E\u91CD\u8BD5\u3002": "The access policy is not ready. Return to the bot list, refresh, and try again.",
|
|
869
|
+
"\u5F53\u524D\u6E20\u9053\u6682\u4E0D\u652F\u6301\u8BBF\u95EE\u8BBE\u7F6E\u3002": "Access settings are not supported by this channel yet.",
|
|
870
|
+
"\u7528\u6237\u6807\u8BC6\u65E0\u6548\u3002": "The user ID is invalid.",
|
|
871
|
+
"\u7528\u6237\u6807\u8BC6\u5FC5\u987B\u662F\u5B57\u7B26\u4E32\u3002": "The user ID must be a string.",
|
|
872
|
+
"\u7528\u6237\u6807\u8BC6\u4E0D\u80FD\u4E3A\u7A7A\u3001\u5305\u542B\u63A7\u5236\u5B57\u7B26\u6216\u8D85\u8FC7 256 \u4E2A\u5B57\u7B26\u3002": "The user ID cannot be empty, contain control characters, or exceed 256 characters.",
|
|
873
|
+
"\u7528\u6237\u6761\u76EE\u5FC5\u987B\u5305\u542B\u7528\u6237\u6807\u8BC6\u548C\u547D\u4EE4\u6743\u9650\u3002": "Each user entry must include a user ID and command permission.",
|
|
874
|
+
"\u547D\u4EE4\u6743\u9650\u5FC5\u987B\u662F\u5E03\u5C14\u503C\u3002": "Command permission must be a boolean.",
|
|
875
|
+
"\u8BBF\u95EE\u6A21\u5F0F\u53EA\u80FD\u662F open \u6216 allowlist\u3002": "Access mode must be open or allowlist.",
|
|
876
|
+
"\u5F00\u653E\u6A21\u5F0F\u8BBE\u7F6E\u5FC5\u987B\u5B8C\u6574\u3002": "Open-mode settings must be complete.",
|
|
877
|
+
"\u5F00\u653E\u6A21\u5F0F\u9ED8\u8BA4\u547D\u4EE4\u6743\u9650\u5FC5\u987B\u662F\u5E03\u5C14\u503C\u3002": "The open-mode default command permission must be a boolean.",
|
|
878
|
+
"\u5F00\u653E\u6A21\u5F0F\u547D\u4EE4\u6743\u9650\u8986\u76D6\u7528\u6237\u5FC5\u987B\u662F\u6570\u7EC4\u3002": "Open-mode command permission overrides must be an array.",
|
|
879
|
+
"\u5F00\u653E\u6A21\u5F0F\u547D\u4EE4\u6743\u9650\u8986\u76D6\u7528\u6237\u4E0D\u80FD\u5305\u542B\u91CD\u590D\u7684\u7528\u6237\u6807\u8BC6\u3002": "Open-mode command permission overrides cannot contain duplicate user IDs.",
|
|
880
|
+
"\u767D\u540D\u5355\u6A21\u5F0F\u8BBE\u7F6E\u5FC5\u987B\u5B8C\u6574\u3002": "Allowlist-mode settings must be complete.",
|
|
881
|
+
"\u767D\u540D\u5355\u6A21\u5F0F\u7528\u6237\u5FC5\u987B\u662F\u6570\u7EC4\u3002": "Allowlist-mode users must be an array.",
|
|
882
|
+
"\u767D\u540D\u5355\u6A21\u5F0F\u7528\u6237\u4E0D\u80FD\u5305\u542B\u91CD\u590D\u7684\u7528\u6237\u6807\u8BC6\u3002": "Allowlist-mode users cannot contain duplicate user IDs.",
|
|
883
|
+
"\u8BBF\u95EE\u573A\u666F\u8BBE\u7F6E\u5FC5\u987B\u540C\u65F6\u5305\u542B\u6A21\u5F0F\u3001\u5F00\u653E\u6A21\u5F0F\u8BBE\u7F6E\u548C\u767D\u540D\u5355\u6A21\u5F0F\u8BBE\u7F6E\u3002": "Each access context must include its mode, open-mode settings, and allowlist-mode settings.",
|
|
884
|
+
"\u8BF7\u540C\u65F6\u63D0\u4EA4\u5B8C\u6574\u7684\u79C1\u804A\u548C\u7FA4\u804A\u8BBF\u95EE\u8BBE\u7F6E\u3002": "Submit complete direct-message and group access settings together.",
|
|
885
|
+
"\u586B\u5199\u5FAE\u4FE1\u7528\u6237 ID": "Enter a WeChat user ID",
|
|
886
|
+
"\u98DE\u4E66 Open ID": "Feishu Open ID",
|
|
887
|
+
"\u7FA4\u6210\u5458 Open ID": "Group member Open ID",
|
|
888
|
+
"\u9489\u9489\u7528\u6237 ID": "DingTalk user ID",
|
|
889
|
+
"\u586B\u5199 senderStaffId \u6216 senderId": "Enter senderStaffId or senderId",
|
|
890
|
+
"\u7FA4\u6210\u5458\u7528\u6237 ID": "Group member user ID",
|
|
891
|
+
"\u4F01\u4E1A\u5FAE\u4FE1\u7528\u6237 ID": "WeCom user ID",
|
|
892
|
+
"\u586B\u5199 userid": "Enter userid",
|
|
893
|
+
"\u586B\u5199 member_openid": "Enter member_openid",
|
|
894
|
+
"QQ User Open ID": "QQ User Open ID",
|
|
895
|
+
"\u7FA4\u6210\u5458 User ID": "Group member User ID",
|
|
896
|
+
"\u586B\u5199\u6570\u5B57 User ID": "Enter a numeric user ID",
|
|
897
|
+
"WhatsApp \u7535\u8BDD\u53F7\u7801\u6216 JID": "WhatsApp phone number or JID",
|
|
898
|
+
"\u7FA4\u6210\u5458\u7535\u8BDD\u53F7\u7801\u6216 JID": "Group member phone number or JID",
|
|
899
|
+
"8613800000000 \u6216\u5B8C\u6574 JID": "8613800000000 or a full JID",
|
|
844
900
|
"IM \u6E20\u9053": "IM channels",
|
|
845
901
|
"\u8BA9 DeepSeek Harness \u89E6\u624B\u53EF\u53CA": "Connecting DeepSeek Harness",
|
|
846
902
|
"\u5F53\u524D\u7248\u672C": "Current version",
|
|
@@ -1355,7 +1411,6 @@ var EN = Object.freeze({
|
|
|
1355
1411
|
"\u5148\u901A\u8FC7 @BotFather \u83B7\u53D6 Bot Token\uFF0C\u518D\u5728\u8FD9\u91CC\u5B8C\u6210\u63A5\u5165\u3002": "Get a Bot Token from @BotFather, then connect it here.",
|
|
1356
1412
|
"\u586B\u5199 @BotFather \u751F\u6210\u7684 Bot Token": "Enter the Bot Token from @BotFather",
|
|
1357
1413
|
"\u8BBF\u95EE\u6A21\u5F0F": "Access mode",
|
|
1358
|
-
"\u8BBF\u95EE\u8BBE\u7F6E": "Access settings",
|
|
1359
1414
|
"Telegram \u8BBF\u95EE\u6A21\u5F0F": "Telegram access mode",
|
|
1360
1415
|
"\u67E5\u770B Telegram \u8BBF\u95EE\u6A21\u5F0F\u8BF4\u660E": "View Telegram access mode details",
|
|
1361
1416
|
"\u7FA4\u804A\u5168\u90E8\u5FFD\u7565\uFF0C\u79C1\u804A\u4EC5\u5141\u8BB8\u767D\u540D\u5355\u7528\u6237\u3002": "All group messages are ignored; only allowlisted users may send DMs.",
|
|
@@ -1885,6 +1940,135 @@ function normalizeLastMessageError(value) {
|
|
|
1885
1940
|
return code && reason && message && referenceId && at !== null ? { code, reason, message, referenceId, at } : null;
|
|
1886
1941
|
}
|
|
1887
1942
|
|
|
1943
|
+
// src/channels/shared/access-policy.mjs
|
|
1944
|
+
var ACCESS_POLICY_MODES = Object.freeze(["open", "allowlist"]);
|
|
1945
|
+
var ACCESS_POLICY_CONVERSATION_TYPES = Object.freeze(["direct", "group"]);
|
|
1946
|
+
var ACCESS_POLICY_USER_ID_MAX_LENGTH = 256;
|
|
1947
|
+
var POLICY_KEYS = ["direct", "group"];
|
|
1948
|
+
var SCOPE_KEYS = ["mode", "open", "allowlist"];
|
|
1949
|
+
var OPEN_KEYS = ["defaultCanExecuteCommands", "commandPermissionOverrides"];
|
|
1950
|
+
var ALLOWLIST_KEYS = ["users"];
|
|
1951
|
+
var USER_KEYS = ["id", "canExecuteCommands"];
|
|
1952
|
+
var CONTROL_CHARACTERS = /[\u0000-\u001f\u007f-\u009f\u202a-\u202e\u2066-\u2069]/;
|
|
1953
|
+
function invalidAccessPolicy(message) {
|
|
1954
|
+
const error = new TypeError(message);
|
|
1955
|
+
error.code = "access-policy-invalid";
|
|
1956
|
+
return error;
|
|
1957
|
+
}
|
|
1958
|
+
function hasExactKeys(input, keys) {
|
|
1959
|
+
return input && typeof input === "object" && !Array.isArray(input) && [Object.prototype, null].includes(Object.getPrototypeOf(input)) && Reflect.ownKeys(input).length === keys.length && keys.every((key) => Object.hasOwn(input, key));
|
|
1960
|
+
}
|
|
1961
|
+
function normalizeAccessPolicyUserId(value) {
|
|
1962
|
+
if (typeof value === "number") {
|
|
1963
|
+
if (!Number.isFinite(value)) throw invalidAccessPolicy("\u7528\u6237\u6807\u8BC6\u65E0\u6548\u3002");
|
|
1964
|
+
value = String(value);
|
|
1965
|
+
} else if (typeof value === "bigint") {
|
|
1966
|
+
value = String(value);
|
|
1967
|
+
}
|
|
1968
|
+
if (typeof value !== "string") throw invalidAccessPolicy("\u7528\u6237\u6807\u8BC6\u5FC5\u987B\u662F\u5B57\u7B26\u4E32\u3002");
|
|
1969
|
+
const id5 = value.trim();
|
|
1970
|
+
if (!id5 || id5.length > ACCESS_POLICY_USER_ID_MAX_LENGTH || CONTROL_CHARACTERS.test(id5)) {
|
|
1971
|
+
throw invalidAccessPolicy(`\u7528\u6237\u6807\u8BC6\u4E0D\u80FD\u4E3A\u7A7A\u3001\u5305\u542B\u63A7\u5236\u5B57\u7B26\u6216\u8D85\u8FC7 ${ACCESS_POLICY_USER_ID_MAX_LENGTH} \u4E2A\u5B57\u7B26\u3002`);
|
|
1972
|
+
}
|
|
1973
|
+
return id5;
|
|
1974
|
+
}
|
|
1975
|
+
function validateAccessPolicyUser(input) {
|
|
1976
|
+
if (!hasExactKeys(input, USER_KEYS)) {
|
|
1977
|
+
throw invalidAccessPolicy("\u7528\u6237\u6761\u76EE\u5FC5\u987B\u5305\u542B\u7528\u6237\u6807\u8BC6\u548C\u547D\u4EE4\u6743\u9650\u3002");
|
|
1978
|
+
}
|
|
1979
|
+
if (typeof input.canExecuteCommands !== "boolean") {
|
|
1980
|
+
throw invalidAccessPolicy("\u547D\u4EE4\u6743\u9650\u5FC5\u987B\u662F\u5E03\u5C14\u503C\u3002");
|
|
1981
|
+
}
|
|
1982
|
+
return Object.freeze({
|
|
1983
|
+
id: normalizeAccessPolicyUserId(input.id),
|
|
1984
|
+
canExecuteCommands: input.canExecuteCommands
|
|
1985
|
+
});
|
|
1986
|
+
}
|
|
1987
|
+
function validateUsers(input, { listMessage, duplicateMessage }) {
|
|
1988
|
+
if (!Array.isArray(input)) throw invalidAccessPolicy(listMessage);
|
|
1989
|
+
const users = input.map(validateAccessPolicyUser);
|
|
1990
|
+
if (new Set(users.map(({ id: id5 }) => id5)).size !== users.length) {
|
|
1991
|
+
throw invalidAccessPolicy(duplicateMessage);
|
|
1992
|
+
}
|
|
1993
|
+
return Object.freeze(users);
|
|
1994
|
+
}
|
|
1995
|
+
function validateOpenSettings(input) {
|
|
1996
|
+
if (!hasExactKeys(input, OPEN_KEYS)) {
|
|
1997
|
+
throw invalidAccessPolicy("\u5F00\u653E\u6A21\u5F0F\u8BBE\u7F6E\u5FC5\u987B\u5B8C\u6574\u3002");
|
|
1998
|
+
}
|
|
1999
|
+
if (typeof input.defaultCanExecuteCommands !== "boolean") {
|
|
2000
|
+
throw invalidAccessPolicy("\u5F00\u653E\u6A21\u5F0F\u9ED8\u8BA4\u547D\u4EE4\u6743\u9650\u5FC5\u987B\u662F\u5E03\u5C14\u503C\u3002");
|
|
2001
|
+
}
|
|
2002
|
+
return Object.freeze({
|
|
2003
|
+
defaultCanExecuteCommands: input.defaultCanExecuteCommands,
|
|
2004
|
+
commandPermissionOverrides: validateUsers(input.commandPermissionOverrides, {
|
|
2005
|
+
listMessage: "\u5F00\u653E\u6A21\u5F0F\u547D\u4EE4\u6743\u9650\u8986\u76D6\u7528\u6237\u5FC5\u987B\u662F\u6570\u7EC4\u3002",
|
|
2006
|
+
duplicateMessage: "\u5F00\u653E\u6A21\u5F0F\u547D\u4EE4\u6743\u9650\u8986\u76D6\u7528\u6237\u4E0D\u80FD\u5305\u542B\u91CD\u590D\u7684\u7528\u6237\u6807\u8BC6\u3002"
|
|
2007
|
+
})
|
|
2008
|
+
});
|
|
2009
|
+
}
|
|
2010
|
+
function validateAllowlistSettings(input) {
|
|
2011
|
+
if (!hasExactKeys(input, ALLOWLIST_KEYS)) {
|
|
2012
|
+
throw invalidAccessPolicy("\u767D\u540D\u5355\u6A21\u5F0F\u8BBE\u7F6E\u5FC5\u987B\u5B8C\u6574\u3002");
|
|
2013
|
+
}
|
|
2014
|
+
return Object.freeze({
|
|
2015
|
+
users: validateUsers(input.users, {
|
|
2016
|
+
listMessage: "\u767D\u540D\u5355\u6A21\u5F0F\u7528\u6237\u5FC5\u987B\u662F\u6570\u7EC4\u3002",
|
|
2017
|
+
duplicateMessage: "\u767D\u540D\u5355\u6A21\u5F0F\u7528\u6237\u4E0D\u80FD\u5305\u542B\u91CD\u590D\u7684\u7528\u6237\u6807\u8BC6\u3002"
|
|
2018
|
+
})
|
|
2019
|
+
});
|
|
2020
|
+
}
|
|
2021
|
+
function validateAccessPolicyScope(input) {
|
|
2022
|
+
if (!hasExactKeys(input, SCOPE_KEYS)) {
|
|
2023
|
+
throw invalidAccessPolicy("\u8BBF\u95EE\u573A\u666F\u8BBE\u7F6E\u5FC5\u987B\u540C\u65F6\u5305\u542B\u6A21\u5F0F\u3001\u5F00\u653E\u6A21\u5F0F\u8BBE\u7F6E\u548C\u767D\u540D\u5355\u6A21\u5F0F\u8BBE\u7F6E\u3002");
|
|
2024
|
+
}
|
|
2025
|
+
if (!ACCESS_POLICY_MODES.includes(input.mode)) {
|
|
2026
|
+
throw invalidAccessPolicy("\u8BBF\u95EE\u6A21\u5F0F\u53EA\u80FD\u662F open \u6216 allowlist\u3002");
|
|
2027
|
+
}
|
|
2028
|
+
return Object.freeze({
|
|
2029
|
+
mode: input.mode,
|
|
2030
|
+
open: validateOpenSettings(input.open),
|
|
2031
|
+
allowlist: validateAllowlistSettings(input.allowlist)
|
|
2032
|
+
});
|
|
2033
|
+
}
|
|
2034
|
+
function validateAccessPolicy(input) {
|
|
2035
|
+
if (!hasExactKeys(input, POLICY_KEYS)) {
|
|
2036
|
+
throw invalidAccessPolicy("\u8BF7\u540C\u65F6\u63D0\u4EA4\u5B8C\u6574\u7684\u79C1\u804A\u548C\u7FA4\u804A\u8BBF\u95EE\u8BBE\u7F6E\u3002");
|
|
2037
|
+
}
|
|
2038
|
+
return Object.freeze({
|
|
2039
|
+
direct: validateAccessPolicyScope(input.direct),
|
|
2040
|
+
group: validateAccessPolicyScope(input.group)
|
|
2041
|
+
});
|
|
2042
|
+
}
|
|
2043
|
+
function normalizeAccessPolicy(input) {
|
|
2044
|
+
try {
|
|
2045
|
+
return validateAccessPolicy(input);
|
|
2046
|
+
} catch {
|
|
2047
|
+
return null;
|
|
2048
|
+
}
|
|
2049
|
+
}
|
|
2050
|
+
function createAccessPolicyScope(options) {
|
|
2051
|
+
return validateAccessPolicyScope(options === void 0 ? {
|
|
2052
|
+
mode: "allowlist",
|
|
2053
|
+
open: {
|
|
2054
|
+
defaultCanExecuteCommands: false,
|
|
2055
|
+
commandPermissionOverrides: []
|
|
2056
|
+
},
|
|
2057
|
+
allowlist: { users: [] }
|
|
2058
|
+
} : options);
|
|
2059
|
+
}
|
|
2060
|
+
var DENY_SCOPE = createAccessPolicyScope();
|
|
2061
|
+
var DEFAULT_ACCESS_POLICY = Object.freeze({
|
|
2062
|
+
direct: DENY_SCOPE,
|
|
2063
|
+
group: DENY_SCOPE
|
|
2064
|
+
});
|
|
2065
|
+
var ALLOWED = Object.freeze({ allowed: true, reason: "allowed" });
|
|
2066
|
+
var POLICY_UNAVAILABLE = Object.freeze({ allowed: false, reason: "policy-unavailable" });
|
|
2067
|
+
var INVALID_CONTEXT = Object.freeze({ allowed: false, reason: "invalid-context" });
|
|
2068
|
+
var SENDER_UNAVAILABLE = Object.freeze({ allowed: false, reason: "sender-unavailable" });
|
|
2069
|
+
var SENDER_NOT_ALLOWED = Object.freeze({ allowed: false, reason: "sender-not-allowed" });
|
|
2070
|
+
var COMMAND_NOT_ALLOWED = Object.freeze({ allowed: false, reason: "command-not-allowed" });
|
|
2071
|
+
|
|
1888
2072
|
// src/channels/shared/context-enhancement.mjs
|
|
1889
2073
|
var CONTEXT_ENHANCEMENT_FIELDS = Object.freeze([
|
|
1890
2074
|
"channel",
|
|
@@ -1911,18 +2095,18 @@ var DEFAULT_CONTEXT_ENHANCEMENT_CONFIG = Object.freeze({
|
|
|
1911
2095
|
})
|
|
1912
2096
|
});
|
|
1913
2097
|
var CONFIG_KEYS = ["group", "direct"];
|
|
1914
|
-
var
|
|
2098
|
+
var SCOPE_KEYS2 = ["enabled", "fields", "guidance"];
|
|
1915
2099
|
var LEGACY_CONFIG_KEYS = ["groupEnabled", "directEnabled", "fields", "guidance"];
|
|
1916
2100
|
function invalidConfig(message) {
|
|
1917
2101
|
const error = new TypeError(message);
|
|
1918
2102
|
error.code = "context-enhancement-invalid";
|
|
1919
2103
|
return error;
|
|
1920
2104
|
}
|
|
1921
|
-
function
|
|
2105
|
+
function hasExactKeys2(input, keys) {
|
|
1922
2106
|
return input && typeof input === "object" && !Array.isArray(input) && [Object.prototype, null].includes(Object.getPrototypeOf(input)) && Reflect.ownKeys(input).length === keys.length && keys.every((key) => Object.hasOwn(input, key));
|
|
1923
2107
|
}
|
|
1924
2108
|
function validateContextEnhancementScope(input) {
|
|
1925
|
-
if (!
|
|
2109
|
+
if (!hasExactKeys2(input, SCOPE_KEYS2)) {
|
|
1926
2110
|
throw invalidConfig("\u8BF7\u63D0\u4EA4\u5B8C\u6574\u7684\u4E0A\u4E0B\u6587\u589E\u5F3A\u8BBE\u7F6E\u3002");
|
|
1927
2111
|
}
|
|
1928
2112
|
const { enabled, fields, guidance } = input;
|
|
@@ -1942,7 +2126,7 @@ function validateContextEnhancementScope(input) {
|
|
|
1942
2126
|
});
|
|
1943
2127
|
}
|
|
1944
2128
|
function validateContextEnhancementConfig(input) {
|
|
1945
|
-
if (!
|
|
2129
|
+
if (!hasExactKeys2(input, CONFIG_KEYS)) {
|
|
1946
2130
|
throw invalidConfig("\u8BF7\u63D0\u4EA4\u5B8C\u6574\u7684\u4E0A\u4E0B\u6587\u589E\u5F3A\u8BBE\u7F6E\u3002");
|
|
1947
2131
|
}
|
|
1948
2132
|
return Object.freeze({
|
|
@@ -1951,7 +2135,7 @@ function validateContextEnhancementConfig(input) {
|
|
|
1951
2135
|
});
|
|
1952
2136
|
}
|
|
1953
2137
|
function migrateLegacyContextEnhancementConfig(input) {
|
|
1954
|
-
if (!
|
|
2138
|
+
if (!hasExactKeys2(input, LEGACY_CONFIG_KEYS)) {
|
|
1955
2139
|
throw invalidConfig("\u8BF7\u63D0\u4EA4\u5B8C\u6574\u7684\u4E0A\u4E0B\u6587\u589E\u5F3A\u8BBE\u7F6E\u3002");
|
|
1956
2140
|
}
|
|
1957
2141
|
return validateContextEnhancementConfig({
|
|
@@ -1991,7 +2175,8 @@ var DINGTALK_ENDPOINTS = Object.freeze({
|
|
|
1991
2175
|
deleteBot: "bot.delete",
|
|
1992
2176
|
setWorkspace: "bot.workspace.set",
|
|
1993
2177
|
setAgentPreset: SET_AGENT_PRESET_ENDPOINT,
|
|
1994
|
-
setContextEnhancement: "bot.context-enhancement.set"
|
|
2178
|
+
setContextEnhancement: "bot.context-enhancement.set",
|
|
2179
|
+
setAccessPolicy: "bot.access-policy.set"
|
|
1995
2180
|
});
|
|
1996
2181
|
var ACCOUNT_STATES = /* @__PURE__ */ new Set(["connected", "connecting", "offline", "error"]);
|
|
1997
2182
|
var SNAPSHOT_STATES = /* @__PURE__ */ new Set(["disconnected", "offline", "provisioning", "connected", "degraded"]);
|
|
@@ -2121,6 +2306,7 @@ function normalizeBot(value) {
|
|
|
2121
2306
|
workspace: optionalString(value.workspace, 4096) ?? "",
|
|
2122
2307
|
agentPreset: normalizeAgentPresetId(value.agentPreset),
|
|
2123
2308
|
contextEnhancement: normalizeContextEnhancementConfig(value.contextEnhancement),
|
|
2309
|
+
...Object.hasOwn(value, "accessPolicy") ? { accessPolicy: normalizeAccessPolicy(value.accessPolicy) } : {},
|
|
2124
2310
|
bot: {
|
|
2125
2311
|
name: optionalString(bot.name, 100) ?? "\u9489\u9489\u673A\u5668\u4EBA",
|
|
2126
2312
|
clientIdMasked: optionalString(bot.clientIdMasked, 140) ?? "\u5DF2\u5B89\u5168\u4FDD\u5B58"
|
|
@@ -3230,7 +3416,7 @@ function SettingsGlyph() {
|
|
|
3230
3416
|
h2("path", { d: "M19.4 15a1.7 1.7 0 0 0 .34 1.88l.06.06-2.83 2.83-.06-.06a1.7 1.7 0 0 0-1.88-.34 1.7 1.7 0 0 0-1.03 1.55V21h-4v-.08A1.7 1.7 0 0 0 8.97 19.4a1.7 1.7 0 0 0-1.88.34l-.06.06-2.83-2.83.06-.06A1.7 1.7 0 0 0 4.6 15a1.7 1.7 0 0 0-1.52-1.03H3v-4h.08A1.7 1.7 0 0 0 4.6 8.97a1.7 1.7 0 0 0-.34-1.88l-.06-.06L7.03 4.2l.06.06a1.7 1.7 0 0 0 1.88.34A1.7 1.7 0 0 0 10 3.08V3h4v.08a1.7 1.7 0 0 0 1.03 1.52 1.7 1.7 0 0 0 1.88-.34l.06-.06 2.83 2.83-.06.06a1.7 1.7 0 0 0-.34 1.88A1.7 1.7 0 0 0 20.92 10H21v4h-.08A1.7 1.7 0 0 0 19.4 15Z" })
|
|
3231
3417
|
);
|
|
3232
3418
|
}
|
|
3233
|
-
function BotSettingsButton({ channel: channel4, botId, botName, connected }) {
|
|
3419
|
+
function BotSettingsButton({ channel: channel4, botId, botName, connected, accessPolicy }) {
|
|
3234
3420
|
const { openBotSettings } = React9.useContext(BotSettingsContext);
|
|
3235
3421
|
const tooltipId = React9.useId();
|
|
3236
3422
|
return h2(
|
|
@@ -3246,7 +3432,8 @@ function BotSettingsButton({ channel: channel4, botId, botName, connected }) {
|
|
|
3246
3432
|
channel: channel4,
|
|
3247
3433
|
botId,
|
|
3248
3434
|
botName,
|
|
3249
|
-
connected: Boolean(connected)
|
|
3435
|
+
connected: Boolean(connected),
|
|
3436
|
+
accessPolicy
|
|
3250
3437
|
})
|
|
3251
3438
|
}, h2(SettingsGlyph)),
|
|
3252
3439
|
h2("span", {
|
|
@@ -3809,7 +3996,8 @@ function AccountCard({
|
|
|
3809
3996
|
channel: "dingtalk",
|
|
3810
3997
|
botId: account.botId,
|
|
3811
3998
|
botName: account.bot.name,
|
|
3812
|
-
connected: account.connected
|
|
3999
|
+
connected: account.connected,
|
|
4000
|
+
accessPolicy: account.accessPolicy
|
|
3813
4001
|
})
|
|
3814
4002
|
)
|
|
3815
4003
|
),
|
|
@@ -4464,12 +4652,13 @@ var TOKEN_BOT_ENDPOINTS = Object.freeze({
|
|
|
4464
4652
|
deleteBot: "bot.delete",
|
|
4465
4653
|
setWorkspace: "bot.workspace.set",
|
|
4466
4654
|
setAgentPreset: SET_AGENT_PRESET_ENDPOINT,
|
|
4467
|
-
setContextEnhancement: "bot.context-enhancement.set"
|
|
4655
|
+
setContextEnhancement: "bot.context-enhancement.set",
|
|
4656
|
+
setAccessPolicy: "bot.access-policy.set"
|
|
4468
4657
|
});
|
|
4469
4658
|
function createTokenChannelApi(channel4, connectionSummary, {
|
|
4470
4659
|
normalizeBotExtension = () => ({})
|
|
4471
4660
|
} = {}) {
|
|
4472
|
-
const
|
|
4661
|
+
const unwrapRpcResult12 = (result) => {
|
|
4473
4662
|
if (!isRecord2(result) || typeof result.ok !== "boolean") {
|
|
4474
4663
|
throw new Error(`${channel4} \u670D\u52A1\u8FD4\u56DE\u4E86\u65E0\u6CD5\u8BC6\u522B\u7684\u54CD\u5E94`);
|
|
4475
4664
|
}
|
|
@@ -4492,6 +4681,7 @@ function createTokenChannelApi(channel4, connectionSummary, {
|
|
|
4492
4681
|
workspace: text2(value.workspace, "", 4096),
|
|
4493
4682
|
agentPreset: normalizeAgentPresetId(value.agentPreset),
|
|
4494
4683
|
contextEnhancement: normalizeContextEnhancementConfig(value.contextEnhancement),
|
|
4684
|
+
...Object.hasOwn(value, "accessPolicy") ? { accessPolicy: normalizeAccessPolicy(value.accessPolicy) } : {},
|
|
4495
4685
|
bot: {
|
|
4496
4686
|
name: text2(value.bot?.name, `${channel4}\u673A\u5668\u4EBA`, 100),
|
|
4497
4687
|
username: text2(value.bot?.username, "", 100),
|
|
@@ -4529,7 +4719,7 @@ function createTokenChannelApi(channel4, connectionSummary, {
|
|
|
4529
4719
|
code: text2(error?.code, `${channel4.toUpperCase()}_ERROR`, 80),
|
|
4530
4720
|
message: text2(error?.message, `${channel4}\u64CD\u4F5C\u5931\u8D25\uFF0C\u8BF7\u7A0D\u540E\u91CD\u8BD5`)
|
|
4531
4721
|
});
|
|
4532
|
-
return Object.freeze({ unwrapRpcResult:
|
|
4722
|
+
return Object.freeze({ unwrapRpcResult: unwrapRpcResult12, normalizeSnapshot: normalizeSnapshot9, presentError: presentError12 });
|
|
4533
4723
|
}
|
|
4534
4724
|
|
|
4535
4725
|
// plugin-src/client/channels/discord/api.js
|
|
@@ -4639,7 +4829,8 @@ function createTokenChannelSettings(definition) {
|
|
|
4639
4829
|
channel: channel4.toLowerCase(),
|
|
4640
4830
|
botId: account.botId,
|
|
4641
4831
|
botName: account.bot.name,
|
|
4642
|
-
connected: account.connected
|
|
4832
|
+
connected: account.connected,
|
|
4833
|
+
accessPolicy: account.accessPolicy
|
|
4643
4834
|
})
|
|
4644
4835
|
)
|
|
4645
4836
|
),
|
|
@@ -5075,6 +5266,7 @@ var FEISHU_ENDPOINTS = Object.freeze({
|
|
|
5075
5266
|
setWorkspace: "bot.workspace.set",
|
|
5076
5267
|
setAgentPreset: "bot.preset.set",
|
|
5077
5268
|
setContextEnhancement: "bot.context-enhancement.set",
|
|
5269
|
+
setAccessPolicy: "bot.access-policy.set",
|
|
5078
5270
|
setGroupResponseMode: "bot.group-response-mode.set",
|
|
5079
5271
|
// Kept for rolling upgrades. The multi-bot UI never calls these endpoints.
|
|
5080
5272
|
testConnection: "connection.test",
|
|
@@ -5224,6 +5416,7 @@ function normalizeBotConnection(value, fallbackBotId) {
|
|
|
5224
5416
|
workspace: optionalString2(value.workspace)?.slice(0, 4096) ?? "",
|
|
5225
5417
|
agentPreset: normalizeAgentPresetId(value.agentPreset),
|
|
5226
5418
|
contextEnhancement: normalizeContextEnhancementConfig(value.contextEnhancement),
|
|
5419
|
+
...Object.hasOwn(value, "accessPolicy") ? { accessPolicy: normalizeAccessPolicy(value.accessPolicy) } : {},
|
|
5227
5420
|
groupResponseMode: normalizeGroupResponseMode(value.groupResponseMode),
|
|
5228
5421
|
groupMessagePermissionGranted: value.groupMessagePermissionGranted === true,
|
|
5229
5422
|
bot: normalizeBot2(value.bot),
|
|
@@ -5957,7 +6150,8 @@ function BotCard({
|
|
|
5957
6150
|
channel: "feishu",
|
|
5958
6151
|
botId: connection.botId,
|
|
5959
6152
|
botName: bot.name,
|
|
5960
|
-
connected
|
|
6153
|
+
connected,
|
|
6154
|
+
accessPolicy: connection.accessPolicy
|
|
5961
6155
|
})
|
|
5962
6156
|
)
|
|
5963
6157
|
),
|
|
@@ -7430,7 +7624,8 @@ var QQ_ENDPOINTS = Object.freeze({
|
|
|
7430
7624
|
deleteBot: "bot.delete",
|
|
7431
7625
|
setWorkspace: "bot.workspace.set",
|
|
7432
7626
|
setAgentPreset: SET_AGENT_PRESET_ENDPOINT,
|
|
7433
|
-
setContextEnhancement: "bot.context-enhancement.set"
|
|
7627
|
+
setContextEnhancement: "bot.context-enhancement.set",
|
|
7628
|
+
setAccessPolicy: "bot.access-policy.set"
|
|
7434
7629
|
});
|
|
7435
7630
|
var PROVISION_STATES2 = /* @__PURE__ */ new Set(["starting", "pending", "refreshing", "connecting", "connected", "failed", "cancelled"]);
|
|
7436
7631
|
var ACCOUNT_STATES3 = /* @__PURE__ */ new Set(["connected", "connecting", "offline", "error"]);
|
|
@@ -7496,6 +7691,7 @@ function normalizeBot3(value) {
|
|
|
7496
7691
|
workspace: text3(value.workspace, "", 4096),
|
|
7497
7692
|
agentPreset: normalizeAgentPresetId(value.agentPreset),
|
|
7498
7693
|
contextEnhancement: normalizeContextEnhancementConfig(value.contextEnhancement),
|
|
7694
|
+
...Object.hasOwn(value, "accessPolicy") ? { accessPolicy: normalizeAccessPolicy(value.accessPolicy) } : {},
|
|
7499
7695
|
bot: {
|
|
7500
7696
|
name: text3(value.bot?.name, "QQ\u673A\u5668\u4EBA", 100),
|
|
7501
7697
|
appIdMasked: text3(value.bot?.appIdMasked, "\u5E94\u7528\u6807\u8BC6\u5DF2\u5B89\u5168\u4FDD\u5B58", 140)
|
|
@@ -7836,7 +8032,8 @@ function AccountCard2({
|
|
|
7836
8032
|
channel: "qq",
|
|
7837
8033
|
botId: account.botId,
|
|
7838
8034
|
botName: account.bot.name,
|
|
7839
|
-
connected: account.connected
|
|
8035
|
+
connected: account.connected,
|
|
8036
|
+
accessPolicy: account.accessPolicy
|
|
7840
8037
|
})
|
|
7841
8038
|
)
|
|
7842
8039
|
),
|
|
@@ -8773,59 +8970,18 @@ var SlackAccountCard = channel2.AccountCard;
|
|
|
8773
8970
|
|
|
8774
8971
|
// plugin-src/client/channels/telegram/api.js
|
|
8775
8972
|
var TELEGRAM_RPC_CHANNEL = "/telegram";
|
|
8776
|
-
var TELEGRAM_ENDPOINTS =
|
|
8777
|
-
|
|
8778
|
-
setAccessPolicy: "bot.access-policy.set"
|
|
8779
|
-
});
|
|
8780
|
-
var api3 = createTokenChannelApi("Telegram", " Bot API \u957F\u8F6E\u8BE2", {
|
|
8781
|
-
normalizeBotExtension: (value) => {
|
|
8782
|
-
const source = value?.accessPolicy;
|
|
8783
|
-
const accessMode = source?.accessMode === "private-allowlist" ? "private-allowlist" : "compatible";
|
|
8784
|
-
const allowedUsers = Array.isArray(source?.allowedUsers) ? [...new Set(source.allowedUsers.filter((entry) => typeof entry === "string" && /^[1-9]\d{0,15}$/.test(entry)))] : [];
|
|
8785
|
-
return { accessPolicy: { accessMode, allowedUsers } };
|
|
8786
|
-
}
|
|
8787
|
-
});
|
|
8973
|
+
var TELEGRAM_ENDPOINTS = TOKEN_BOT_ENDPOINTS;
|
|
8974
|
+
var api3 = createTokenChannelApi("Telegram", " Bot API \u957F\u8F6E\u8BE2");
|
|
8788
8975
|
var unwrapRpcResult6 = api3.unwrapRpcResult;
|
|
8789
8976
|
var normalizeSnapshot5 = api3.normalizeSnapshot;
|
|
8790
8977
|
var presentError6 = api3.presentError;
|
|
8791
8978
|
|
|
8792
|
-
// plugin-src/client/channels/telegram/index.js
|
|
8793
|
-
var React17 = __toESM(require("react"), 1);
|
|
8794
|
-
|
|
8795
8979
|
// plugin-src/client/channels/telegram/styles.js
|
|
8796
8980
|
var TELEGRAM_STYLE_ID = "xmanrui-dsh-im-telegram-settings";
|
|
8797
8981
|
var CSS7 = String.raw`
|
|
8798
8982
|
.dtg-page { --ddt-accent: #229ed9; --ddt-accent-deep: #1687bd; --ddt-accent-wash: #eaf7fd; }
|
|
8799
8983
|
.dtg-avatar { color: #fff; background: #229ed9; }
|
|
8800
8984
|
.dtg-avatar svg { display: block; }
|
|
8801
|
-
.dtg-access { min-width: 0; width: 100%; max-width: 100%; display: grid; gap: 10px; padding: 12px; border: 1px solid var(--dsw-alias-border-l2, #dfe1e5); border-radius: 10px; background: var(--dsw-alias-bg-layer-2, #f7f8fa); }
|
|
8802
|
-
.dtg-accessHeading { position: relative; min-width: 0; max-width: 100%; display: flex; align-items: center; justify-content: space-between; flex-wrap: wrap; gap: 8px 12px; }
|
|
8803
|
-
.dtg-accessHeading > strong { min-width: 0; font-size: 13px; overflow-wrap: anywhere; }
|
|
8804
|
-
.dtg-accessStatus { min-width: 0; max-width: 100%; flex: 0 1 auto; display: inline-flex; align-items: center; justify-content: flex-end; flex-wrap: wrap; gap: 6px; }
|
|
8805
|
-
.dtg-accessBadge { min-width: 0; max-width: 100%; flex: 0 1 auto; padding: 3px 8px; border-radius: 999px; color: #1687bd; background: #eaf7fd; font-size: 11px; font-weight: 700; overflow-wrap: anywhere; text-align: center; }
|
|
8806
|
-
.dtg-accessBadge[data-mode="private-allowlist"] { color: #a15c00; background: #fff3d6; }
|
|
8807
|
-
.dtg-accessHelp { position: static; display: inline-flex; flex: none; }
|
|
8808
|
-
.dtg-accessHelpButton { width: 20px; height: 20px; display: grid; place-items: center; padding: 0; border: 1px solid color-mix(in srgb, #229ed9 28%, var(--dsw-alias-border-l2, #dfe1e5)); border-radius: 50%; color: #1687bd; background: var(--dsw-alias-bg-layer-1, #fff); font: inherit; font-size: 12px; line-height: 1; font-weight: 750; cursor: help; transition: border-color .15s ease, color .15s ease, background .15s ease, box-shadow .15s ease; }
|
|
8809
|
-
.dtg-accessHelpButton:hover { border-color: #229ed9; color: #1178a8; background: #eaf7fd; }
|
|
8810
|
-
.dtg-accessHelpButton:focus-visible { outline: none; border-color: #229ed9; box-shadow: 0 0 0 3px color-mix(in srgb, #229ed9 18%, transparent); }
|
|
8811
|
-
.dtg-accessTooltip { position: absolute; top: calc(100% + 8px); right: 0; z-index: 30; width: min(300px, 100%); max-width: 100%; display: grid; gap: 8px; padding: 10px 11px; border: 1px solid var(--dsw-alias-border-l2, #dfe1e5); border-radius: 9px; color: var(--dsw-alias-label-primary, #1f2329); background: var(--dsw-alias-bg-layer-3, #fff); box-shadow: 0 10px 28px rgb(31 35 41 / 16%); opacity: 0; visibility: hidden; transform: translateY(-3px); pointer-events: none; transition: opacity .15s ease, transform .15s ease, visibility .15s ease; }
|
|
8812
|
-
.dtg-accessTooltipItem { display: grid; gap: 2px; }
|
|
8813
|
-
.dtg-accessTooltipItem + .dtg-accessTooltipItem { padding-top: 8px; border-top: 1px solid var(--dsw-alias-border-l2, #eef0f3); }
|
|
8814
|
-
.dtg-accessTooltipItem strong { color: var(--dsw-alias-label-primary, #1f2329); font-size: 12px; line-height: 17px; font-weight: 700; }
|
|
8815
|
-
.dtg-accessTooltipItem > span { color: var(--dsw-alias-label-secondary, #646a73); font-size: 11px; line-height: 16px; font-weight: 400; }
|
|
8816
|
-
.dtg-accessHelp:hover .dtg-accessTooltip, .dtg-accessHelp:focus-within .dtg-accessTooltip { opacity: 1; visibility: visible; transform: translateY(0); }
|
|
8817
|
-
.dtg-accessField { min-width: 0; max-width: 100%; display: grid; gap: 5px; color: var(--dsw-alias-label-primary, #1f2329); font-size: 12px; font-weight: 600; }
|
|
8818
|
-
.dtg-accessField select, .dtg-accessField textarea { min-width: 0; width: 100%; max-width: 100%; box-sizing: border-box; border: 1px solid var(--dsw-alias-border-l1, #c9cdd4); border-radius: 7px; color: inherit; background: var(--dsw-alias-bg-layer-1, #fff); font: inherit; font-weight: 400; }
|
|
8819
|
-
.dtg-accessField select { height: 34px; padding: 0 9px; }
|
|
8820
|
-
.dtg-accessField textarea { min-height: 68px; padding: 8px 9px; resize: vertical; font-family: ui-monospace, SFMono-Regular, Menlo, monospace; }
|
|
8821
|
-
.dtg-accessField textarea:disabled { color: var(--dsw-alias-label-tertiary, #8f959e); background: var(--dsw-alias-bg-module-platform, #f2f3f5); cursor: not-allowed; resize: none; opacity: 1; }
|
|
8822
|
-
.dtg-accessField > span, .dtg-accessField small { overflow-wrap: anywhere; }
|
|
8823
|
-
.dtg-accessField small { color: var(--dsw-alias-label-secondary, #646a73); font-weight: 400; }
|
|
8824
|
-
.dtg-accessWarning, .dtg-accessError { margin: 0; font-size: 12px; line-height: 1.5; }
|
|
8825
|
-
.dtg-accessWarning { color: #a15c00; }
|
|
8826
|
-
.dtg-accessError { color: var(--dsw-alias-state-error-primary, #d83931); }
|
|
8827
|
-
.dtg-accessActions { min-width: 0; max-width: 100%; display: flex; justify-content: flex-end; flex-wrap: wrap; }
|
|
8828
|
-
.dtg-accessActions .ddt-button { max-width: 100%; white-space: normal; }
|
|
8829
8985
|
`;
|
|
8830
8986
|
function installTelegramStyles() {
|
|
8831
8987
|
if (typeof document === "undefined") return () => {
|
|
@@ -8842,146 +8998,6 @@ function installTelegramStyles() {
|
|
|
8842
8998
|
}
|
|
8843
8999
|
|
|
8844
9000
|
// plugin-src/client/channels/telegram/index.js
|
|
8845
|
-
function policyFor(account) {
|
|
8846
|
-
return {
|
|
8847
|
-
accessMode: account?.accessPolicy?.accessMode === "private-allowlist" ? "private-allowlist" : "compatible",
|
|
8848
|
-
allowedUsers: Array.isArray(account?.accessPolicy?.allowedUsers) ? account.accessPolicy.allowedUsers : []
|
|
8849
|
-
};
|
|
8850
|
-
}
|
|
8851
|
-
function allowedUsersFromText(value) {
|
|
8852
|
-
const entries = value.split(/\r?\n/).map((entry) => entry.trim()).filter(Boolean);
|
|
8853
|
-
if (entries.some((entry) => !/^[1-9]\d{0,15}$/.test(entry))) {
|
|
8854
|
-
throw new TypeError("User ID \u5FC5\u987B\u662F 1\u201316 \u4F4D\u6B63\u6574\u6570\uFF0C\u6BCF\u884C\u4E00\u4E2A\u3002");
|
|
8855
|
-
}
|
|
8856
|
-
return [...new Set(entries)];
|
|
8857
|
-
}
|
|
8858
|
-
function TelegramAccessSettings({ account, busy = false, onSave }) {
|
|
8859
|
-
const policy = policyFor(account);
|
|
8860
|
-
const sourceUsers = policy.allowedUsers.join("\n");
|
|
8861
|
-
const accessHelpId = React17.useId();
|
|
8862
|
-
const [accessMode, setAccessMode] = React17.useState(policy.accessMode);
|
|
8863
|
-
const [allowedUsers, setAllowedUsers] = React17.useState(sourceUsers);
|
|
8864
|
-
const [error, setError] = React17.useState(null);
|
|
8865
|
-
React17.useEffect(() => {
|
|
8866
|
-
setAccessMode(policy.accessMode);
|
|
8867
|
-
setAllowedUsers(sourceUsers);
|
|
8868
|
-
setError(null);
|
|
8869
|
-
}, [policy.accessMode, sourceUsers]);
|
|
8870
|
-
const save = async (event) => {
|
|
8871
|
-
event.preventDefault();
|
|
8872
|
-
setError(null);
|
|
8873
|
-
try {
|
|
8874
|
-
const normalized = allowedUsersFromText(allowedUsers);
|
|
8875
|
-
if (typeof onSave !== "function") throw new Error("Telegram \u8BBF\u95EE\u8BBE\u7F6E\u6682\u4E0D\u53EF\u7528\u3002");
|
|
8876
|
-
await onSave({ accessMode, allowedUsers: normalized });
|
|
8877
|
-
} catch (caught) {
|
|
8878
|
-
setError(caught?.message ?? "Telegram \u8BBF\u95EE\u8BBE\u7F6E\u4FDD\u5B58\u5931\u8D25\u3002");
|
|
8879
|
-
}
|
|
8880
|
-
};
|
|
8881
|
-
const privateAllowlist = accessMode === "private-allowlist";
|
|
8882
|
-
const savedPrivateAllowlist = policy.accessMode === "private-allowlist";
|
|
8883
|
-
const emptyAllowlist = privateAllowlist && allowedUsers.trim() === "";
|
|
8884
|
-
return h2(
|
|
8885
|
-
"form",
|
|
8886
|
-
{ className: "dtg-access", onSubmit: save },
|
|
8887
|
-
h2(
|
|
8888
|
-
"div",
|
|
8889
|
-
{ className: "dtg-accessHeading" },
|
|
8890
|
-
h2("strong", null, "\u8BBF\u95EE\u8BBE\u7F6E"),
|
|
8891
|
-
h2(
|
|
8892
|
-
"span",
|
|
8893
|
-
{ className: "dtg-accessStatus" },
|
|
8894
|
-
h2(
|
|
8895
|
-
"span",
|
|
8896
|
-
{ className: "dtg-accessBadge", "data-mode": policy.accessMode },
|
|
8897
|
-
savedPrivateAllowlist ? "\u5DF2\u751F\u6548\uFF1A\u5B89\u5168\u6A21\u5F0F" : "\u5DF2\u751F\u6548\uFF1A\u517C\u5BB9\u6A21\u5F0F"
|
|
8898
|
-
),
|
|
8899
|
-
h2(
|
|
8900
|
-
"span",
|
|
8901
|
-
{ className: "dtg-accessHelp" },
|
|
8902
|
-
h2("button", {
|
|
8903
|
-
type: "button",
|
|
8904
|
-
className: "dtg-accessHelpButton",
|
|
8905
|
-
"aria-label": "\u67E5\u770B Telegram \u8BBF\u95EE\u6A21\u5F0F\u8BF4\u660E",
|
|
8906
|
-
"aria-describedby": accessHelpId
|
|
8907
|
-
}, h2("span", { "aria-hidden": "true" }, "?")),
|
|
8908
|
-
h2(
|
|
8909
|
-
"span",
|
|
8910
|
-
{
|
|
8911
|
-
id: accessHelpId,
|
|
8912
|
-
className: "dtg-accessTooltip",
|
|
8913
|
-
role: "tooltip"
|
|
8914
|
-
},
|
|
8915
|
-
h2(
|
|
8916
|
-
"span",
|
|
8917
|
-
{ className: "dtg-accessTooltipItem" },
|
|
8918
|
-
h2("strong", null, "\u517C\u5BB9\u6A21\u5F0F"),
|
|
8919
|
-
h2("span", null, "\u4FDD\u6301\u539F\u6709\u884C\u4E3A\uFF1A\u79C1\u804A\u76F4\u63A5\u54CD\u5E94\uFF0C\u7FA4\u804A\u5728\u88AB\u63D0\u53CA\u6216\u56DE\u590D\u65F6\u54CD\u5E94\u3002")
|
|
8920
|
-
),
|
|
8921
|
-
h2(
|
|
8922
|
-
"span",
|
|
8923
|
-
{ className: "dtg-accessTooltipItem" },
|
|
8924
|
-
h2("strong", null, "\u5B89\u5168\u6A21\u5F0F"),
|
|
8925
|
-
h2("span", null, "\u7FA4\u804A\u5168\u90E8\u5FFD\u7565\uFF0C\u79C1\u804A\u4EC5\u5141\u8BB8\u767D\u540D\u5355\u7528\u6237\u3002")
|
|
8926
|
-
)
|
|
8927
|
-
)
|
|
8928
|
-
)
|
|
8929
|
-
)
|
|
8930
|
-
),
|
|
8931
|
-
h2(
|
|
8932
|
-
"label",
|
|
8933
|
-
{ className: "dtg-accessField" },
|
|
8934
|
-
h2("span", null, "\u6A21\u5F0F"),
|
|
8935
|
-
h2(
|
|
8936
|
-
"select",
|
|
8937
|
-
{
|
|
8938
|
-
value: accessMode,
|
|
8939
|
-
disabled: busy,
|
|
8940
|
-
"aria-label": "Telegram \u8BBF\u95EE\u6A21\u5F0F",
|
|
8941
|
-
onChange: (event) => {
|
|
8942
|
-
setAccessMode(event.target.value);
|
|
8943
|
-
setError(null);
|
|
8944
|
-
}
|
|
8945
|
-
},
|
|
8946
|
-
h2("option", { value: "compatible" }, "\u517C\u5BB9\u6A21\u5F0F\uFF08\u9ED8\u8BA4\uFF09"),
|
|
8947
|
-
h2("option", { value: "private-allowlist" }, "\u5B89\u5168\u6A21\u5F0F\uFF08\u79C1\u804A\u767D\u540D\u5355\uFF09")
|
|
8948
|
-
)
|
|
8949
|
-
),
|
|
8950
|
-
h2(
|
|
8951
|
-
"label",
|
|
8952
|
-
{ className: "dtg-accessField" },
|
|
8953
|
-
h2("span", null, "\u5141\u8BB8\u79C1\u804A\u7684 Telegram User ID"),
|
|
8954
|
-
h2("textarea", {
|
|
8955
|
-
value: allowedUsers,
|
|
8956
|
-
disabled: busy || !privateAllowlist,
|
|
8957
|
-
rows: 3,
|
|
8958
|
-
placeholder: "\u6BCF\u884C\u4E00\u4E2A\u6570\u5B57 User ID",
|
|
8959
|
-
"aria-label": "\u5141\u8BB8\u79C1\u804A\u7684 Telegram User ID",
|
|
8960
|
-
onChange: (event) => {
|
|
8961
|
-
setAllowedUsers(event.target.value);
|
|
8962
|
-
setError(null);
|
|
8963
|
-
}
|
|
8964
|
-
}),
|
|
8965
|
-
h2("small", null, privateAllowlist ? "\u767D\u540D\u5355\u4EC5\u5C5E\u4E8E\u5F53\u524D\u673A\u5668\u4EBA\u3002" : "\u517C\u5BB9\u6A21\u5F0F\u4E0B\u6682\u4E0D\u4F7F\u7528\u767D\u540D\u5355\uFF0C\u5207\u6362\u6A21\u5F0F\u65F6\u4F1A\u4FDD\u7559\u3002")
|
|
8966
|
-
),
|
|
8967
|
-
emptyAllowlist ? h2(
|
|
8968
|
-
"p",
|
|
8969
|
-
{ className: "dtg-accessWarning", role: "status" },
|
|
8970
|
-
"\u767D\u540D\u5355\u4E3A\u7A7A\uFF1B\u4FDD\u5B58\u540E\u8BE5\u673A\u5668\u4EBA\u4F1A\u62D2\u7EDD\u6240\u6709\u5165\u7AD9\u6D88\u606F\u3002"
|
|
8971
|
-
) : null,
|
|
8972
|
-
error ? h2("p", { className: "dtg-accessError", role: "alert" }, error) : null,
|
|
8973
|
-
h2(
|
|
8974
|
-
"div",
|
|
8975
|
-
{ className: "dtg-accessActions" },
|
|
8976
|
-
h2("button", {
|
|
8977
|
-
type: "submit",
|
|
8978
|
-
className: "ddt-button",
|
|
8979
|
-
"data-kind": "secondary",
|
|
8980
|
-
disabled: busy
|
|
8981
|
-
}, busy ? "\u6B63\u5728\u4FDD\u5B58\u2026" : "\u4FDD\u5B58\u8BBF\u95EE\u8BBE\u7F6E")
|
|
8982
|
-
)
|
|
8983
|
-
);
|
|
8984
|
-
}
|
|
8985
9001
|
var channel3 = createTokenChannelSettings({
|
|
8986
9002
|
channel: "Telegram",
|
|
8987
9003
|
endpoints: TELEGRAM_ENDPOINTS,
|
|
@@ -8994,9 +9010,7 @@ var channel3 = createTokenChannelSettings({
|
|
|
8994
9010
|
tokenPlaceholder: "\u586B\u5199 @BotFather \u751F\u6210\u7684 Bot Token",
|
|
8995
9011
|
emptyTitle: "\u63A5\u5165 Telegram \u673A\u5668\u4EBA",
|
|
8996
9012
|
emptyDescription: "\u5148\u901A\u8FC7 @BotFather \u83B7\u53D6 Bot Token\uFF0C\u518D\u5728\u8FD9\u91CC\u5B8C\u6210\u63A5\u5165\u3002",
|
|
8997
|
-
platformLabel: "Telegram"
|
|
8998
|
-
AccountSettings: TelegramAccessSettings,
|
|
8999
|
-
accountSettingsEndpoint: TELEGRAM_ENDPOINTS.setAccessPolicy
|
|
9013
|
+
platformLabel: "Telegram"
|
|
9000
9014
|
});
|
|
9001
9015
|
var TelegramSettingsTab = channel3.SettingsTab;
|
|
9002
9016
|
var TelegramAccountCard = channel3.AccountCard;
|
|
@@ -9013,7 +9027,8 @@ var WECOM_ENDPOINTS = Object.freeze({
|
|
|
9013
9027
|
deleteBot: "bot.delete",
|
|
9014
9028
|
setWorkspace: "bot.workspace.set",
|
|
9015
9029
|
setAgentPreset: SET_AGENT_PRESET_ENDPOINT,
|
|
9016
|
-
setContextEnhancement: "bot.context-enhancement.set"
|
|
9030
|
+
setContextEnhancement: "bot.context-enhancement.set",
|
|
9031
|
+
setAccessPolicy: "bot.access-policy.set"
|
|
9017
9032
|
});
|
|
9018
9033
|
var PROVISION_STATES3 = /* @__PURE__ */ new Set(["starting", "pending", "refreshing", "connecting", "connected", "failed", "cancelled"]);
|
|
9019
9034
|
var ACCOUNT_STATES4 = /* @__PURE__ */ new Set(["connected", "connecting", "offline", "error"]);
|
|
@@ -9085,6 +9100,7 @@ function normalizeBot4(value) {
|
|
|
9085
9100
|
workspace: text4(value.workspace, "", 4096),
|
|
9086
9101
|
agentPreset: normalizeAgentPresetId(value.agentPreset),
|
|
9087
9102
|
contextEnhancement: normalizeContextEnhancementConfig(value.contextEnhancement),
|
|
9103
|
+
...Object.hasOwn(value, "accessPolicy") ? { accessPolicy: normalizeAccessPolicy(value.accessPolicy) } : {},
|
|
9088
9104
|
bot: {
|
|
9089
9105
|
name: text4(value.bot?.name, "\u4F01\u4E1A\u5FAE\u4FE1\u673A\u5668\u4EBA", 100),
|
|
9090
9106
|
appIdMasked: text4(value.bot?.appIdMasked, "\u5E94\u7528\u6807\u8BC6\u5DF2\u5B89\u5168\u4FDD\u5B58", 140)
|
|
@@ -9125,7 +9141,7 @@ function formatRemaining4(milliseconds) {
|
|
|
9125
9141
|
}
|
|
9126
9142
|
|
|
9127
9143
|
// plugin-src/client/channels/wecom/index.js
|
|
9128
|
-
var
|
|
9144
|
+
var React17 = __toESM(require("react"), 1);
|
|
9129
9145
|
|
|
9130
9146
|
// plugin-src/client/channels/wecom/styles.js
|
|
9131
9147
|
var WECOM_STYLE_ID = "xmanrui-dsh-im-wecom-settings";
|
|
@@ -9150,7 +9166,7 @@ function installWecomStyles() {
|
|
|
9150
9166
|
|
|
9151
9167
|
// plugin-src/client/channels/wecom/index.js
|
|
9152
9168
|
var ACTIVE_STATES2 = /* @__PURE__ */ new Set(["pending", "refreshing", "connecting"]);
|
|
9153
|
-
var Button10 =
|
|
9169
|
+
var Button10 = React17.forwardRef(function Button11({ children, kind = "secondary", className = "", ...props }, ref) {
|
|
9154
9170
|
return h2("button", {
|
|
9155
9171
|
...props,
|
|
9156
9172
|
ref,
|
|
@@ -9408,7 +9424,8 @@ function AccountCard3({
|
|
|
9408
9424
|
channel: "wecom",
|
|
9409
9425
|
botId: account.botId,
|
|
9410
9426
|
botName: account.bot.name,
|
|
9411
|
-
connected: account.connected
|
|
9427
|
+
connected: account.connected,
|
|
9428
|
+
accessPolicy: account.accessPolicy
|
|
9412
9429
|
})
|
|
9413
9430
|
)
|
|
9414
9431
|
),
|
|
@@ -9461,27 +9478,27 @@ function AccountCard3({
|
|
|
9461
9478
|
);
|
|
9462
9479
|
}
|
|
9463
9480
|
function WecomSettingsTab({ rpcCall }) {
|
|
9464
|
-
const [model, setModel] =
|
|
9481
|
+
const [model, setModel] = React17.useState({
|
|
9465
9482
|
phase: "loading",
|
|
9466
9483
|
bots: [],
|
|
9467
9484
|
totals: { configured: 0, connected: 0 },
|
|
9468
9485
|
error: null,
|
|
9469
9486
|
agentPresetCatalog: EMPTY_AGENT_PRESET_CATALOG
|
|
9470
9487
|
});
|
|
9471
|
-
const [provision, setProvision] =
|
|
9472
|
-
const [busy, setBusy] =
|
|
9473
|
-
const [busyByBot, setBusyByBot] =
|
|
9474
|
-
const [feedbackByBot, setFeedbackByBot] =
|
|
9475
|
-
const [removeTarget, setRemoveTarget] =
|
|
9476
|
-
const [credentialOpen, setCredentialOpen] =
|
|
9477
|
-
const [credentialError, setCredentialError] =
|
|
9478
|
-
const [notice, setNotice] =
|
|
9479
|
-
const [now, setNow] =
|
|
9480
|
-
const mounted =
|
|
9488
|
+
const [provision, setProvision] = React17.useState(null);
|
|
9489
|
+
const [busy, setBusy] = React17.useState(false);
|
|
9490
|
+
const [busyByBot, setBusyByBot] = React17.useState({});
|
|
9491
|
+
const [feedbackByBot, setFeedbackByBot] = React17.useState({});
|
|
9492
|
+
const [removeTarget, setRemoveTarget] = React17.useState(null);
|
|
9493
|
+
const [credentialOpen, setCredentialOpen] = React17.useState(false);
|
|
9494
|
+
const [credentialError, setCredentialError] = React17.useState(null);
|
|
9495
|
+
const [notice, setNotice] = React17.useState("");
|
|
9496
|
+
const [now, setNow] = React17.useState(Date.now());
|
|
9497
|
+
const mounted = React17.useRef(true);
|
|
9481
9498
|
const workspaceFence = useWorkspaceSnapshotFence();
|
|
9482
|
-
const addButtonRef =
|
|
9483
|
-
const noticeFrameRef =
|
|
9484
|
-
const announce =
|
|
9499
|
+
const addButtonRef = React17.useRef(null);
|
|
9500
|
+
const noticeFrameRef = React17.useRef(null);
|
|
9501
|
+
const announce = React17.useCallback((message) => {
|
|
9485
9502
|
if (!mounted.current) return;
|
|
9486
9503
|
if (noticeFrameRef.current !== null) {
|
|
9487
9504
|
window.cancelAnimationFrame(noticeFrameRef.current);
|
|
@@ -9495,7 +9512,7 @@ function WecomSettingsTab({ rpcCall }) {
|
|
|
9495
9512
|
});
|
|
9496
9513
|
}
|
|
9497
9514
|
}, []);
|
|
9498
|
-
|
|
9515
|
+
React17.useEffect(() => {
|
|
9499
9516
|
const disposeDingtalk = installDingtalkStyles();
|
|
9500
9517
|
const disposeWecom = installWecomStyles();
|
|
9501
9518
|
mounted.current = true;
|
|
@@ -9509,11 +9526,11 @@ function WecomSettingsTab({ rpcCall }) {
|
|
|
9509
9526
|
disposeDingtalk();
|
|
9510
9527
|
};
|
|
9511
9528
|
}, []);
|
|
9512
|
-
const invoke =
|
|
9529
|
+
const invoke = React17.useCallback(async (endpoint, payload = {}, signal) => {
|
|
9513
9530
|
if (typeof rpcCall !== "function") throw new TypeError("\u4F01\u4E1A\u5FAE\u4FE1\u8BBE\u7F6E\u9875\u7F3A\u5C11 RPC \u8FDE\u63A5");
|
|
9514
9531
|
return unwrapRpcResult7(await rpcCall(endpoint, payload, signal));
|
|
9515
9532
|
}, [rpcCall]);
|
|
9516
|
-
const loadStatus =
|
|
9533
|
+
const loadStatus = React17.useCallback(async ({ signal, silent = false, restore = false } = {}) => {
|
|
9517
9534
|
const workspaceVersion = workspaceFence.beginStatus();
|
|
9518
9535
|
if (workspaceVersion === null) return void 0;
|
|
9519
9536
|
if (!silent && mounted.current) setModel((current) => ({ ...current, phase: "loading", error: null }));
|
|
@@ -9539,12 +9556,12 @@ function WecomSettingsTab({ rpcCall }) {
|
|
|
9539
9556
|
return void 0;
|
|
9540
9557
|
}
|
|
9541
9558
|
}, [invoke, workspaceFence]);
|
|
9542
|
-
|
|
9559
|
+
React17.useEffect(() => {
|
|
9543
9560
|
const controller = new AbortController();
|
|
9544
9561
|
void loadStatus({ signal: controller.signal, restore: true });
|
|
9545
9562
|
return () => controller.abort();
|
|
9546
9563
|
}, [loadStatus]);
|
|
9547
|
-
|
|
9564
|
+
React17.useEffect(() => {
|
|
9548
9565
|
if (model.phase !== "ready") return void 0;
|
|
9549
9566
|
const controller = new AbortController();
|
|
9550
9567
|
const timer = window.setInterval(() => void loadStatus({ signal: controller.signal, silent: true }), 15e3);
|
|
@@ -9553,12 +9570,12 @@ function WecomSettingsTab({ rpcCall }) {
|
|
|
9553
9570
|
window.clearInterval(timer);
|
|
9554
9571
|
};
|
|
9555
9572
|
}, [loadStatus, model.phase]);
|
|
9556
|
-
|
|
9573
|
+
React17.useEffect(() => {
|
|
9557
9574
|
if (!provision || !ACTIVE_STATES2.has(provision.status)) return void 0;
|
|
9558
9575
|
const timer = window.setInterval(() => mounted.current && setNow(Date.now()), 1e3);
|
|
9559
9576
|
return () => window.clearInterval(timer);
|
|
9560
9577
|
}, [provision?.attemptId, provision?.status]);
|
|
9561
|
-
const startProvisioning =
|
|
9578
|
+
const startProvisioning = React17.useCallback(async (replace = false) => {
|
|
9562
9579
|
setCredentialOpen(false);
|
|
9563
9580
|
setCredentialError(null);
|
|
9564
9581
|
setBusy(true);
|
|
@@ -9576,7 +9593,7 @@ function WecomSettingsTab({ rpcCall }) {
|
|
|
9576
9593
|
if (mounted.current) setBusy(false);
|
|
9577
9594
|
}
|
|
9578
9595
|
}, [invoke, provision?.attemptId]);
|
|
9579
|
-
const bindCredentials =
|
|
9596
|
+
const bindCredentials = React17.useCallback(async ({ identity, secret }) => {
|
|
9580
9597
|
const snapshotVersion = workspaceFence.beginMutation();
|
|
9581
9598
|
setBusy(true);
|
|
9582
9599
|
setCredentialError(null);
|
|
@@ -9604,7 +9621,7 @@ function WecomSettingsTab({ rpcCall }) {
|
|
|
9604
9621
|
if (mounted.current) setBusy(false);
|
|
9605
9622
|
}
|
|
9606
9623
|
}, [invoke, loadStatus, workspaceFence]);
|
|
9607
|
-
const closeProvision =
|
|
9624
|
+
const closeProvision = React17.useCallback(async () => {
|
|
9608
9625
|
setBusy(true);
|
|
9609
9626
|
try {
|
|
9610
9627
|
if (provision?.attemptId && ACTIVE_STATES2.has(provision.status)) {
|
|
@@ -9615,7 +9632,7 @@ function WecomSettingsTab({ rpcCall }) {
|
|
|
9615
9632
|
if (mounted.current) setBusy(false);
|
|
9616
9633
|
}
|
|
9617
9634
|
}, [invoke, provision?.attemptId, provision?.status]);
|
|
9618
|
-
|
|
9635
|
+
React17.useEffect(() => {
|
|
9619
9636
|
const attemptId = provision?.attemptId;
|
|
9620
9637
|
if (!attemptId || !ACTIVE_STATES2.has(provision.status)) return void 0;
|
|
9621
9638
|
const controller = new AbortController();
|
|
@@ -9645,7 +9662,7 @@ function WecomSettingsTab({ rpcCall }) {
|
|
|
9645
9662
|
window.clearTimeout(timer);
|
|
9646
9663
|
};
|
|
9647
9664
|
}, [invoke, loadStatus, provision?.attemptId, provision?.pollIntervalMs, provision?.status]);
|
|
9648
|
-
const botAction =
|
|
9665
|
+
const botAction = React17.useCallback(async (account, operation, endpoint, payload) => {
|
|
9649
9666
|
const snapshotVersion = workspaceFence.beginMutation();
|
|
9650
9667
|
setBusyByBot((current) => ({ ...current, [account.botId]: operation }));
|
|
9651
9668
|
try {
|
|
@@ -9670,7 +9687,7 @@ function WecomSettingsTab({ rpcCall }) {
|
|
|
9670
9687
|
});
|
|
9671
9688
|
}
|
|
9672
9689
|
}, [invoke, loadStatus, workspaceFence]);
|
|
9673
|
-
const reconnect =
|
|
9690
|
+
const reconnect = React17.useCallback(async (account) => {
|
|
9674
9691
|
setFeedbackByBot((current) => {
|
|
9675
9692
|
const next = { ...current };
|
|
9676
9693
|
delete next[account.botId];
|
|
@@ -9797,7 +9814,7 @@ function WecomSettingsTab({ rpcCall }) {
|
|
|
9797
9814
|
}),
|
|
9798
9815
|
h2("div", { className: "ddt-visuallyHidden", role: "status", "aria-live": "polite" }, notice),
|
|
9799
9816
|
model.phase === "loading" ? h2(LoadingView4) : model.phase === "error" ? h2("div", { className: "ddt-card dim-surfaceCard" }, h2("div", { className: "ddt-inlineError dim-inlineError" }, h2("h3", null, "\u65E0\u6CD5\u8BFB\u53D6\u4F01\u4E1A\u5FAE\u4FE1\u673A\u5668\u4EBA\u72B6\u6001"), h2("p", null, model.error?.message), h2(Button10, { onClick: () => void loadStatus() }, "\u91CD\u65B0\u8BFB\u53D6"))) : h2(
|
|
9800
|
-
|
|
9817
|
+
React17.Fragment,
|
|
9801
9818
|
null,
|
|
9802
9819
|
credentialView,
|
|
9803
9820
|
provisionView,
|
|
@@ -9808,7 +9825,7 @@ function WecomSettingsTab({ rpcCall }) {
|
|
|
9808
9825
|
}
|
|
9809
9826
|
|
|
9810
9827
|
// plugin-src/client/channels/weixin/index.js
|
|
9811
|
-
var
|
|
9828
|
+
var React18 = __toESM(require("react"), 1);
|
|
9812
9829
|
|
|
9813
9830
|
// plugin-src/client/channels/weixin/api.js
|
|
9814
9831
|
var WEIXIN_RPC_CHANNEL = "/weixin";
|
|
@@ -9822,7 +9839,8 @@ var WEIXIN_ENDPOINTS = Object.freeze({
|
|
|
9822
9839
|
deleteBot: "bot.delete",
|
|
9823
9840
|
setWorkspace: "bot.workspace.set",
|
|
9824
9841
|
setAgentPreset: SET_AGENT_PRESET_ENDPOINT,
|
|
9825
|
-
setContextEnhancement: "bot.context-enhancement.set"
|
|
9842
|
+
setContextEnhancement: "bot.context-enhancement.set",
|
|
9843
|
+
setAccessPolicy: "bot.access-policy.set"
|
|
9826
9844
|
});
|
|
9827
9845
|
var ACCOUNT_STATES5 = /* @__PURE__ */ new Set(["connected", "connecting", "offline", "error"]);
|
|
9828
9846
|
var PROVISION_STATES4 = /* @__PURE__ */ new Set([
|
|
@@ -9914,6 +9932,7 @@ function normalizeBot5(value) {
|
|
|
9914
9932
|
workspace: string(value.workspace).slice(0, 4096),
|
|
9915
9933
|
agentPreset: normalizeAgentPresetId(value.agentPreset),
|
|
9916
9934
|
contextEnhancement: normalizeContextEnhancementConfig(value.contextEnhancement),
|
|
9935
|
+
...Object.hasOwn(value, "accessPolicy") ? { accessPolicy: normalizeAccessPolicy(value.accessPolicy) } : {},
|
|
9917
9936
|
bot: {
|
|
9918
9937
|
name: string(value.bot.name, "\u5FAE\u4FE1\u673A\u5668\u4EBA"),
|
|
9919
9938
|
accountIdMasked: string(value.bot.accountIdMasked, "\u5DF2\u5B89\u5168\u4FDD\u5B58")
|
|
@@ -9965,7 +9984,7 @@ function formatRemaining5(milliseconds) {
|
|
|
9965
9984
|
}
|
|
9966
9985
|
|
|
9967
9986
|
// plugin-src/client/channels/weixin/index.js
|
|
9968
|
-
var Button12 =
|
|
9987
|
+
var Button12 = React18.forwardRef(function Button13({ children, kind = "secondary", className = "", ...props }, ref) {
|
|
9969
9988
|
return h2("button", {
|
|
9970
9989
|
...props,
|
|
9971
9990
|
ref,
|
|
@@ -10038,14 +10057,14 @@ function EmptyView5({ onStart, busy }) {
|
|
|
10038
10057
|
);
|
|
10039
10058
|
}
|
|
10040
10059
|
function QrPanel4({ provision, now, busy, onRefresh, onCancel }) {
|
|
10041
|
-
const [imageFailed, setImageFailed] =
|
|
10060
|
+
const [imageFailed, setImageFailed] = React18.useState(false);
|
|
10042
10061
|
const source = safeQrSource5(provision.qrCodeDataUrl);
|
|
10043
10062
|
const href = safeVerificationUrl(provision.verificationUrl);
|
|
10044
10063
|
const remaining = Math.max(0, provision.expiresAt - now);
|
|
10045
10064
|
const expired = remaining === 0 || provision.status === "expired";
|
|
10046
10065
|
const duration = Math.max(1, provision.durationMs ?? 5 * 6e4);
|
|
10047
10066
|
const progress = Math.round(Math.min(1, remaining / duration) * 100);
|
|
10048
|
-
|
|
10067
|
+
React18.useEffect(() => setImageFailed(false), [source]);
|
|
10049
10068
|
return h2(
|
|
10050
10069
|
"div",
|
|
10051
10070
|
{ className: "dxw-card dim-surfaceCard" },
|
|
@@ -10112,9 +10131,9 @@ function QrPanel4({ provision, now, busy, onRefresh, onCancel }) {
|
|
|
10112
10131
|
);
|
|
10113
10132
|
}
|
|
10114
10133
|
function VerificationPanel({ provision, busy, onSubmit, onCancel }) {
|
|
10115
|
-
const [code, setCode] =
|
|
10134
|
+
const [code, setCode] = React18.useState("");
|
|
10116
10135
|
const valid = /^\d{4,8}$/.test(code);
|
|
10117
|
-
|
|
10136
|
+
React18.useEffect(() => setCode(""), [provision.attemptId]);
|
|
10118
10137
|
return h2(
|
|
10119
10138
|
"div",
|
|
10120
10139
|
{ className: "dxw-card dim-surfaceCard" },
|
|
@@ -10251,7 +10270,8 @@ function AccountCard4({
|
|
|
10251
10270
|
channel: "weixin",
|
|
10252
10271
|
botId: account.botId,
|
|
10253
10272
|
botName: account.bot.name,
|
|
10254
|
-
connected: account.connected
|
|
10273
|
+
connected: account.connected,
|
|
10274
|
+
accessPolicy: account.accessPolicy
|
|
10255
10275
|
})
|
|
10256
10276
|
)
|
|
10257
10277
|
),
|
|
@@ -10357,7 +10377,7 @@ function mergeWeixinProvisioningSnapshot(current, incoming, { restoreProvisionin
|
|
|
10357
10377
|
};
|
|
10358
10378
|
}
|
|
10359
10379
|
function WeixinSettingsTab({ rpcCall }) {
|
|
10360
|
-
const [model, setModel] =
|
|
10380
|
+
const [model, setModel] = React18.useState({
|
|
10361
10381
|
phase: "loading",
|
|
10362
10382
|
bots: [],
|
|
10363
10383
|
totals: EMPTY_TOTALS3,
|
|
@@ -10365,33 +10385,33 @@ function WeixinSettingsTab({ rpcCall }) {
|
|
|
10365
10385
|
error: null,
|
|
10366
10386
|
agentPresetCatalog: EMPTY_AGENT_PRESET_CATALOG
|
|
10367
10387
|
});
|
|
10368
|
-
const [provision, setProvision] =
|
|
10369
|
-
const [busy, setBusy] =
|
|
10370
|
-
const [busyByBot, setBusyByBot] =
|
|
10371
|
-
const [feedbackByBot, setFeedbackByBot] =
|
|
10372
|
-
const [removeTarget, setRemoveTarget] =
|
|
10373
|
-
const [notice, setNotice] =
|
|
10374
|
-
const [now, setNow] =
|
|
10375
|
-
const addButtonRef =
|
|
10376
|
-
const mountedRef =
|
|
10388
|
+
const [provision, setProvision] = React18.useState(null);
|
|
10389
|
+
const [busy, setBusy] = React18.useState(false);
|
|
10390
|
+
const [busyByBot, setBusyByBot] = React18.useState({});
|
|
10391
|
+
const [feedbackByBot, setFeedbackByBot] = React18.useState({});
|
|
10392
|
+
const [removeTarget, setRemoveTarget] = React18.useState(null);
|
|
10393
|
+
const [notice, setNotice] = React18.useState("");
|
|
10394
|
+
const [now, setNow] = React18.useState(() => Date.now());
|
|
10395
|
+
const addButtonRef = React18.useRef(null);
|
|
10396
|
+
const mountedRef = React18.useRef(true);
|
|
10377
10397
|
const workspaceFence = useWorkspaceSnapshotFence();
|
|
10378
10398
|
const scheduleAnimationFrame = useAnimationFrameScheduler();
|
|
10379
|
-
|
|
10399
|
+
React18.useEffect(() => {
|
|
10380
10400
|
mountedRef.current = true;
|
|
10381
10401
|
return () => {
|
|
10382
10402
|
mountedRef.current = false;
|
|
10383
10403
|
};
|
|
10384
10404
|
}, []);
|
|
10385
|
-
const announce =
|
|
10405
|
+
const announce = React18.useCallback((value) => {
|
|
10386
10406
|
setNotice("");
|
|
10387
10407
|
scheduleAnimationFrame(() => {
|
|
10388
10408
|
if (value) setNotice(value);
|
|
10389
10409
|
}, "announcement");
|
|
10390
10410
|
}, [scheduleAnimationFrame]);
|
|
10391
|
-
const invoke =
|
|
10411
|
+
const invoke = React18.useCallback(async (endpoint, payload = {}, signal) => {
|
|
10392
10412
|
return unwrapRpcResult8(await rpcCall(endpoint, payload, signal));
|
|
10393
10413
|
}, [rpcCall]);
|
|
10394
|
-
const loadStatus =
|
|
10414
|
+
const loadStatus = React18.useCallback(async ({
|
|
10395
10415
|
signal,
|
|
10396
10416
|
silent = false,
|
|
10397
10417
|
restoreProvisioning = false
|
|
@@ -10428,12 +10448,12 @@ function WeixinSettingsTab({ rpcCall }) {
|
|
|
10428
10448
|
return void 0;
|
|
10429
10449
|
}
|
|
10430
10450
|
}, [invoke, workspaceFence]);
|
|
10431
|
-
|
|
10451
|
+
React18.useEffect(() => {
|
|
10432
10452
|
const controller = new AbortController();
|
|
10433
10453
|
void loadStatus({ signal: controller.signal, restoreProvisioning: true });
|
|
10434
10454
|
return () => controller.abort();
|
|
10435
10455
|
}, [loadStatus]);
|
|
10436
|
-
|
|
10456
|
+
React18.useEffect(() => {
|
|
10437
10457
|
if (model.phase !== "ready") return void 0;
|
|
10438
10458
|
const controller = new AbortController();
|
|
10439
10459
|
let running = false;
|
|
@@ -10452,12 +10472,12 @@ function WeixinSettingsTab({ rpcCall }) {
|
|
|
10452
10472
|
window.clearInterval(timer);
|
|
10453
10473
|
};
|
|
10454
10474
|
}, [loadStatus, model.phase]);
|
|
10455
|
-
|
|
10475
|
+
React18.useEffect(() => {
|
|
10456
10476
|
if (!provision || !["pending", "scanned"].includes(provision.status)) return void 0;
|
|
10457
10477
|
const timer = window.setInterval(() => setNow(Date.now()), 1e3);
|
|
10458
10478
|
return () => window.clearInterval(timer);
|
|
10459
10479
|
}, [provision?.attemptId, provision?.status]);
|
|
10460
|
-
const startProvisioning =
|
|
10480
|
+
const startProvisioning = React18.useCallback(async ({ replace = false } = {}) => {
|
|
10461
10481
|
setBusy(true);
|
|
10462
10482
|
try {
|
|
10463
10483
|
if (replace && provision?.attemptId) {
|
|
@@ -10478,7 +10498,7 @@ function WeixinSettingsTab({ rpcCall }) {
|
|
|
10478
10498
|
setBusy(false);
|
|
10479
10499
|
}
|
|
10480
10500
|
}, [announce, invoke, provision?.attemptId]);
|
|
10481
|
-
const cancelProvisioning =
|
|
10501
|
+
const cancelProvisioning = React18.useCallback(async () => {
|
|
10482
10502
|
setBusy(true);
|
|
10483
10503
|
try {
|
|
10484
10504
|
if (provision?.attemptId && !["failed", "expired", "cancelled"].includes(provision.status)) {
|
|
@@ -10493,7 +10513,7 @@ function WeixinSettingsTab({ rpcCall }) {
|
|
|
10493
10513
|
setBusy(false);
|
|
10494
10514
|
}
|
|
10495
10515
|
}, [announce, invoke, provision?.attemptId, provision?.status, scheduleAnimationFrame]);
|
|
10496
|
-
const submitVerification =
|
|
10516
|
+
const submitVerification = React18.useCallback(async (verifyCode) => {
|
|
10497
10517
|
if (!provision?.attemptId) return;
|
|
10498
10518
|
setBusy(true);
|
|
10499
10519
|
try {
|
|
@@ -10509,7 +10529,7 @@ function WeixinSettingsTab({ rpcCall }) {
|
|
|
10509
10529
|
setBusy(false);
|
|
10510
10530
|
}
|
|
10511
10531
|
}, [announce, invoke, provision?.attemptId]);
|
|
10512
|
-
|
|
10532
|
+
React18.useEffect(() => {
|
|
10513
10533
|
const attemptId = provision?.attemptId;
|
|
10514
10534
|
if (!attemptId || !["pending", "scanned", "connecting"].includes(provision.status)) return void 0;
|
|
10515
10535
|
const controller = new AbortController();
|
|
@@ -10557,7 +10577,7 @@ function WeixinSettingsTab({ rpcCall }) {
|
|
|
10557
10577
|
controller.abort();
|
|
10558
10578
|
};
|
|
10559
10579
|
}, [announce, invoke, loadStatus, provision?.attemptId, provision?.status, provision?.pollIntervalMs]);
|
|
10560
|
-
const setBotBusy =
|
|
10580
|
+
const setBotBusy = React18.useCallback((botId, value) => {
|
|
10561
10581
|
setBusyByBot((current) => {
|
|
10562
10582
|
const next = { ...current };
|
|
10563
10583
|
if (value) next[botId] = value;
|
|
@@ -10565,7 +10585,7 @@ function WeixinSettingsTab({ rpcCall }) {
|
|
|
10565
10585
|
return next;
|
|
10566
10586
|
});
|
|
10567
10587
|
}, []);
|
|
10568
|
-
const reconnect =
|
|
10588
|
+
const reconnect = React18.useCallback(async (account) => {
|
|
10569
10589
|
const snapshotVersion = workspaceFence.beginMutation();
|
|
10570
10590
|
setBotBusy(account.botId, "reconnect");
|
|
10571
10591
|
setFeedbackByBot((current) => {
|
|
@@ -10616,7 +10636,7 @@ function WeixinSettingsTab({ rpcCall }) {
|
|
|
10616
10636
|
setBotBusy(account.botId, null);
|
|
10617
10637
|
}
|
|
10618
10638
|
}, [announce, invoke, loadStatus, setBotBusy, workspaceFence]);
|
|
10619
|
-
const saveWorkspace =
|
|
10639
|
+
const saveWorkspace = React18.useCallback(async (account, workspace) => {
|
|
10620
10640
|
const workspaceVersion = workspaceFence.beginMutation();
|
|
10621
10641
|
setBotBusy(account.botId, "workspace");
|
|
10622
10642
|
try {
|
|
@@ -10640,7 +10660,7 @@ function WeixinSettingsTab({ rpcCall }) {
|
|
|
10640
10660
|
if (mountedRef.current) setBotBusy(account.botId, null);
|
|
10641
10661
|
}
|
|
10642
10662
|
}, [invoke, loadStatus, setBotBusy, workspaceFence]);
|
|
10643
|
-
const saveBotSetting =
|
|
10663
|
+
const saveBotSetting = React18.useCallback(async (account, operation, endpoint, payload) => {
|
|
10644
10664
|
const snapshotVersion = workspaceFence.beginMutation();
|
|
10645
10665
|
setBotBusy(account.botId, operation);
|
|
10646
10666
|
try {
|
|
@@ -10664,7 +10684,7 @@ function WeixinSettingsTab({ rpcCall }) {
|
|
|
10664
10684
|
if (mountedRef.current) setBotBusy(account.botId, null);
|
|
10665
10685
|
}
|
|
10666
10686
|
}, [invoke, loadStatus, setBotBusy, workspaceFence]);
|
|
10667
|
-
const remove =
|
|
10687
|
+
const remove = React18.useCallback(async (account) => {
|
|
10668
10688
|
const snapshotVersion = workspaceFence.beginMutation();
|
|
10669
10689
|
setBotBusy(account.botId, "delete");
|
|
10670
10690
|
try {
|
|
@@ -10748,7 +10768,7 @@ function WeixinSettingsTab({ rpcCall }) {
|
|
|
10748
10768
|
h2(Button12, { onClick: () => void loadStatus() }, "\u91CD\u65B0\u8BFB\u53D6")
|
|
10749
10769
|
)
|
|
10750
10770
|
) : h2(
|
|
10751
|
-
|
|
10771
|
+
React18.Fragment,
|
|
10752
10772
|
null,
|
|
10753
10773
|
provisionView,
|
|
10754
10774
|
model.bots.length === 0 && !provision ? h2(EmptyView5, { onStart: () => void startProvisioning(), busy }) : null,
|
|
@@ -10975,12 +10995,7 @@ function normalizeBot6(value) {
|
|
|
10975
10995
|
workspace: text5(value.workspace, "", 4096),
|
|
10976
10996
|
agentPreset: normalizeAgentPresetId(value.agentPreset),
|
|
10977
10997
|
contextEnhancement: normalizeContextEnhancementConfig(value.contextEnhancement),
|
|
10978
|
-
accessPolicy: {
|
|
10979
|
-
accessMode: ["self-only", "private-allowlist", "open"].includes(
|
|
10980
|
-
value.accessPolicy?.accessMode
|
|
10981
|
-
) ? value.accessPolicy.accessMode : "self-only",
|
|
10982
|
-
allowedNumbers: Array.isArray(value.accessPolicy?.allowedNumbers) ? [...new Set(value.accessPolicy.allowedNumbers.filter((entry) => typeof entry === "string" && /^[1-9]\d{4,14}$/.test(entry)))] : []
|
|
10983
|
-
},
|
|
10998
|
+
...Object.hasOwn(value, "accessPolicy") ? { accessPolicy: normalizeAccessPolicy(value.accessPolicy) } : {},
|
|
10984
10999
|
bot: {
|
|
10985
11000
|
name: text5(value.bot?.name, "WhatsApp\u673A\u5668\u4EBA", 100),
|
|
10986
11001
|
idMasked: text5(value.bot?.idMasked, "WhatsApp\u8D26\u53F7", 140)
|
|
@@ -11022,7 +11037,7 @@ function formatRemaining6(milliseconds) {
|
|
|
11022
11037
|
}
|
|
11023
11038
|
|
|
11024
11039
|
// plugin-src/client/channels/whatsapp/index.js
|
|
11025
|
-
var
|
|
11040
|
+
var React19 = __toESM(require("react"), 1);
|
|
11026
11041
|
|
|
11027
11042
|
// plugin-src/client/channels/whatsapp/styles.js
|
|
11028
11043
|
var WHATSAPP_STYLE_ID = "xmanrui-dsh-im-whatsapp-settings";
|
|
@@ -11030,31 +11045,6 @@ var CSS10 = String.raw`
|
|
|
11030
11045
|
.dwa-page { --ddt-accent: #25d366; --ddt-accent-deep: #128c7e; --ddt-accent-wash: #eafbf0; }
|
|
11031
11046
|
.dwa-avatar { color: #fff; background: #25d366; }
|
|
11032
11047
|
.dwa-avatar svg { display: block; }
|
|
11033
|
-
.dwa-access { display: grid; gap: 10px; padding: 12px; border: 1px solid var(--dsw-alias-border-l2, #dfe1e5); border-radius: 10px; background: var(--dsw-alias-bg-layer-2, #f7f8fa); }
|
|
11034
|
-
.dwa-accessHeading { display: flex; align-items: center; justify-content: space-between; gap: 12px; }
|
|
11035
|
-
.dwa-accessHeading > strong { font-size: 13px; }
|
|
11036
|
-
.dwa-accessStatus { min-width: 0; display: inline-flex; align-items: center; justify-content: flex-end; gap: 6px; }
|
|
11037
|
-
.dwa-accessBadge { flex: none; padding: 3px 8px; border-radius: 999px; color: #08785f; background: #eafbf0; font-size: 11px; font-weight: 700; }
|
|
11038
|
-
.dwa-accessBadge[data-mode="private-allowlist"] { color: #0f6f8f; background: #eaf7fd; }
|
|
11039
|
-
.dwa-accessBadge[data-mode="open"] { color: #a15c00; background: #fff3d6; }
|
|
11040
|
-
.dwa-accessHelp { position: relative; display: inline-flex; flex: none; }
|
|
11041
|
-
.dwa-accessHelpButton { width: 20px; height: 20px; display: grid; place-items: center; padding: 0; border: 1px solid color-mix(in srgb, #25d366 34%, var(--dsw-alias-border-l2, #dfe1e5)); border-radius: 50%; color: #128c7e; background: var(--dsw-alias-bg-layer-1, #fff); font: inherit; font-size: 12px; line-height: 1; font-weight: 750; cursor: help; }
|
|
11042
|
-
.dwa-accessTooltip { position: absolute; top: calc(100% + 8px); right: 0; z-index: 30; width: 270px; max-width: min(290px, calc(100vw - 48px)); display: grid; gap: 8px; padding: 10px 11px; border: 1px solid var(--dsw-alias-border-l2, #dfe1e5); border-radius: 9px; color: var(--dsw-alias-label-primary, #1f2329); background: var(--dsw-alias-bg-layer-3, #fff); box-shadow: 0 10px 28px rgb(31 35 41 / 16%); opacity: 0; visibility: hidden; transform: translateY(-3px); pointer-events: none; transition: opacity .15s ease, transform .15s ease, visibility .15s ease; }
|
|
11043
|
-
.dwa-accessTooltipItem { display: grid; gap: 2px; }
|
|
11044
|
-
.dwa-accessTooltipItem + .dwa-accessTooltipItem { padding-top: 8px; border-top: 1px solid var(--dsw-alias-border-l2, #eef0f3); }
|
|
11045
|
-
.dwa-accessTooltipItem strong { font-size: 12px; line-height: 17px; }
|
|
11046
|
-
.dwa-accessTooltipItem > span { color: var(--dsw-alias-label-secondary, #646a73); font-size: 11px; line-height: 16px; }
|
|
11047
|
-
.dwa-accessHelp:hover .dwa-accessTooltip, .dwa-accessHelp:focus-within .dwa-accessTooltip { opacity: 1; visibility: visible; transform: translateY(0); }
|
|
11048
|
-
.dwa-accessField { display: grid; gap: 5px; color: var(--dsw-alias-label-primary, #1f2329); font-size: 12px; font-weight: 600; }
|
|
11049
|
-
.dwa-accessField select, .dwa-accessField textarea { width: 100%; box-sizing: border-box; border: 1px solid var(--dsw-alias-border-l1, #c9cdd4); border-radius: 7px; color: inherit; background: var(--dsw-alias-bg-layer-1, #fff); font: inherit; font-weight: 400; }
|
|
11050
|
-
.dwa-accessField select { height: 34px; padding: 0 9px; }
|
|
11051
|
-
.dwa-accessField textarea { min-height: 68px; padding: 8px 9px; resize: vertical; font-family: ui-monospace, SFMono-Regular, Menlo, monospace; }
|
|
11052
|
-
.dwa-accessField textarea:disabled { color: var(--dsw-alias-label-tertiary, #8f959e); background: var(--dsw-alias-bg-module-platform, #f2f3f5); cursor: not-allowed; resize: none; opacity: 1; }
|
|
11053
|
-
.dwa-accessField small { color: var(--dsw-alias-label-secondary, #646a73); font-weight: 400; }
|
|
11054
|
-
.dwa-accessWarning, .dwa-accessError { margin: 0; font-size: 12px; line-height: 1.5; }
|
|
11055
|
-
.dwa-accessWarning { color: #a15c00; }
|
|
11056
|
-
.dwa-accessError { color: var(--dsw-alias-state-error-primary, #d83931); }
|
|
11057
|
-
.dwa-accessActions { display: flex; justify-content: flex-end; }
|
|
11058
11048
|
`;
|
|
11059
11049
|
function installWhatsappStyles() {
|
|
11060
11050
|
if (typeof document === "undefined") return () => {
|
|
@@ -11072,193 +11062,43 @@ function installWhatsappStyles() {
|
|
|
11072
11062
|
|
|
11073
11063
|
// plugin-src/client/channels/whatsapp/index.js
|
|
11074
11064
|
var ACTIVE_STATES3 = /* @__PURE__ */ new Set(["pending", "connecting"]);
|
|
11075
|
-
function
|
|
11076
|
-
|
|
11077
|
-
|
|
11078
|
-
|
|
11079
|
-
|
|
11080
|
-
|
|
11081
|
-
|
|
11082
|
-
};
|
|
11065
|
+
var Button14 = React19.forwardRef(function Button15({ children, kind = "secondary", className = "", ...props }, ref) {
|
|
11066
|
+
return h2("button", {
|
|
11067
|
+
...props,
|
|
11068
|
+
ref,
|
|
11069
|
+
type: "button",
|
|
11070
|
+
className: `ddt-button ${className}`.trim(),
|
|
11071
|
+
"data-kind": kind
|
|
11072
|
+
}, children);
|
|
11073
|
+
});
|
|
11074
|
+
function checkedTime6(value) {
|
|
11075
|
+
if (!value) return "\u5C1A\u672A\u68C0\u67E5";
|
|
11076
|
+
try {
|
|
11077
|
+
return new Intl.DateTimeFormat("zh-CN", {
|
|
11078
|
+
hour: "2-digit",
|
|
11079
|
+
minute: "2-digit",
|
|
11080
|
+
second: "2-digit"
|
|
11081
|
+
}).format(new Date(value));
|
|
11082
|
+
} catch {
|
|
11083
|
+
return "\u521A\u521A";
|
|
11084
|
+
}
|
|
11083
11085
|
}
|
|
11084
|
-
function
|
|
11085
|
-
|
|
11086
|
-
|
|
11087
|
-
if (normalized.some((entry) => !/^[1-9]\d{4,14}$/.test(entry))) {
|
|
11088
|
-
throw new TypeError("\u7535\u8BDD\u53F7\u7801\u5FC5\u987B\u5305\u542B\u56FD\u5BB6\u6216\u5730\u533A\u4EE3\u7801\uFF0C\u6BCF\u884C\u4E00\u4E2A\u3002");
|
|
11086
|
+
function connectionTestNotice3(value) {
|
|
11087
|
+
if (value?.testMessage?.sent === true) {
|
|
11088
|
+
return "\u6D4B\u8BD5\u6D88\u606F\u5DF2\u53D1\u9001\uFF0C\u8BF7\u5230 WhatsApp \u81EA\u804A\u4F1A\u8BDD\u4E2D\u786E\u8BA4\u3002";
|
|
11089
11089
|
}
|
|
11090
|
-
|
|
11091
|
-
|
|
11092
|
-
|
|
11093
|
-
|
|
11094
|
-
|
|
11095
|
-
|
|
11096
|
-
const [accessMode, setAccessMode] = React20.useState(policy.accessMode);
|
|
11097
|
-
const [allowedNumbers, setAllowedNumbers] = React20.useState(sourceNumbers);
|
|
11098
|
-
const [error, setError] = React20.useState(null);
|
|
11099
|
-
React20.useEffect(() => {
|
|
11100
|
-
setAccessMode(policy.accessMode);
|
|
11101
|
-
setAllowedNumbers(sourceNumbers);
|
|
11102
|
-
setError(null);
|
|
11103
|
-
}, [policy.accessMode, sourceNumbers]);
|
|
11104
|
-
const save = async (event) => {
|
|
11105
|
-
event.preventDefault();
|
|
11106
|
-
setError(null);
|
|
11107
|
-
try {
|
|
11108
|
-
const normalized = allowedNumbersFromText(allowedNumbers);
|
|
11109
|
-
if (typeof onSave !== "function") throw new Error("WhatsApp \u8BBF\u95EE\u8BBE\u7F6E\u6682\u4E0D\u53EF\u7528\u3002");
|
|
11110
|
-
await onSave({ accessMode, allowedNumbers: normalized });
|
|
11111
|
-
} catch (caught) {
|
|
11112
|
-
setError(caught?.message ?? "WhatsApp \u8BBF\u95EE\u8BBE\u7F6E\u4FDD\u5B58\u5931\u8D25\u3002");
|
|
11113
|
-
}
|
|
11114
|
-
};
|
|
11115
|
-
const allowlistEnabled = accessMode === "private-allowlist";
|
|
11116
|
-
const labels = {
|
|
11117
|
-
"self-only": "\u4EC5\u81EA\u5DF1\u6A21\u5F0F",
|
|
11118
|
-
"private-allowlist": "\u6307\u5B9A\u8054\u7CFB\u4EBA\u6A21\u5F0F",
|
|
11119
|
-
open: "\u5F00\u653E\u54CD\u5E94\u6A21\u5F0F"
|
|
11120
|
-
};
|
|
11090
|
+
if (value?.testMessage?.code === "test-target-unavailable") {
|
|
11091
|
+
return "\u8FDE\u63A5\u68C0\u67E5\u5B8C\u6210\uFF0C\u4F46\u5F53\u524D\u6CA1\u6709\u53EF\u7528\u7684 WhatsApp \u81EA\u804A\u76EE\u6807\u3002";
|
|
11092
|
+
}
|
|
11093
|
+
return value?.testMessage ? "\u8FDE\u63A5\u68C0\u67E5\u5B8C\u6210\uFF0C\u4F46\u6D4B\u8BD5\u6D88\u606F\u53D1\u9001\u5931\u8D25\u3002" : null;
|
|
11094
|
+
}
|
|
11095
|
+
function Heading6({ totals, busy, onAdd, addButtonRef }) {
|
|
11121
11096
|
return h2(
|
|
11122
|
-
"
|
|
11123
|
-
{ className: "
|
|
11097
|
+
"div",
|
|
11098
|
+
{ className: "ddt-heading" },
|
|
11124
11099
|
h2(
|
|
11125
11100
|
"div",
|
|
11126
|
-
{ className: "
|
|
11127
|
-
h2("strong", null, "\u8BBF\u95EE\u8BBE\u7F6E"),
|
|
11128
|
-
h2(
|
|
11129
|
-
"span",
|
|
11130
|
-
{ className: "dwa-accessStatus" },
|
|
11131
|
-
h2(
|
|
11132
|
-
"span",
|
|
11133
|
-
{ className: "dwa-accessBadge", "data-mode": policy.accessMode },
|
|
11134
|
-
["\u5DF2\u751F\u6548\uFF1A", labels[policy.accessMode]]
|
|
11135
|
-
),
|
|
11136
|
-
h2(
|
|
11137
|
-
"span",
|
|
11138
|
-
{ className: "dwa-accessHelp" },
|
|
11139
|
-
h2("button", {
|
|
11140
|
-
type: "button",
|
|
11141
|
-
className: "dwa-accessHelpButton",
|
|
11142
|
-
"aria-label": "\u67E5\u770B WhatsApp \u8BBF\u95EE\u6A21\u5F0F\u8BF4\u660E",
|
|
11143
|
-
"aria-describedby": helpId
|
|
11144
|
-
}, h2("span", { "aria-hidden": "true" }, "?")),
|
|
11145
|
-
h2(
|
|
11146
|
-
"span",
|
|
11147
|
-
{ id: helpId, className: "dwa-accessTooltip", role: "tooltip" },
|
|
11148
|
-
h2(
|
|
11149
|
-
"span",
|
|
11150
|
-
{ className: "dwa-accessTooltipItem" },
|
|
11151
|
-
h2("strong", null, "\u4EC5\u81EA\u5DF1\u6A21\u5F0F"),
|
|
11152
|
-
h2("span", null, "\u53EA\u54CD\u5E94\u5DF2\u7ED1\u5B9A WhatsApp \u8D26\u53F7\u7684\u81EA\u804A\u6D88\u606F\u3002")
|
|
11153
|
-
),
|
|
11154
|
-
h2(
|
|
11155
|
-
"span",
|
|
11156
|
-
{ className: "dwa-accessTooltipItem" },
|
|
11157
|
-
h2("strong", null, "\u6307\u5B9A\u8054\u7CFB\u4EBA\u6A21\u5F0F"),
|
|
11158
|
-
h2("span", null, "\u54CD\u5E94\u81EA\u804A\u548C\u767D\u540D\u5355\u8054\u7CFB\u4EBA\u7684\u79C1\u804A\uFF0C\u5FFD\u7565\u7FA4\u804A\u3002")
|
|
11159
|
-
),
|
|
11160
|
-
h2(
|
|
11161
|
-
"span",
|
|
11162
|
-
{ className: "dwa-accessTooltipItem" },
|
|
11163
|
-
h2("strong", null, "\u5F00\u653E\u54CD\u5E94\u6A21\u5F0F"),
|
|
11164
|
-
h2("span", null, "\u54CD\u5E94\u6240\u6709\u79C1\u804A\u3001\u5DF2\u7ED1\u5B9A\u8D26\u53F7\u81EA\u5DF1\u53D1\u51FA\u7684\u7FA4\u804A\u6D88\u606F\uFF0C\u4EE5\u53CA\u5176\u4ED6\u7FA4\u6210\u5458\u7684\u63D0\u53CA\u6216\u56DE\u590D\u3002")
|
|
11165
|
-
)
|
|
11166
|
-
)
|
|
11167
|
-
)
|
|
11168
|
-
)
|
|
11169
|
-
),
|
|
11170
|
-
h2(
|
|
11171
|
-
"label",
|
|
11172
|
-
{ className: "dwa-accessField" },
|
|
11173
|
-
h2("span", null, "\u6A21\u5F0F"),
|
|
11174
|
-
h2(
|
|
11175
|
-
"select",
|
|
11176
|
-
{
|
|
11177
|
-
value: accessMode,
|
|
11178
|
-
disabled: busy,
|
|
11179
|
-
"aria-label": "WhatsApp \u8BBF\u95EE\u6A21\u5F0F",
|
|
11180
|
-
onChange: (event) => {
|
|
11181
|
-
setAccessMode(event.target.value);
|
|
11182
|
-
setError(null);
|
|
11183
|
-
}
|
|
11184
|
-
},
|
|
11185
|
-
h2("option", { value: "self-only" }, "\u4EC5\u81EA\u5DF1\u6A21\u5F0F\uFF08\u9ED8\u8BA4\uFF09"),
|
|
11186
|
-
h2("option", { value: "private-allowlist" }, "\u6307\u5B9A\u8054\u7CFB\u4EBA\u6A21\u5F0F"),
|
|
11187
|
-
h2("option", { value: "open" }, "\u5F00\u653E\u54CD\u5E94\u6A21\u5F0F")
|
|
11188
|
-
)
|
|
11189
|
-
),
|
|
11190
|
-
allowlistEnabled ? h2(
|
|
11191
|
-
"label",
|
|
11192
|
-
{ className: "dwa-accessField" },
|
|
11193
|
-
h2("span", null, "\u5141\u8BB8\u79C1\u804A\u7684 WhatsApp \u7535\u8BDD\u53F7\u7801"),
|
|
11194
|
-
h2("textarea", {
|
|
11195
|
-
value: allowedNumbers,
|
|
11196
|
-
disabled: busy,
|
|
11197
|
-
rows: 3,
|
|
11198
|
-
placeholder: "\u6BCF\u884C\u4E00\u4E2A\u542B\u56FD\u5BB6\u6216\u5730\u533A\u4EE3\u7801\u7684\u53F7\u7801",
|
|
11199
|
-
"aria-label": "\u5141\u8BB8\u79C1\u804A\u7684 WhatsApp \u7535\u8BDD\u53F7\u7801",
|
|
11200
|
-
onChange: (event) => {
|
|
11201
|
-
setAllowedNumbers(event.target.value);
|
|
11202
|
-
setError(null);
|
|
11203
|
-
}
|
|
11204
|
-
}),
|
|
11205
|
-
h2("small", null, "\u53EF\u4EE5\u5305\u542B\u5F00\u5934\u7684 +\uFF0C\u4FDD\u5B58\u65F6\u4F1A\u81EA\u52A8\u79FB\u9664\u3002")
|
|
11206
|
-
) : null,
|
|
11207
|
-
allowlistEnabled && allowedNumbers.trim() === "" ? h2(
|
|
11208
|
-
"p",
|
|
11209
|
-
{ className: "dwa-accessWarning", role: "status" },
|
|
11210
|
-
"\u767D\u540D\u5355\u4E3A\u7A7A\uFF1B\u4FDD\u5B58\u540E\u5C06\u53EA\u63A5\u53D7\u81EA\u804A\u6D88\u606F\u3002"
|
|
11211
|
-
) : null,
|
|
11212
|
-
error ? h2("p", { className: "dwa-accessError", role: "alert" }, error) : null,
|
|
11213
|
-
h2(
|
|
11214
|
-
"div",
|
|
11215
|
-
{ className: "dwa-accessActions" },
|
|
11216
|
-
h2("button", {
|
|
11217
|
-
type: "submit",
|
|
11218
|
-
className: "ddt-button",
|
|
11219
|
-
"data-kind": "secondary",
|
|
11220
|
-
disabled: busy
|
|
11221
|
-
}, busy ? "\u6B63\u5728\u4FDD\u5B58\u2026" : "\u4FDD\u5B58\u8BBF\u95EE\u8BBE\u7F6E")
|
|
11222
|
-
)
|
|
11223
|
-
);
|
|
11224
|
-
}
|
|
11225
|
-
var Button14 = React20.forwardRef(function Button15({ children, kind = "secondary", className = "", ...props }, ref) {
|
|
11226
|
-
return h2("button", {
|
|
11227
|
-
...props,
|
|
11228
|
-
ref,
|
|
11229
|
-
type: "button",
|
|
11230
|
-
className: `ddt-button ${className}`.trim(),
|
|
11231
|
-
"data-kind": kind
|
|
11232
|
-
}, children);
|
|
11233
|
-
});
|
|
11234
|
-
function checkedTime6(value) {
|
|
11235
|
-
if (!value) return "\u5C1A\u672A\u68C0\u67E5";
|
|
11236
|
-
try {
|
|
11237
|
-
return new Intl.DateTimeFormat("zh-CN", {
|
|
11238
|
-
hour: "2-digit",
|
|
11239
|
-
minute: "2-digit",
|
|
11240
|
-
second: "2-digit"
|
|
11241
|
-
}).format(new Date(value));
|
|
11242
|
-
} catch {
|
|
11243
|
-
return "\u521A\u521A";
|
|
11244
|
-
}
|
|
11245
|
-
}
|
|
11246
|
-
function connectionTestNotice3(value) {
|
|
11247
|
-
if (value?.testMessage?.sent === true) {
|
|
11248
|
-
return "\u6D4B\u8BD5\u6D88\u606F\u5DF2\u53D1\u9001\uFF0C\u8BF7\u5230 WhatsApp \u81EA\u804A\u4F1A\u8BDD\u4E2D\u786E\u8BA4\u3002";
|
|
11249
|
-
}
|
|
11250
|
-
if (value?.testMessage?.code === "test-target-unavailable") {
|
|
11251
|
-
return "\u8FDE\u63A5\u68C0\u67E5\u5B8C\u6210\uFF0C\u4F46\u5F53\u524D\u6CA1\u6709\u53EF\u7528\u7684 WhatsApp \u81EA\u804A\u76EE\u6807\u3002";
|
|
11252
|
-
}
|
|
11253
|
-
return value?.testMessage ? "\u8FDE\u63A5\u68C0\u67E5\u5B8C\u6210\uFF0C\u4F46\u6D4B\u8BD5\u6D88\u606F\u53D1\u9001\u5931\u8D25\u3002" : null;
|
|
11254
|
-
}
|
|
11255
|
-
function Heading6({ totals, busy, onAdd, addButtonRef }) {
|
|
11256
|
-
return h2(
|
|
11257
|
-
"div",
|
|
11258
|
-
{ className: "ddt-heading" },
|
|
11259
|
-
h2(
|
|
11260
|
-
"div",
|
|
11261
|
-
{ className: "ddt-tools" },
|
|
11101
|
+
{ className: "ddt-tools" },
|
|
11262
11102
|
h2(
|
|
11263
11103
|
"div",
|
|
11264
11104
|
{ className: "dim-bindActions" },
|
|
@@ -11446,7 +11286,6 @@ function WhatsappAccountCard({
|
|
|
11446
11286
|
onWorkspaceSave,
|
|
11447
11287
|
onAgentPresetSave,
|
|
11448
11288
|
onContextEnhancementSave,
|
|
11449
|
-
onAccessPolicySave,
|
|
11450
11289
|
onRequestRemove,
|
|
11451
11290
|
onConfirmRemove,
|
|
11452
11291
|
onCancelRemove
|
|
@@ -11493,7 +11332,8 @@ function WhatsappAccountCard({
|
|
|
11493
11332
|
channel: "whatsapp",
|
|
11494
11333
|
botId: account.botId,
|
|
11495
11334
|
botName: account.bot.name,
|
|
11496
|
-
connected: account.connected
|
|
11335
|
+
connected: account.connected,
|
|
11336
|
+
accessPolicy: account.accessPolicy
|
|
11497
11337
|
})
|
|
11498
11338
|
)
|
|
11499
11339
|
),
|
|
@@ -11512,11 +11352,6 @@ function WhatsappAccountCard({
|
|
|
11512
11352
|
disabled: Boolean(busy),
|
|
11513
11353
|
onSave: onContextEnhancementSave
|
|
11514
11354
|
}),
|
|
11515
|
-
h2(WhatsappAccessSettings, {
|
|
11516
|
-
account,
|
|
11517
|
-
busy: Boolean(busy),
|
|
11518
|
-
onSave: onAccessPolicySave
|
|
11519
|
-
}),
|
|
11520
11355
|
h2(
|
|
11521
11356
|
"div",
|
|
11522
11357
|
{ className: "ddt-accountFooter dim-cardFooter" },
|
|
@@ -11559,23 +11394,23 @@ function WhatsappAccountCard({
|
|
|
11559
11394
|
);
|
|
11560
11395
|
}
|
|
11561
11396
|
function WhatsappSettingsTab({ rpcCall }) {
|
|
11562
|
-
const [model, setModel] =
|
|
11397
|
+
const [model, setModel] = React19.useState({
|
|
11563
11398
|
phase: "loading",
|
|
11564
11399
|
bots: [],
|
|
11565
11400
|
totals: { configured: 0, connected: 0 },
|
|
11566
11401
|
error: null,
|
|
11567
11402
|
agentPresetCatalog: EMPTY_AGENT_PRESET_CATALOG
|
|
11568
11403
|
});
|
|
11569
|
-
const [provision, setProvision] =
|
|
11570
|
-
const [busy, setBusy] =
|
|
11571
|
-
const [busyByBot, setBusyByBot] =
|
|
11572
|
-
const [testNoticeByBot, setTestNoticeByBot] =
|
|
11573
|
-
const [removeTarget, setRemoveTarget] =
|
|
11574
|
-
const [now, setNow] =
|
|
11575
|
-
const mounted =
|
|
11404
|
+
const [provision, setProvision] = React19.useState(null);
|
|
11405
|
+
const [busy, setBusy] = React19.useState(false);
|
|
11406
|
+
const [busyByBot, setBusyByBot] = React19.useState({});
|
|
11407
|
+
const [testNoticeByBot, setTestNoticeByBot] = React19.useState({});
|
|
11408
|
+
const [removeTarget, setRemoveTarget] = React19.useState(null);
|
|
11409
|
+
const [now, setNow] = React19.useState(Date.now());
|
|
11410
|
+
const mounted = React19.useRef(true);
|
|
11576
11411
|
const workspaceFence = useWorkspaceSnapshotFence();
|
|
11577
|
-
const addButtonRef =
|
|
11578
|
-
|
|
11412
|
+
const addButtonRef = React19.useRef(null);
|
|
11413
|
+
React19.useEffect(() => {
|
|
11579
11414
|
const disposeDingtalk = installDingtalkStyles();
|
|
11580
11415
|
const disposeWhatsapp = installWhatsappStyles();
|
|
11581
11416
|
mounted.current = true;
|
|
@@ -11585,11 +11420,11 @@ function WhatsappSettingsTab({ rpcCall }) {
|
|
|
11585
11420
|
disposeDingtalk();
|
|
11586
11421
|
};
|
|
11587
11422
|
}, []);
|
|
11588
|
-
const invoke =
|
|
11423
|
+
const invoke = React19.useCallback(async (endpoint, payload = {}, signal) => {
|
|
11589
11424
|
if (typeof rpcCall !== "function") throw new TypeError("WhatsApp \u8BBE\u7F6E\u9875\u7F3A\u5C11 RPC \u8FDE\u63A5");
|
|
11590
11425
|
return unwrapRpcResult9(await rpcCall(endpoint, payload, signal));
|
|
11591
11426
|
}, [rpcCall]);
|
|
11592
|
-
const loadStatus =
|
|
11427
|
+
const loadStatus = React19.useCallback(async ({ signal, silent = false, restore = false } = {}) => {
|
|
11593
11428
|
const workspaceVersion = workspaceFence.beginStatus();
|
|
11594
11429
|
if (workspaceVersion === null) return void 0;
|
|
11595
11430
|
if (!silent && mounted.current) setModel((current) => ({ ...current, phase: "loading", error: null }));
|
|
@@ -11619,12 +11454,12 @@ function WhatsappSettingsTab({ rpcCall }) {
|
|
|
11619
11454
|
return void 0;
|
|
11620
11455
|
}
|
|
11621
11456
|
}, [invoke, workspaceFence]);
|
|
11622
|
-
|
|
11457
|
+
React19.useEffect(() => {
|
|
11623
11458
|
const controller = new AbortController();
|
|
11624
11459
|
void loadStatus({ signal: controller.signal, restore: true });
|
|
11625
11460
|
return () => controller.abort();
|
|
11626
11461
|
}, [loadStatus]);
|
|
11627
|
-
|
|
11462
|
+
React19.useEffect(() => {
|
|
11628
11463
|
if (model.phase !== "ready") return void 0;
|
|
11629
11464
|
const controller = new AbortController();
|
|
11630
11465
|
const timer = window.setInterval(
|
|
@@ -11636,12 +11471,12 @@ function WhatsappSettingsTab({ rpcCall }) {
|
|
|
11636
11471
|
window.clearInterval(timer);
|
|
11637
11472
|
};
|
|
11638
11473
|
}, [loadStatus, model.phase]);
|
|
11639
|
-
|
|
11474
|
+
React19.useEffect(() => {
|
|
11640
11475
|
if (!provision || !ACTIVE_STATES3.has(provision.status)) return void 0;
|
|
11641
11476
|
const timer = window.setInterval(() => mounted.current && setNow(Date.now()), 1e3);
|
|
11642
11477
|
return () => window.clearInterval(timer);
|
|
11643
11478
|
}, [provision?.attemptId, provision?.status]);
|
|
11644
|
-
const startProvisioning =
|
|
11479
|
+
const startProvisioning = React19.useCallback(async (replace = false) => {
|
|
11645
11480
|
setBusy(true);
|
|
11646
11481
|
try {
|
|
11647
11482
|
if (replace && provision?.attemptId) {
|
|
@@ -11659,7 +11494,7 @@ function WhatsappSettingsTab({ rpcCall }) {
|
|
|
11659
11494
|
if (mounted.current) setBusy(false);
|
|
11660
11495
|
}
|
|
11661
11496
|
}, [invoke, provision?.attemptId]);
|
|
11662
|
-
const closeProvision =
|
|
11497
|
+
const closeProvision = React19.useCallback(async () => {
|
|
11663
11498
|
setBusy(true);
|
|
11664
11499
|
try {
|
|
11665
11500
|
if (provision?.attemptId && ACTIVE_STATES3.has(provision.status)) {
|
|
@@ -11670,7 +11505,7 @@ function WhatsappSettingsTab({ rpcCall }) {
|
|
|
11670
11505
|
if (mounted.current) setBusy(false);
|
|
11671
11506
|
}
|
|
11672
11507
|
}, [invoke, provision?.attemptId, provision?.status]);
|
|
11673
|
-
|
|
11508
|
+
React19.useEffect(() => {
|
|
11674
11509
|
const attemptId = provision?.attemptId;
|
|
11675
11510
|
if (!attemptId || !ACTIVE_STATES3.has(provision.status)) return void 0;
|
|
11676
11511
|
const controller = new AbortController();
|
|
@@ -11711,7 +11546,7 @@ function WhatsappSettingsTab({ rpcCall }) {
|
|
|
11711
11546
|
if (timer) window.clearTimeout(timer);
|
|
11712
11547
|
};
|
|
11713
11548
|
}, [invoke, loadStatus, provision?.attemptId, provision?.status]);
|
|
11714
|
-
const botAction =
|
|
11549
|
+
const botAction = React19.useCallback(async (account, operation, endpoint, payload) => {
|
|
11715
11550
|
const snapshotVersion = workspaceFence.beginMutation();
|
|
11716
11551
|
setBusyByBot((current) => ({ ...current, [account.botId]: operation }));
|
|
11717
11552
|
if (operation === "reconnect") {
|
|
@@ -11794,12 +11629,6 @@ function WhatsappSettingsTab({ rpcCall }) {
|
|
|
11794
11629
|
WHATSAPP_ENDPOINTS.setContextEnhancement,
|
|
11795
11630
|
{ botId: account.botId, config }
|
|
11796
11631
|
),
|
|
11797
|
-
onAccessPolicySave: (accessPolicy) => botAction(
|
|
11798
|
-
account,
|
|
11799
|
-
"access",
|
|
11800
|
-
WHATSAPP_ENDPOINTS.setAccessPolicy,
|
|
11801
|
-
{ botId: account.botId, ...accessPolicy }
|
|
11802
|
-
),
|
|
11803
11632
|
onRequestRemove: () => setRemoveTarget(account.botId),
|
|
11804
11633
|
onCancelRemove: () => setRemoveTarget(null),
|
|
11805
11634
|
onConfirmRemove: async () => {
|
|
@@ -11836,7 +11665,7 @@ function WhatsappSettingsTab({ rpcCall }) {
|
|
|
11836
11665
|
h2(Button14, { onClick: () => void loadStatus() }, "\u91CD\u65B0\u8BFB\u53D6")
|
|
11837
11666
|
)
|
|
11838
11667
|
) : h2(
|
|
11839
|
-
|
|
11668
|
+
React19.Fragment,
|
|
11840
11669
|
null,
|
|
11841
11670
|
provision?.status === "pending" ? h2(QrPanel5, {
|
|
11842
11671
|
provision,
|
|
@@ -11857,6 +11686,404 @@ function WhatsappSettingsTab({ rpcCall }) {
|
|
|
11857
11686
|
|
|
11858
11687
|
// plugin-src/client/delivery-settings.js
|
|
11859
11688
|
var React21 = __toESM(require("react"), 1);
|
|
11689
|
+
|
|
11690
|
+
// plugin-src/client/access-policy-settings.js
|
|
11691
|
+
var React20 = __toESM(require("react"), 1);
|
|
11692
|
+
var ACCESS_POLICY_ENDPOINT = "bot.access-policy.set";
|
|
11693
|
+
var ACCESS_CHANNEL_DEFINITIONS = Object.freeze({
|
|
11694
|
+
weixin: Object.freeze({
|
|
11695
|
+
directUserLabel: "\u5FAE\u4FE1\u7528\u6237 ID",
|
|
11696
|
+
directPlaceholder: "\u586B\u5199\u5FAE\u4FE1\u7528\u6237 ID",
|
|
11697
|
+
groupSupported: false
|
|
11698
|
+
}),
|
|
11699
|
+
feishu: Object.freeze({
|
|
11700
|
+
directUserLabel: "\u98DE\u4E66 Open ID",
|
|
11701
|
+
directPlaceholder: "ou_xxx",
|
|
11702
|
+
groupUserLabel: "\u7FA4\u6210\u5458 Open ID",
|
|
11703
|
+
groupPlaceholder: "ou_xxx"
|
|
11704
|
+
}),
|
|
11705
|
+
dingtalk: Object.freeze({
|
|
11706
|
+
directUserLabel: "\u9489\u9489\u7528\u6237 ID",
|
|
11707
|
+
directPlaceholder: "\u586B\u5199 senderStaffId \u6216 senderId",
|
|
11708
|
+
groupUserLabel: "\u7FA4\u6210\u5458\u7528\u6237 ID",
|
|
11709
|
+
groupPlaceholder: "\u586B\u5199 senderStaffId \u6216 senderId"
|
|
11710
|
+
}),
|
|
11711
|
+
wecom: Object.freeze({
|
|
11712
|
+
directUserLabel: "\u4F01\u4E1A\u5FAE\u4FE1\u7528\u6237 ID",
|
|
11713
|
+
directPlaceholder: "\u586B\u5199 userid",
|
|
11714
|
+
groupUserLabel: "\u7FA4\u6210\u5458\u7528\u6237 ID",
|
|
11715
|
+
groupPlaceholder: "\u586B\u5199 userid"
|
|
11716
|
+
}),
|
|
11717
|
+
qq: Object.freeze({
|
|
11718
|
+
directUserLabel: "QQ User Open ID",
|
|
11719
|
+
directPlaceholder: "\u586B\u5199 user_openid",
|
|
11720
|
+
groupUserLabel: "\u7FA4\u6210\u5458 Open ID",
|
|
11721
|
+
groupPlaceholder: "\u586B\u5199 member_openid"
|
|
11722
|
+
}),
|
|
11723
|
+
slack: Object.freeze({
|
|
11724
|
+
directUserLabel: "Slack User ID",
|
|
11725
|
+
directPlaceholder: "U0123456789",
|
|
11726
|
+
groupUserLabel: "\u7FA4\u6210\u5458 User ID",
|
|
11727
|
+
groupPlaceholder: "U0123456789"
|
|
11728
|
+
}),
|
|
11729
|
+
telegram: Object.freeze({
|
|
11730
|
+
directUserLabel: "Telegram User ID",
|
|
11731
|
+
directPlaceholder: "\u586B\u5199\u6570\u5B57 User ID",
|
|
11732
|
+
groupUserLabel: "\u7FA4\u6210\u5458 User ID",
|
|
11733
|
+
groupPlaceholder: "\u586B\u5199\u6570\u5B57 User ID"
|
|
11734
|
+
}),
|
|
11735
|
+
discord: Object.freeze({
|
|
11736
|
+
directUserLabel: "Discord User ID",
|
|
11737
|
+
directPlaceholder: "\u586B\u5199\u6570\u5B57 User ID",
|
|
11738
|
+
groupUserLabel: "\u7FA4\u6210\u5458 User ID",
|
|
11739
|
+
groupPlaceholder: "\u586B\u5199\u6570\u5B57 User ID"
|
|
11740
|
+
}),
|
|
11741
|
+
whatsapp: Object.freeze({
|
|
11742
|
+
directUserLabel: "WhatsApp \u7535\u8BDD\u53F7\u7801\u6216 JID",
|
|
11743
|
+
directPlaceholder: "8613800000000 \u6216\u5B8C\u6574 JID",
|
|
11744
|
+
groupUserLabel: "\u7FA4\u6210\u5458\u7535\u8BDD\u53F7\u7801\u6216 JID",
|
|
11745
|
+
groupPlaceholder: "8613800000000 \u6216\u5B8C\u6574 JID"
|
|
11746
|
+
})
|
|
11747
|
+
});
|
|
11748
|
+
function clonePolicy(policy) {
|
|
11749
|
+
const cloneScope = (scope) => ({
|
|
11750
|
+
mode: scope.mode,
|
|
11751
|
+
open: {
|
|
11752
|
+
defaultCanExecuteCommands: scope.open.defaultCanExecuteCommands,
|
|
11753
|
+
commandPermissionOverrides: scope.open.commandPermissionOverrides.map((user) => ({
|
|
11754
|
+
...user
|
|
11755
|
+
}))
|
|
11756
|
+
},
|
|
11757
|
+
allowlist: {
|
|
11758
|
+
users: scope.allowlist.users.map((user) => ({ ...user }))
|
|
11759
|
+
}
|
|
11760
|
+
});
|
|
11761
|
+
return {
|
|
11762
|
+
direct: cloneScope(policy.direct),
|
|
11763
|
+
group: cloneScope(policy.group)
|
|
11764
|
+
};
|
|
11765
|
+
}
|
|
11766
|
+
function unwrapRpcResult10(result) {
|
|
11767
|
+
if (result?.ok === true) return result.value;
|
|
11768
|
+
if (result?.ok === false) {
|
|
11769
|
+
const error = new Error(result.error?.message || "\u8BBF\u95EE\u8BBE\u7F6E\u4FDD\u5B58\u5931\u8D25\uFF0C\u8BF7\u7A0D\u540E\u91CD\u8BD5\u3002");
|
|
11770
|
+
error.code = result.error?.code;
|
|
11771
|
+
throw error;
|
|
11772
|
+
}
|
|
11773
|
+
return result;
|
|
11774
|
+
}
|
|
11775
|
+
function policyFromSnapshot(value, botId) {
|
|
11776
|
+
const source = value?.snapshot ?? value;
|
|
11777
|
+
const bot = Array.isArray(source?.bots) ? source.bots.find((entry) => entry?.botId === botId) : null;
|
|
11778
|
+
return normalizeAccessPolicy(bot?.accessPolicy ?? source?.accessPolicy ?? source?.policy);
|
|
11779
|
+
}
|
|
11780
|
+
function commandValue(value) {
|
|
11781
|
+
return value === "allow";
|
|
11782
|
+
}
|
|
11783
|
+
function ScenePolicyEditor({
|
|
11784
|
+
scene,
|
|
11785
|
+
title,
|
|
11786
|
+
policy,
|
|
11787
|
+
userLabel,
|
|
11788
|
+
placeholder,
|
|
11789
|
+
disabled = false,
|
|
11790
|
+
unsupported = false,
|
|
11791
|
+
onChange
|
|
11792
|
+
}) {
|
|
11793
|
+
const ownerHelpId = React20.useId();
|
|
11794
|
+
const emptyAllowlistHelpId = React20.useId();
|
|
11795
|
+
const allowlist = policy.mode === "allowlist";
|
|
11796
|
+
const collectionKey = allowlist ? "users" : "commandPermissionOverrides";
|
|
11797
|
+
const branchKey = allowlist ? "allowlist" : "open";
|
|
11798
|
+
const users = policy[branchKey][collectionKey];
|
|
11799
|
+
const emptyAllowlist = allowlist && users.length === 0;
|
|
11800
|
+
const updateUsers = (nextUsers) => onChange({
|
|
11801
|
+
...policy,
|
|
11802
|
+
[branchKey]: {
|
|
11803
|
+
...policy[branchKey],
|
|
11804
|
+
[collectionKey]: nextUsers
|
|
11805
|
+
}
|
|
11806
|
+
});
|
|
11807
|
+
const updateUser = (index, patch) => updateUsers(users.map((user, userIndex) => userIndex === index ? { ...user, ...patch } : user));
|
|
11808
|
+
return h2(
|
|
11809
|
+
"fieldset",
|
|
11810
|
+
{
|
|
11811
|
+
className: "dim-accessScene",
|
|
11812
|
+
disabled,
|
|
11813
|
+
"data-scene": scene,
|
|
11814
|
+
"aria-label": localizeText(title)
|
|
11815
|
+
},
|
|
11816
|
+
h2(
|
|
11817
|
+
"legend",
|
|
11818
|
+
null,
|
|
11819
|
+
h2(
|
|
11820
|
+
"span",
|
|
11821
|
+
{ className: "dim-accessLegendContent" },
|
|
11822
|
+
h2("span", null, title),
|
|
11823
|
+
h2(
|
|
11824
|
+
"span",
|
|
11825
|
+
{ className: "dim-channelHelp dim-accessLegendHelp" },
|
|
11826
|
+
h2("button", {
|
|
11827
|
+
type: "button",
|
|
11828
|
+
className: "dim-channelHelpButton",
|
|
11829
|
+
"aria-label": [localizeText(title), localizeText("\u67E5\u770B\u8BBF\u95EE\u6743\u9650\u8BF4\u660E")].join(" "),
|
|
11830
|
+
"aria-describedby": ownerHelpId
|
|
11831
|
+
}, h2("span", { "aria-hidden": true }, "?")),
|
|
11832
|
+
h2("span", {
|
|
11833
|
+
id: ownerHelpId,
|
|
11834
|
+
className: "dim-channelTooltip dim-accessHelpTooltip",
|
|
11835
|
+
role: "tooltip"
|
|
11836
|
+
}, "\u539F\u6240\u6709\u8005\u6216\u626B\u7801\u63A5\u5165\u8005\u59CB\u7EC8\u53EF\u4EE5\u8BBF\u95EE\u5E76\u6267\u884C\u547D\u4EE4\uFF1B\u4EE5\u4E0B\u8BBE\u7F6E\u4EC5\u7EA6\u675F\u5176\u4ED6\u7528\u6237\u3002")
|
|
11837
|
+
)
|
|
11838
|
+
)
|
|
11839
|
+
),
|
|
11840
|
+
unsupported ? h2(
|
|
11841
|
+
"div",
|
|
11842
|
+
{ className: "dim-accessUnsupported", role: "note" },
|
|
11843
|
+
h2("strong", null, "\u5F53\u524D\u6E20\u9053\u4E0D\u652F\u6301\u7FA4\u804A"),
|
|
11844
|
+
h2("p", null, "\u6B64\u533A\u57DF\u65E0\u9700\u914D\u7F6E\uFF0C\u4FDD\u5B58\u79C1\u804A\u8BBE\u7F6E\u65F6\u4F1A\u4FDD\u7559\u73B0\u6709\u7FA4\u804A\u7B56\u7565\u3002")
|
|
11845
|
+
) : h2(
|
|
11846
|
+
React20.Fragment,
|
|
11847
|
+
null,
|
|
11848
|
+
h2(
|
|
11849
|
+
"div",
|
|
11850
|
+
{ className: "dim-accessControls", "data-mode": policy.mode },
|
|
11851
|
+
h2(
|
|
11852
|
+
"label",
|
|
11853
|
+
{ className: "dim-accessField" },
|
|
11854
|
+
h2("span", null, "\u8BBF\u95EE\u6A21\u5F0F"),
|
|
11855
|
+
h2(
|
|
11856
|
+
"select",
|
|
11857
|
+
{
|
|
11858
|
+
value: policy.mode,
|
|
11859
|
+
"aria-label": [localizeText(title), localizeText("\u8BBF\u95EE\u6A21\u5F0F")].join(" "),
|
|
11860
|
+
onChange: (event) => onChange({ ...policy, mode: event.target.value })
|
|
11861
|
+
},
|
|
11862
|
+
h2("option", { value: "open" }, "\u5141\u8BB8\u6240\u6709\u7528\u6237"),
|
|
11863
|
+
h2("option", { value: "allowlist" }, "\u4EC5\u767D\u540D\u5355\u7528\u6237")
|
|
11864
|
+
)
|
|
11865
|
+
),
|
|
11866
|
+
allowlist ? null : h2(
|
|
11867
|
+
"label",
|
|
11868
|
+
{ className: "dim-accessField" },
|
|
11869
|
+
h2("span", null, "\u9ED8\u8BA4\u547D\u4EE4\u6743\u9650"),
|
|
11870
|
+
h2(
|
|
11871
|
+
"select",
|
|
11872
|
+
{
|
|
11873
|
+
value: policy.open.defaultCanExecuteCommands ? "allow" : "deny",
|
|
11874
|
+
"aria-label": [localizeText(title), localizeText("\u9ED8\u8BA4\u547D\u4EE4\u6743\u9650")].join(" "),
|
|
11875
|
+
onChange: (event) => onChange({
|
|
11876
|
+
...policy,
|
|
11877
|
+
open: {
|
|
11878
|
+
...policy.open,
|
|
11879
|
+
defaultCanExecuteCommands: commandValue(event.target.value)
|
|
11880
|
+
}
|
|
11881
|
+
})
|
|
11882
|
+
},
|
|
11883
|
+
h2("option", { value: "allow" }, "\u53EF\u4EE5\u6267\u884C\u547D\u4EE4"),
|
|
11884
|
+
h2("option", { value: "deny" }, "\u4E0D\u53EF\u4EE5\u6267\u884C\u547D\u4EE4")
|
|
11885
|
+
)
|
|
11886
|
+
)
|
|
11887
|
+
),
|
|
11888
|
+
h2(
|
|
11889
|
+
"div",
|
|
11890
|
+
{ className: "dim-accessUsers" },
|
|
11891
|
+
h2(
|
|
11892
|
+
"div",
|
|
11893
|
+
{ className: "dim-accessUsersHeading" },
|
|
11894
|
+
h2(
|
|
11895
|
+
"div",
|
|
11896
|
+
{ className: "dim-accessUsersTitle" },
|
|
11897
|
+
h2("strong", null, allowlist ? "\u767D\u540D\u5355\u7528\u6237" : "\u547D\u4EE4\u6743\u9650\u4F8B\u5916"),
|
|
11898
|
+
emptyAllowlist ? h2(
|
|
11899
|
+
"span",
|
|
11900
|
+
{ className: "dim-channelHelp dim-accessUsersHelp" },
|
|
11901
|
+
h2("button", {
|
|
11902
|
+
type: "button",
|
|
11903
|
+
className: "dim-channelHelpButton",
|
|
11904
|
+
"aria-label": [localizeText(title), localizeText("\u67E5\u770B\u767D\u540D\u5355\u8BF4\u660E")].join(" "),
|
|
11905
|
+
"aria-describedby": emptyAllowlistHelpId
|
|
11906
|
+
}, h2("span", { "aria-hidden": true }, "?")),
|
|
11907
|
+
h2("span", {
|
|
11908
|
+
id: emptyAllowlistHelpId,
|
|
11909
|
+
className: "dim-channelTooltip dim-accessEmptyAllowlistTooltip",
|
|
11910
|
+
role: "tooltip"
|
|
11911
|
+
}, "\u5F53\u524D\u6CA1\u6709\u767D\u540D\u5355\u7528\u6237\uFF0C\u4FDD\u5B58\u540E\u666E\u901A\u7528\u6237\u5C06\u65E0\u6CD5\u4F7F\u7528\u673A\u5668\u4EBA\u3002")
|
|
11912
|
+
) : null
|
|
11913
|
+
),
|
|
11914
|
+
h2("button", {
|
|
11915
|
+
type: "button",
|
|
11916
|
+
className: "dim-deliveryButton dim-accessAddUser",
|
|
11917
|
+
"aria-label": [localizeText(title), localizeText("\u65B0\u589E\u7528\u6237")].join(" "),
|
|
11918
|
+
title: localizeText("\u65B0\u589E\u7528\u6237"),
|
|
11919
|
+
onClick: () => updateUsers([...users, {
|
|
11920
|
+
id: "",
|
|
11921
|
+
canExecuteCommands: allowlist ? false : !policy.open.defaultCanExecuteCommands
|
|
11922
|
+
}])
|
|
11923
|
+
}, h2("span", { "aria-hidden": true }, "+"))
|
|
11924
|
+
),
|
|
11925
|
+
users.length === 0 ? h2("div", { className: "dim-accessUsersEmpty" }, "\u5C1A\u672A\u6DFB\u52A0\u7528\u6237") : h2("ul", { className: "dim-accessUserList" }, users.map((user, index) => h2(
|
|
11926
|
+
"li",
|
|
11927
|
+
{ key: `${scene}-${policy.mode}-${index}`, className: "dim-accessUserRow" },
|
|
11928
|
+
h2(
|
|
11929
|
+
"label",
|
|
11930
|
+
{ className: "dim-accessField dim-accessUserId" },
|
|
11931
|
+
h2("span", null, userLabel),
|
|
11932
|
+
h2("input", {
|
|
11933
|
+
value: user.id,
|
|
11934
|
+
maxLength: 256,
|
|
11935
|
+
required: true,
|
|
11936
|
+
autoCapitalize: "none",
|
|
11937
|
+
autoCorrect: "off",
|
|
11938
|
+
spellCheck: false,
|
|
11939
|
+
placeholder,
|
|
11940
|
+
"aria-label": [localizeText(title), localizeText(userLabel), index + 1].join(" "),
|
|
11941
|
+
onChange: (event) => updateUser(index, { id: event.target.value })
|
|
11942
|
+
})
|
|
11943
|
+
),
|
|
11944
|
+
h2(
|
|
11945
|
+
"label",
|
|
11946
|
+
{ className: "dim-accessField dim-accessUserCommand" },
|
|
11947
|
+
h2("span", null, "\u547D\u4EE4\u6743\u9650"),
|
|
11948
|
+
h2(
|
|
11949
|
+
"select",
|
|
11950
|
+
{
|
|
11951
|
+
value: user.canExecuteCommands ? "allow" : "deny",
|
|
11952
|
+
"aria-label": [
|
|
11953
|
+
localizeText(title),
|
|
11954
|
+
localizeText("\u7528\u6237"),
|
|
11955
|
+
index + 1,
|
|
11956
|
+
localizeText("\u547D\u4EE4\u6743\u9650")
|
|
11957
|
+
].join(" "),
|
|
11958
|
+
onChange: (event) => updateUser(index, {
|
|
11959
|
+
canExecuteCommands: commandValue(event.target.value)
|
|
11960
|
+
})
|
|
11961
|
+
},
|
|
11962
|
+
h2("option", { value: "allow" }, "\u53EF\u4EE5\u6267\u884C\u547D\u4EE4"),
|
|
11963
|
+
h2("option", { value: "deny" }, "\u4E0D\u53EF\u4EE5\u6267\u884C\u547D\u4EE4")
|
|
11964
|
+
)
|
|
11965
|
+
),
|
|
11966
|
+
h2("button", {
|
|
11967
|
+
type: "button",
|
|
11968
|
+
className: "dim-deliveryButton dim-accessDeleteUser",
|
|
11969
|
+
"data-kind": "danger",
|
|
11970
|
+
"aria-label": [
|
|
11971
|
+
localizeText(title),
|
|
11972
|
+
localizeText("\u5220\u9664"),
|
|
11973
|
+
localizeText("\u7528\u6237"),
|
|
11974
|
+
index + 1
|
|
11975
|
+
].join(" "),
|
|
11976
|
+
onClick: () => updateUsers(users.filter((_, userIndex) => userIndex !== index))
|
|
11977
|
+
}, "\u5220\u9664")
|
|
11978
|
+
)))
|
|
11979
|
+
)
|
|
11980
|
+
)
|
|
11981
|
+
);
|
|
11982
|
+
}
|
|
11983
|
+
function AccessPolicySettingsPage({ channel: channel4, account, rpcCall, onSaved }) {
|
|
11984
|
+
const definition = ACCESS_CHANNEL_DEFINITIONS[channel4];
|
|
11985
|
+
const initialPolicy = normalizeAccessPolicy(account?.accessPolicy);
|
|
11986
|
+
const initialKey = JSON.stringify(initialPolicy);
|
|
11987
|
+
const [draft, setDraft] = React20.useState(() => clonePolicy(
|
|
11988
|
+
initialPolicy ?? DEFAULT_ACCESS_POLICY
|
|
11989
|
+
));
|
|
11990
|
+
const [saving, setSaving] = React20.useState(false);
|
|
11991
|
+
const [feedback, setFeedback] = React20.useState(null);
|
|
11992
|
+
React20.useEffect(() => {
|
|
11993
|
+
const next = normalizeAccessPolicy(account?.accessPolicy);
|
|
11994
|
+
setDraft(clonePolicy(next ?? DEFAULT_ACCESS_POLICY));
|
|
11995
|
+
}, [account?.botId, initialKey]);
|
|
11996
|
+
React20.useEffect(() => {
|
|
11997
|
+
setFeedback(null);
|
|
11998
|
+
}, [account?.botId]);
|
|
11999
|
+
if (!definition) {
|
|
12000
|
+
return h2(
|
|
12001
|
+
"div",
|
|
12002
|
+
{ className: "dim-accessState", role: "alert" },
|
|
12003
|
+
"\u5F53\u524D\u6E20\u9053\u6682\u4E0D\u652F\u6301\u8BBF\u95EE\u8BBE\u7F6E\u3002"
|
|
12004
|
+
);
|
|
12005
|
+
}
|
|
12006
|
+
const save = async (event) => {
|
|
12007
|
+
event.preventDefault();
|
|
12008
|
+
setFeedback(null);
|
|
12009
|
+
setSaving(true);
|
|
12010
|
+
try {
|
|
12011
|
+
const policy = validateAccessPolicy(draft);
|
|
12012
|
+
if (typeof rpcCall !== "function") throw new Error("\u8BBF\u95EE\u8BBE\u7F6E\u6682\u4E0D\u53EF\u7528\u3002");
|
|
12013
|
+
const value = unwrapRpcResult10(await rpcCall(ACCESS_POLICY_ENDPOINT, {
|
|
12014
|
+
botId: account.botId,
|
|
12015
|
+
policy
|
|
12016
|
+
}));
|
|
12017
|
+
const saved = policyFromSnapshot(value, account.botId);
|
|
12018
|
+
if (!saved) throw new Error("\u670D\u52A1\u6CA1\u6709\u8FD4\u56DE\u5DF2\u4FDD\u5B58\u7684\u8BBF\u95EE\u7B56\u7565\uFF0C\u8BF7\u5237\u65B0\u540E\u91CD\u8BD5\u3002");
|
|
12019
|
+
setDraft(clonePolicy(saved));
|
|
12020
|
+
onSaved?.(saved);
|
|
12021
|
+
setFeedback({ tone: "success", message: "\u8BBF\u95EE\u8BBE\u7F6E\u5DF2\u4FDD\u5B58\u3002" });
|
|
12022
|
+
} catch (error) {
|
|
12023
|
+
setFeedback({
|
|
12024
|
+
tone: "error",
|
|
12025
|
+
message: error?.message || "\u8BBF\u95EE\u8BBE\u7F6E\u4FDD\u5B58\u5931\u8D25\uFF0C\u8BF7\u7A0D\u540E\u91CD\u8BD5\u3002"
|
|
12026
|
+
});
|
|
12027
|
+
} finally {
|
|
12028
|
+
setSaving(false);
|
|
12029
|
+
}
|
|
12030
|
+
};
|
|
12031
|
+
return h2(
|
|
12032
|
+
"form",
|
|
12033
|
+
{
|
|
12034
|
+
className: "dim-accessPage",
|
|
12035
|
+
onSubmit: (event) => void save(event)
|
|
12036
|
+
},
|
|
12037
|
+
initialPolicy ? null : h2(
|
|
12038
|
+
"div",
|
|
12039
|
+
{ className: "dim-accessState", role: "alert" },
|
|
12040
|
+
"\u8BBF\u95EE\u7B56\u7565\u5C1A\u672A\u5C31\u7EEA\uFF0C\u8BF7\u8FD4\u56DE\u673A\u5668\u4EBA\u5217\u8868\u5237\u65B0\u540E\u91CD\u8BD5\u3002"
|
|
12041
|
+
),
|
|
12042
|
+
h2(ScenePolicyEditor, {
|
|
12043
|
+
scene: "direct",
|
|
12044
|
+
title: "\u79C1\u804A",
|
|
12045
|
+
policy: draft.direct,
|
|
12046
|
+
userLabel: definition.directUserLabel,
|
|
12047
|
+
placeholder: definition.directPlaceholder,
|
|
12048
|
+
disabled: saving,
|
|
12049
|
+
onChange: (direct) => {
|
|
12050
|
+
setDraft((current) => ({ ...current, direct }));
|
|
12051
|
+
setFeedback(null);
|
|
12052
|
+
}
|
|
12053
|
+
}),
|
|
12054
|
+
h2(ScenePolicyEditor, {
|
|
12055
|
+
scene: "group",
|
|
12056
|
+
title: "\u7FA4\u804A",
|
|
12057
|
+
policy: draft.group,
|
|
12058
|
+
userLabel: definition.groupUserLabel ?? definition.directUserLabel,
|
|
12059
|
+
placeholder: definition.groupPlaceholder ?? definition.directPlaceholder,
|
|
12060
|
+
disabled: saving || definition.groupSupported === false,
|
|
12061
|
+
unsupported: definition.groupSupported === false,
|
|
12062
|
+
onChange: (group) => {
|
|
12063
|
+
setDraft((current) => ({ ...current, group }));
|
|
12064
|
+
setFeedback(null);
|
|
12065
|
+
}
|
|
12066
|
+
}),
|
|
12067
|
+
feedback ? h2("p", {
|
|
12068
|
+
className: "dim-accessFeedback",
|
|
12069
|
+
"data-tone": feedback.tone,
|
|
12070
|
+
role: feedback.tone === "error" ? "alert" : "status",
|
|
12071
|
+
"aria-live": "polite"
|
|
12072
|
+
}, feedback.message) : null,
|
|
12073
|
+
h2(
|
|
12074
|
+
"div",
|
|
12075
|
+
{ className: "dim-accessActions" },
|
|
12076
|
+
h2("button", {
|
|
12077
|
+
type: "submit",
|
|
12078
|
+
className: "dim-deliveryButton",
|
|
12079
|
+
"data-kind": "primary",
|
|
12080
|
+
disabled: saving || !initialPolicy
|
|
12081
|
+
}, saving ? "\u6B63\u5728\u4FDD\u5B58\u2026" : "\u4FDD\u5B58\u8BBF\u95EE\u8BBE\u7F6E")
|
|
12082
|
+
)
|
|
12083
|
+
);
|
|
12084
|
+
}
|
|
12085
|
+
|
|
12086
|
+
// plugin-src/client/delivery-settings.js
|
|
11860
12087
|
var DELIVERY_RPC_CHANNEL = "/dsh-im-delivery";
|
|
11861
12088
|
var DELIVERY_DOCS_URL = Object.freeze({
|
|
11862
12089
|
zh: "https://github.com/xmanrui/dsh-im/blob/main/PROACTIVE_DELIVERY.md",
|
|
@@ -11870,6 +12097,10 @@ var DELIVERY_ENDPOINTS = Object.freeze({
|
|
|
11870
12097
|
delete: "target.delete",
|
|
11871
12098
|
test: "target.test"
|
|
11872
12099
|
});
|
|
12100
|
+
var BOT_SETTINGS_TABS = Object.freeze([
|
|
12101
|
+
Object.freeze({ id: "delivery", label: "\u6295\u9012\u8BBE\u7F6E" }),
|
|
12102
|
+
Object.freeze({ id: "access", label: "\u8BBF\u95EE\u8BBE\u7F6E" })
|
|
12103
|
+
]);
|
|
11873
12104
|
var CHANNEL_DEFINITIONS = Object.freeze({
|
|
11874
12105
|
weixin: {
|
|
11875
12106
|
label: "\u5FAE\u4FE1",
|
|
@@ -11947,7 +12178,7 @@ var CHANNEL_DEFINITIONS = Object.freeze({
|
|
|
11947
12178
|
function presentError10(error, fallback) {
|
|
11948
12179
|
return error?.message || fallback;
|
|
11949
12180
|
}
|
|
11950
|
-
function
|
|
12181
|
+
function unwrapRpcResult11(result) {
|
|
11951
12182
|
if (result?.ok === true) return result.value;
|
|
11952
12183
|
if (result?.ok === false) {
|
|
11953
12184
|
const error = new Error(result.error?.message || "\u8BF7\u6C42\u5931\u8D25\uFF0C\u8BF7\u7A0D\u540E\u91CD\u8BD5\u3002");
|
|
@@ -12405,8 +12636,15 @@ function TargetRow({ definition, target, botId, connected, rpcCall, onChanged, o
|
|
|
12405
12636
|
) : null
|
|
12406
12637
|
);
|
|
12407
12638
|
}
|
|
12408
|
-
function DeliveryTargetSettingsPage({
|
|
12639
|
+
function DeliveryTargetSettingsPage({
|
|
12640
|
+
channel: channel4,
|
|
12641
|
+
account,
|
|
12642
|
+
rpcCall,
|
|
12643
|
+
accessRpcCall,
|
|
12644
|
+
onBack
|
|
12645
|
+
}) {
|
|
12409
12646
|
const definition = CHANNEL_DEFINITIONS[channel4];
|
|
12647
|
+
const [activeTabId, setActiveTabId] = React21.useState(BOT_SETTINGS_TABS[0].id);
|
|
12410
12648
|
const [phase, setPhase] = React21.useState("loading");
|
|
12411
12649
|
const [targets, setTargets] = React21.useState([]);
|
|
12412
12650
|
const [suggestionPhase, setSuggestionPhase] = React21.useState("idle");
|
|
@@ -12416,10 +12654,14 @@ function DeliveryTargetSettingsPage({ channel: channel4, account, rpcCall, onBac
|
|
|
12416
12654
|
const [editor, setEditor] = React21.useState(null);
|
|
12417
12655
|
const [saving, setSaving] = React21.useState(false);
|
|
12418
12656
|
const [botCopyState, setBotCopyState] = React21.useState(null);
|
|
12657
|
+
const [accessPolicy, setAccessPolicy] = React21.useState(account.accessPolicy);
|
|
12419
12658
|
const mounted = React21.useRef(true);
|
|
12659
|
+
React21.useEffect(() => {
|
|
12660
|
+
setAccessPolicy(account.accessPolicy);
|
|
12661
|
+
}, [account.botId, account.accessPolicy]);
|
|
12420
12662
|
const invoke = React21.useCallback(async (endpoint, payload = {}, signal) => {
|
|
12421
12663
|
if (typeof rpcCall !== "function") throw new Error("\u6295\u9012\u76EE\u6807\u8BBE\u7F6E\u6682\u4E0D\u53EF\u7528\u3002");
|
|
12422
|
-
return
|
|
12664
|
+
return unwrapRpcResult11(await rpcCall(endpoint, payload, signal));
|
|
12423
12665
|
}, [rpcCall]);
|
|
12424
12666
|
const loadTargets = React21.useCallback(async ({ signal, silent = false } = {}) => {
|
|
12425
12667
|
if (!silent) setPhase("loading");
|
|
@@ -12520,6 +12762,9 @@ function DeliveryTargetSettingsPage({ channel: channel4, account, rpcCall, onBac
|
|
|
12520
12762
|
setBotCopyState(presentError10(caught, "\u590D\u5236\u5931\u8D25\u3002"));
|
|
12521
12763
|
}
|
|
12522
12764
|
};
|
|
12765
|
+
const activeTab = BOT_SETTINGS_TABS.find((tab) => tab.id === activeTabId) ?? BOT_SETTINGS_TABS[0];
|
|
12766
|
+
const activeTabDomId = `dim-bot-settings-${activeTab.id}-tab`;
|
|
12767
|
+
const activePanelId = `dim-bot-settings-${activeTab.id}-panel`;
|
|
12523
12768
|
return h2(
|
|
12524
12769
|
"section",
|
|
12525
12770
|
{
|
|
@@ -12529,114 +12774,147 @@ function DeliveryTargetSettingsPage({ channel: channel4, account, rpcCall, onBac
|
|
|
12529
12774
|
h2(
|
|
12530
12775
|
"header",
|
|
12531
12776
|
{ className: "dim-deliveryHeader" },
|
|
12532
|
-
h2(DeliveryButton, { className: "dim-deliveryBack", onClick: onBack }, "\u2190 \u8FD4\u56DE\u673A\u5668\u4EBA\u5217\u8868")
|
|
12533
|
-
h2(
|
|
12534
|
-
"div",
|
|
12535
|
-
{ className: "dim-deliveryHeaderMeta" },
|
|
12536
|
-
h2(
|
|
12537
|
-
"a",
|
|
12538
|
-
{
|
|
12539
|
-
className: "dim-deliveryDocsLink",
|
|
12540
|
-
href: isEnglish() ? DELIVERY_DOCS_URL.en : DELIVERY_DOCS_URL.zh,
|
|
12541
|
-
target: "_blank",
|
|
12542
|
-
rel: "noopener noreferrer",
|
|
12543
|
-
"aria-label": "\u6253\u5F00\u4E3B\u52A8\u6295\u9012\u4F7F\u7528\u6587\u6863"
|
|
12544
|
-
},
|
|
12545
|
-
h2("span", null, "\u4F7F\u7528\u6587\u6863"),
|
|
12546
|
-
h2("span", { "aria-hidden": "true" }, "\u2197")
|
|
12547
|
-
)
|
|
12548
|
-
)
|
|
12777
|
+
h2(DeliveryButton, { className: "dim-deliveryBack", onClick: onBack }, "\u2190 \u8FD4\u56DE\u673A\u5668\u4EBA\u5217\u8868")
|
|
12549
12778
|
),
|
|
12550
12779
|
h2(
|
|
12551
|
-
"
|
|
12552
|
-
{ className: "dim-
|
|
12553
|
-
h2(
|
|
12554
|
-
"
|
|
12555
|
-
|
|
12556
|
-
|
|
12557
|
-
|
|
12558
|
-
|
|
12559
|
-
|
|
12560
|
-
|
|
12561
|
-
|
|
12562
|
-
|
|
12563
|
-
"
|
|
12564
|
-
|
|
12565
|
-
|
|
12566
|
-
|
|
12567
|
-
|
|
12568
|
-
),
|
|
12569
|
-
botCopyState ? h2("p", { className: "dim-targetFeedback", role: "status" }, botCopyState) : null
|
|
12780
|
+
"div",
|
|
12781
|
+
{ className: "dim-botSettingsTabsBar" },
|
|
12782
|
+
h2("nav", {
|
|
12783
|
+
className: "dim-botSettingsTabs",
|
|
12784
|
+
role: "tablist",
|
|
12785
|
+
"aria-label": "\u673A\u5668\u4EBA\u8BBE\u7F6E\u9875\u7B7E"
|
|
12786
|
+
}, BOT_SETTINGS_TABS.map((tab) => h2("button", {
|
|
12787
|
+
key: tab.id,
|
|
12788
|
+
id: `dim-bot-settings-${tab.id}-tab`,
|
|
12789
|
+
type: "button",
|
|
12790
|
+
role: "tab",
|
|
12791
|
+
className: "dim-botSettingsTab",
|
|
12792
|
+
"aria-selected": tab.id === activeTab.id,
|
|
12793
|
+
"aria-controls": `dim-bot-settings-${tab.id}-panel`,
|
|
12794
|
+
tabIndex: tab.id === activeTab.id ? 0 : -1,
|
|
12795
|
+
onClick: () => setActiveTabId(tab.id)
|
|
12796
|
+
}, tab.label)))
|
|
12570
12797
|
),
|
|
12571
12798
|
h2(
|
|
12572
|
-
"
|
|
12573
|
-
{
|
|
12574
|
-
|
|
12575
|
-
"
|
|
12576
|
-
|
|
12799
|
+
"div",
|
|
12800
|
+
{
|
|
12801
|
+
id: activePanelId,
|
|
12802
|
+
className: "dim-botSettingsTabPanel",
|
|
12803
|
+
role: "tabpanel",
|
|
12804
|
+
"aria-labelledby": activeTabDomId
|
|
12805
|
+
},
|
|
12806
|
+
activeTab.id === "access" ? h2(AccessPolicySettingsPage, {
|
|
12807
|
+
channel: channel4,
|
|
12808
|
+
account: { ...account, accessPolicy },
|
|
12809
|
+
rpcCall: accessRpcCall,
|
|
12810
|
+
onSaved: setAccessPolicy
|
|
12811
|
+
}) : h2(
|
|
12812
|
+
React21.Fragment,
|
|
12813
|
+
null,
|
|
12577
12814
|
h2(
|
|
12578
|
-
"
|
|
12579
|
-
|
|
12580
|
-
h2(
|
|
12581
|
-
|
|
12815
|
+
"section",
|
|
12816
|
+
{ className: "dim-deliveryIdentity", "aria-labelledby": "dim-delivery-bot-title" },
|
|
12817
|
+
h2(
|
|
12818
|
+
"div",
|
|
12819
|
+
{ className: "dim-deliveryIdentityHeading" },
|
|
12820
|
+
h2(
|
|
12821
|
+
"h2",
|
|
12822
|
+
{ id: "dim-delivery-bot-title", className: "dim-deliveryBotName" },
|
|
12823
|
+
account.botName || "\u673A\u5668\u4EBA\u8BBE\u7F6E"
|
|
12824
|
+
),
|
|
12825
|
+
h2(
|
|
12826
|
+
"a",
|
|
12827
|
+
{
|
|
12828
|
+
className: "dim-deliveryDocsLink",
|
|
12829
|
+
href: isEnglish() ? DELIVERY_DOCS_URL.en : DELIVERY_DOCS_URL.zh,
|
|
12830
|
+
target: "_blank",
|
|
12831
|
+
rel: "noopener noreferrer",
|
|
12832
|
+
"aria-label": "\u6253\u5F00\u4E3B\u52A8\u6295\u9012\u4F7F\u7528\u6587\u6863"
|
|
12833
|
+
},
|
|
12834
|
+
h2("span", null, "\u4F7F\u7528\u6587\u6863"),
|
|
12835
|
+
h2("span", { "aria-hidden": "true" }, "\u2197")
|
|
12836
|
+
)
|
|
12837
|
+
),
|
|
12838
|
+
h2(
|
|
12839
|
+
"div",
|
|
12840
|
+
{ className: "dim-deliveryBotId" },
|
|
12841
|
+
h2("span", null, "Bot ID"),
|
|
12842
|
+
h2("code", { title: account.botId }, account.botId),
|
|
12843
|
+
h2(DeliveryButton, { onClick: () => void copyBotId() }, "\u590D\u5236")
|
|
12844
|
+
),
|
|
12845
|
+
botCopyState ? h2("p", { className: "dim-targetFeedback", role: "status" }, botCopyState) : null
|
|
12582
12846
|
),
|
|
12583
|
-
h2(
|
|
12584
|
-
|
|
12585
|
-
|
|
12586
|
-
|
|
12587
|
-
|
|
12588
|
-
|
|
12589
|
-
|
|
12590
|
-
|
|
12591
|
-
|
|
12592
|
-
|
|
12593
|
-
|
|
12594
|
-
|
|
12595
|
-
|
|
12596
|
-
|
|
12597
|
-
|
|
12598
|
-
|
|
12599
|
-
|
|
12600
|
-
|
|
12601
|
-
|
|
12602
|
-
|
|
12603
|
-
|
|
12604
|
-
|
|
12605
|
-
|
|
12606
|
-
|
|
12607
|
-
|
|
12608
|
-
|
|
12609
|
-
|
|
12610
|
-
|
|
12611
|
-
|
|
12612
|
-
|
|
12613
|
-
|
|
12614
|
-
|
|
12615
|
-
|
|
12616
|
-
|
|
12617
|
-
|
|
12618
|
-
|
|
12619
|
-
|
|
12620
|
-
|
|
12621
|
-
|
|
12622
|
-
|
|
12623
|
-
|
|
12624
|
-
|
|
12625
|
-
|
|
12626
|
-
|
|
12627
|
-
|
|
12628
|
-
|
|
12629
|
-
|
|
12630
|
-
|
|
12631
|
-
|
|
12632
|
-
|
|
12633
|
-
|
|
12634
|
-
|
|
12635
|
-
|
|
12636
|
-
|
|
12637
|
-
|
|
12638
|
-
|
|
12639
|
-
|
|
12847
|
+
h2(
|
|
12848
|
+
"section",
|
|
12849
|
+
{ className: "dim-deliveryTargets", "aria-labelledby": "dim-delivery-targets-title" },
|
|
12850
|
+
h2(
|
|
12851
|
+
"div",
|
|
12852
|
+
{ className: "dim-deliverySectionHeading" },
|
|
12853
|
+
h2(
|
|
12854
|
+
"div",
|
|
12855
|
+
null,
|
|
12856
|
+
h2("h3", { id: "dim-delivery-targets-title" }, "\u6295\u9012\u76EE\u6807"),
|
|
12857
|
+
account.connected ? null : h2("p", null, "\u673A\u5668\u4EBA\u5F53\u524D\u79BB\u7EBF\uFF1B\u4ECD\u53EF\u914D\u7F6E\u76EE\u6807\uFF0C\u6062\u590D\u8FDE\u63A5\u540E\u518D\u6D4B\u8BD5\u3002")
|
|
12858
|
+
),
|
|
12859
|
+
h2(DeliveryButton, {
|
|
12860
|
+
kind: "primary",
|
|
12861
|
+
onClick: openSuggestionPicker,
|
|
12862
|
+
disabled: Boolean(editor) || phase !== "ready",
|
|
12863
|
+
title: phase === "ready" ? void 0 : "\u8BF7\u5148\u5B8C\u6210\u6295\u9012\u76EE\u6807\u8BFB\u53D6"
|
|
12864
|
+
}, "\u65B0\u5EFA\u76EE\u6807")
|
|
12865
|
+
),
|
|
12866
|
+
editor?.mode === "suggestions" ? h2(TargetSuggestionPicker, {
|
|
12867
|
+
definition,
|
|
12868
|
+
phase: suggestionPhase,
|
|
12869
|
+
suggestions,
|
|
12870
|
+
error: suggestionError,
|
|
12871
|
+
targets,
|
|
12872
|
+
onRefresh: loadSuggestions,
|
|
12873
|
+
onSelect: selectSuggestion,
|
|
12874
|
+
onManual: () => setEditor({
|
|
12875
|
+
mode: "create",
|
|
12876
|
+
source: "manual",
|
|
12877
|
+
draftKey: "manual",
|
|
12878
|
+
initialValue: { targetId: randomTargetId(targets) }
|
|
12879
|
+
}),
|
|
12880
|
+
onCancel: () => setEditor(null)
|
|
12881
|
+
}) : editor ? h2(TargetForm, {
|
|
12882
|
+
key: editor.mode === "edit" ? editor.target.targetId : editor.draftKey,
|
|
12883
|
+
definition,
|
|
12884
|
+
mode: editor.mode,
|
|
12885
|
+
initialValue: editor.mode === "edit" ? editor.target : editor.initialValue,
|
|
12886
|
+
source: editor.source,
|
|
12887
|
+
busy: saving,
|
|
12888
|
+
connected: account.connected,
|
|
12889
|
+
onCancel: () => setEditor(editor.source === "suggestion" ? { mode: "suggestions" } : null),
|
|
12890
|
+
onSave: saveTarget,
|
|
12891
|
+
onTest: (target) => invoke(DELIVERY_ENDPOINTS.test, {
|
|
12892
|
+
botId: account.botId,
|
|
12893
|
+
target
|
|
12894
|
+
})
|
|
12895
|
+
}) : null,
|
|
12896
|
+
phase === "loading" ? h2("div", { className: "dim-deliveryState", "aria-busy": "true" }, "\u6B63\u5728\u8BFB\u53D6\u6295\u9012\u76EE\u6807\u2026") : phase === "error" ? h2(
|
|
12897
|
+
"div",
|
|
12898
|
+
{ className: "dim-deliveryState", role: "alert" },
|
|
12899
|
+
h2("p", null, error),
|
|
12900
|
+
h2(DeliveryButton, { onClick: () => void loadTargets() }, "\u91CD\u65B0\u8BFB\u53D6")
|
|
12901
|
+
) : targets.length === 0 ? h2(
|
|
12902
|
+
"div",
|
|
12903
|
+
{ className: "dim-deliveryState dim-deliveryEmpty" },
|
|
12904
|
+
h2("strong", null, "\u5C1A\u672A\u914D\u7F6E\u6295\u9012\u76EE\u6807"),
|
|
12905
|
+
h2("p", null, "\u70B9\u51FB\u201C\u65B0\u5EFA\u76EE\u6807\u201D\u53EF\u4ECE\u5DF2\u804A\u8FC7\u7684\u4F1A\u8BDD\u9009\u62E9\uFF0C\u4E5F\u53EF\u624B\u52A8\u586B\u5199\u3002")
|
|
12906
|
+
) : h2("ul", { className: "dim-targetList" }, targets.map((target) => h2(TargetRow, {
|
|
12907
|
+
key: target.targetId,
|
|
12908
|
+
definition,
|
|
12909
|
+
target,
|
|
12910
|
+
botId: account.botId,
|
|
12911
|
+
connected: account.connected,
|
|
12912
|
+
rpcCall: invoke,
|
|
12913
|
+
onChanged: () => loadTargets({ silent: true }),
|
|
12914
|
+
onEdit: () => setEditor({ mode: "edit", target, source: "edit" })
|
|
12915
|
+
})))
|
|
12916
|
+
)
|
|
12917
|
+
)
|
|
12640
12918
|
)
|
|
12641
12919
|
);
|
|
12642
12920
|
}
|
|
@@ -13067,9 +13345,18 @@ var CSS11 = String.raw`
|
|
|
13067
13345
|
.dim-botSettingsButton:focus-visible { outline: 2px solid var(--dsw-alias-state-business-primary, #3370ff); outline-offset: 2px; }
|
|
13068
13346
|
.dim-botSettingsTooltip { position: absolute; top: calc(100% + 6px); right: 0; z-index: 30; width: max-content; padding: 6px 9px; border: 1px solid var(--dsw-alias-border-l2, #dfe1e5); border-radius: 7px; color: var(--dsw-alias-label-primary, #1f2329); background: var(--dsw-alias-bg-layer-3, #fff); box-shadow: 0 8px 24px rgb(31 35 41 / 14%); font-size: 11px; line-height: 16px; opacity: 0; visibility: hidden; transform: translateY(-3px); pointer-events: none; transition: opacity .15s ease, transform .15s ease, visibility .15s ease; }
|
|
13069
13347
|
.dim-botSettingsAction:hover .dim-botSettingsTooltip, .dim-botSettingsAction:focus-within .dim-botSettingsTooltip { opacity: 1; visibility: visible; transform: translateY(0); }
|
|
13070
|
-
.dim-deliveryPage { min-width: 0; display: grid;
|
|
13348
|
+
.dim-deliveryPage { min-width: 0; display: grid; }
|
|
13071
13349
|
.dim-deliveryHeader { min-width: 0; display: flex; align-items: center; justify-content: space-between; gap: 16px; }
|
|
13072
|
-
.dim-
|
|
13350
|
+
.dim-botSettingsTabsBar { min-width: 0; margin-top: 10px; border-bottom: 1px solid var(--dsw-alias-border-l2, #dfe1e5); }
|
|
13351
|
+
.dim-botSettingsTabs { min-width: 0; display: flex; align-items: flex-end; gap: 24px; overflow-x: auto; scrollbar-width: none; }
|
|
13352
|
+
.dim-botSettingsTabs::-webkit-scrollbar { display: none; }
|
|
13353
|
+
.dim-botSettingsTab { position: relative; min-height: 38px; flex: none; display: inline-flex; align-items: center; justify-content: center; padding: 6px 2px 9px; border: 0; color: var(--dsw-alias-label-secondary, #646a73); background: transparent; font: inherit; font-size: 13px; line-height: 20px; font-weight: 560; white-space: nowrap; cursor: pointer; transition: color .15s ease; }
|
|
13354
|
+
.dim-botSettingsTab::after { content: ''; position: absolute; right: 0; bottom: -1px; left: 0; height: 2px; border-radius: 2px 2px 0 0; background: transparent; transform: scaleX(.45); transition: background .15s ease, transform .15s ease; }
|
|
13355
|
+
.dim-botSettingsTab:hover:not([aria-selected="true"]) { color: var(--dsw-alias-label-primary, #1f2329); }
|
|
13356
|
+
.dim-botSettingsTab[aria-selected="true"] { color: var(--dsw-alias-state-business-primary, #3370ff); font-weight: 650; }
|
|
13357
|
+
.dim-botSettingsTab[aria-selected="true"]::after { background: var(--dsw-alias-state-business-primary, #3370ff); transform: scaleX(1); }
|
|
13358
|
+
.dim-botSettingsTab:focus-visible { outline: 2px solid var(--dsw-alias-state-business-primary, #3370ff); outline-offset: -2px; border-radius: 5px; }
|
|
13359
|
+
.dim-botSettingsTabPanel { min-width: 0; display: grid; gap: 14px; padding-top: 14px; }
|
|
13073
13360
|
.dim-deliveryDocsLink { min-height: 30px; flex: none; display: inline-flex; align-items: center; gap: 4px; padding: 5px 8px; border-radius: 7px; color: var(--dsw-alias-state-business-primary, #3370ff); font-size: 12px; line-height: 18px; text-decoration: none; white-space: nowrap; }
|
|
13074
13361
|
.dim-deliveryDocsLink:hover { background: color-mix(in srgb, var(--dsw-alias-state-business-primary, #3370ff) 8%, transparent); }
|
|
13075
13362
|
.dim-deliveryDocsLink:focus-visible { outline: 2px solid var(--dsw-alias-state-business-primary, #3370ff); outline-offset: 2px; }
|
|
@@ -13081,6 +13368,7 @@ var CSS11 = String.raw`
|
|
|
13081
13368
|
.dim-deliveryButton[data-kind="danger"] { color: var(--dsw-alias-state-error-primary, #d54941); }
|
|
13082
13369
|
.dim-deliveryBack { flex: none; border-color: transparent; background: transparent; }
|
|
13083
13370
|
.dim-deliveryIdentity, .dim-deliveryTargets { min-width: 0; padding: 16px; border: 1px solid var(--dsw-alias-border-l2, #dfe1e5); border-radius: 12px; background: var(--dsw-alias-bg-layer-3, #fff); }
|
|
13371
|
+
.dim-deliveryIdentityHeading { min-width: 0; display: flex; align-items: center; justify-content: space-between; gap: 12px; }
|
|
13084
13372
|
.dim-deliveryBotName, .dim-deliverySectionHeading h3 { min-width: 0; overflow: hidden; margin: 0; font-size: 15px; line-height: 22px; font-weight: 650; text-overflow: ellipsis; white-space: nowrap; }
|
|
13085
13373
|
.dim-deliveryIdentity > div:first-child p, .dim-deliverySectionHeading p { margin: 2px 0 0; color: var(--dsw-alias-label-secondary, #646a73); font-size: 12px; line-height: 18px; }
|
|
13086
13374
|
.dim-deliveryBotId { min-width: 0; display: grid; grid-template-columns: max-content minmax(0, 1fr) max-content; align-items: center; gap: 10px; margin-top: 12px; padding: 10px 12px; border-radius: 9px; background: var(--dsw-alias-bg-module-platform, #f7f8fa); }
|
|
@@ -13123,6 +13411,38 @@ var CSS11 = String.raw`
|
|
|
13123
13411
|
.dim-targetField input[readonly] { color: var(--dsw-alias-label-secondary, #646a73); background: var(--dsw-alias-bg-module-platform, #f7f8fa); }
|
|
13124
13412
|
.dim-targetFormError { margin: 10px 0 0; font-size: 12px; line-height: 18px; }
|
|
13125
13413
|
.dim-targetFormActions { display: flex; justify-content: flex-end; gap: 7px; margin-top: 12px; }
|
|
13414
|
+
.dim-accessPage { min-width: 0; display: grid; gap: 14px; }
|
|
13415
|
+
.dim-accessScene { position: relative; min-width: 0; margin: 0; padding: 16px; border: 1px solid var(--dsw-alias-border-l2, #dfe1e5); border-radius: 12px; background: var(--dsw-alias-bg-layer-3, #fff); }
|
|
13416
|
+
.dim-accessScene > legend { padding: 0 6px; color: var(--dsw-alias-label-primary, #1f2329); font-size: 15px; line-height: 22px; font-weight: 650; }
|
|
13417
|
+
.dim-accessLegendContent { display: inline-flex; align-items: center; gap: 6px; }
|
|
13418
|
+
.dim-panel .dim-accessLegendHelp { position: static; }
|
|
13419
|
+
.dim-accessLegendHelp .dim-channelTooltip { top: 20px; right: auto; left: 16px; width: min(320px, calc(100% - 32px)); max-width: none; }
|
|
13420
|
+
.dim-accessControls { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 12px; }
|
|
13421
|
+
.dim-accessControls[data-mode="allowlist"] { grid-template-columns: minmax(0, 1fr); }
|
|
13422
|
+
.dim-accessField { min-width: 0; display: grid; align-content: start; gap: 5px; color: var(--dsw-alias-label-secondary, #646a73); font-size: 11px; line-height: 16px; }
|
|
13423
|
+
.dim-accessField input, .dim-accessField select { width: 100%; min-width: 0; height: 36px; padding: 0 9px; border: 1px solid var(--dsw-alias-border-l2, #dfe1e5); border-radius: 7px; color: var(--dsw-alias-label-primary, #1f2329); background: var(--dsw-alias-bg-layer-1, #fff); font: inherit; font-size: 12px; }
|
|
13424
|
+
.dim-accessField input:focus, .dim-accessField select:focus { outline: 2px solid color-mix(in srgb, var(--dsw-alias-state-business-primary, #3370ff) 28%, transparent); border-color: var(--dsw-alias-state-business-primary, #3370ff); }
|
|
13425
|
+
.dim-accessUsers { min-width: 0; margin-top: 14px; padding-top: 14px; border-top: 1px solid var(--dsw-alias-border-l1, #eef0f3); }
|
|
13426
|
+
.dim-accessUsersHeading { position: relative; min-width: 0; display: flex; align-items: flex-start; justify-content: space-between; gap: 12px; }
|
|
13427
|
+
.dim-accessUsersHeading > div { min-width: 0; }
|
|
13428
|
+
.dim-accessUsersTitle { display: inline-flex; align-items: center; gap: 6px; }
|
|
13429
|
+
.dim-accessUsersHeading strong { color: var(--dsw-alias-label-primary, #1f2329); font-size: 13px; line-height: 20px; font-weight: 620; }
|
|
13430
|
+
.dim-accessUsersHeading p { margin: 2px 0 0; color: var(--dsw-alias-label-secondary, #646a73); font-size: 11px; line-height: 17px; }
|
|
13431
|
+
.dim-panel .dim-accessUsersHelp { position: static; }
|
|
13432
|
+
.dim-accessUsersHelp .dim-channelTooltip { top: calc(100% + 7px); right: auto; left: 0; width: min(320px, 100%); max-width: none; }
|
|
13433
|
+
.dim-accessAddUser { width: 32px; height: 32px; min-height: 32px; flex: 0 0 32px; padding: 0; font-size: 20px; line-height: 1; }
|
|
13434
|
+
.dim-accessUsersEmpty { margin-top: 10px; padding: 15px 12px; border: 1px dashed var(--dsw-alias-border-l2, #dfe1e5); border-radius: 8px; color: var(--dsw-alias-label-tertiary, #8f959e); font-size: 12px; line-height: 18px; text-align: center; }
|
|
13435
|
+
.dim-accessUserList { display: grid; gap: 9px; margin: 10px 0 0; padding: 0; list-style: none; }
|
|
13436
|
+
.dim-accessUserRow { min-width: 0; display: grid; grid-template-columns: minmax(0, 1fr) minmax(145px, 180px) max-content; align-items: end; gap: 10px; padding: 11px; border: 1px solid var(--dsw-alias-border-l1, #eef0f3); border-radius: 9px; background: var(--dsw-alias-bg-module-platform, #f7f8fa); }
|
|
13437
|
+
.dim-accessDeleteUser { margin-bottom: 1px; }
|
|
13438
|
+
.dim-accessUnsupported { padding: 18px 14px; border: 1px dashed var(--dsw-alias-border-l2, #dfe1e5); border-radius: 9px; color: var(--dsw-alias-label-secondary, #646a73); background: var(--dsw-alias-bg-module-platform, #f7f8fa); text-align: center; }
|
|
13439
|
+
.dim-accessUnsupported strong { color: var(--dsw-alias-label-primary, #1f2329); font-size: 13px; line-height: 20px; }
|
|
13440
|
+
.dim-accessUnsupported p { margin: 4px 0 0; font-size: 12px; line-height: 18px; }
|
|
13441
|
+
.dim-accessState { padding: 11px 13px; border: 1px solid color-mix(in srgb, var(--dsw-alias-state-warn-primary, #d97706) 24%, var(--dsw-alias-border-l2, #dfe1e5)); border-radius: 9px; color: var(--dsw-alias-state-warn-primary, #d97706); background: color-mix(in srgb, var(--dsw-alias-state-warn-primary, #d97706) 7%, var(--dsw-alias-bg-layer-1, #fff)); font-size: 12px; line-height: 18px; }
|
|
13442
|
+
.dim-accessFeedback { margin: 0; padding: 10px 12px; border-radius: 8px; color: var(--dsw-alias-label-secondary, #646a73); background: var(--dsw-alias-bg-module-platform, #f7f8fa); font-size: 12px; line-height: 18px; }
|
|
13443
|
+
.dim-accessFeedback[data-tone="success"] { color: var(--dsw-alias-state-success-primary, #20a162); }
|
|
13444
|
+
.dim-accessFeedback[data-tone="error"] { color: var(--dsw-alias-state-error-primary, #d54941); }
|
|
13445
|
+
.dim-accessActions { display: flex; justify-content: flex-end; }
|
|
13126
13446
|
.dim-panel .dim-botCard .dim-cardFooter { margin-top: 0; }
|
|
13127
13447
|
.dim-panel .ddt-headingCopy { display: none; }
|
|
13128
13448
|
.dim-panel .ddt-qrFrame, .dim-panel .ddt-countdown { width: min(270px, 100%); }
|
|
@@ -13146,6 +13466,9 @@ var CSS11 = String.raw`
|
|
|
13146
13466
|
.dim-targetActions { justify-content: flex-start; }
|
|
13147
13467
|
.dim-targetFormGrid { grid-template-columns: minmax(0, 1fr); }
|
|
13148
13468
|
.dim-targetSuggestionHeading { align-items: stretch; flex-direction: column; }
|
|
13469
|
+
.dim-accessControls { grid-template-columns: minmax(0, 1fr); }
|
|
13470
|
+
.dim-accessUserRow { grid-template-columns: minmax(0, 1fr); }
|
|
13471
|
+
.dim-accessDeleteUser { justify-self: start; }
|
|
13149
13472
|
}
|
|
13150
13473
|
@media (max-width: 840px) {
|
|
13151
13474
|
.dim-title { align-items: flex-start; }
|
|
@@ -13169,11 +13492,12 @@ var CSS11 = String.raw`
|
|
|
13169
13492
|
.dim-rail { grid-template-columns: minmax(0, 1fr); }
|
|
13170
13493
|
.dim-loopbackRecovery { align-items: stretch; flex-direction: column; gap: 12px; }
|
|
13171
13494
|
.dim-loopbackRecoveryAction { width: 100%; }
|
|
13172
|
-
.dim-
|
|
13173
|
-
.dim-
|
|
13495
|
+
.dim-deliverySectionHeading { align-items: stretch; flex-direction: column; }
|
|
13496
|
+
.dim-botSettingsTabs { gap: 18px; }
|
|
13174
13497
|
.dim-deliveryBotId { grid-template-columns: minmax(0, 1fr) max-content; }
|
|
13175
13498
|
.dim-deliveryBotId > span { grid-column: 1 / -1; }
|
|
13176
13499
|
.dim-targetActions .dim-deliveryButton { flex: 1 1 auto; }
|
|
13500
|
+
.dim-accessActions .dim-deliveryButton { width: 100%; }
|
|
13177
13501
|
.dim-directoryPickerBackdrop { padding: 10px; }
|
|
13178
13502
|
.dim-directoryPicker { height: calc(100vh - 20px); min-height: 0; border-radius: 14px; }
|
|
13179
13503
|
.dim-directoryPickerHeader { padding: 18px 17px 14px; }
|
|
@@ -13985,6 +14309,7 @@ function IMSettingsTab({
|
|
|
13985
14309
|
channel: active.id,
|
|
13986
14310
|
account: deliverySettings,
|
|
13987
14311
|
rpcCall: rpcCalls.deliveryRpcCall,
|
|
14312
|
+
accessRpcCall: rpcCalls[`${active.id}RpcCall`],
|
|
13988
14313
|
onBack: () => setDeliverySettings(null)
|
|
13989
14314
|
}) : active.id === "weixin" ? h2(WeixinSettingsTab, { rpcCall: rpcCalls.weixinRpcCall }) : active.id === "feishu" ? h2(FeishuSettingsTab, { rpcCall: rpcCalls.feishuRpcCall }) : active.id === "dingtalk" ? h2(DingtalkSettingsTab, { rpcCall: rpcCalls.dingtalkRpcCall }) : active.id === "wecom" ? h2(WecomSettingsTab, { rpcCall: rpcCalls.wecomRpcCall }) : active.id === "qq" ? h2(QqSettingsTab, { rpcCall: rpcCalls.qqRpcCall }) : active.id === "slack" ? h2(SlackSettingsTab, { rpcCall: rpcCalls.slackRpcCall }) : active.id === "telegram" ? h2(TelegramSettingsTab, { rpcCall: rpcCalls.telegramRpcCall }) : active.id === "discord" ? h2(DiscordSettingsTab, { rpcCall: rpcCalls.discordRpcCall }) : active.id === "whatsapp" ? h2(WhatsappSettingsTab, { rpcCall: rpcCalls.whatsappRpcCall }) : h2(OfficeSettingsTab, { rpcCall: rpcCalls.officeRpcCall })
|
|
13990
14315
|
)
|