@openclaw/crabline 0.1.11 → 0.1.13
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +137 -23
- package/dist/src/bin/crabline.js +3 -1
- package/dist/src/bin/crabline.js.map +1 -1
- package/dist/src/cli/program.d.ts +5 -1
- package/dist/src/cli/program.js +281 -52
- package/dist/src/cli/program.js.map +1 -1
- package/dist/src/config/load.js +39 -3
- package/dist/src/config/load.js.map +1 -1
- package/dist/src/config/schema.d.ts +20 -0
- package/dist/src/config/schema.js +163 -35
- package/dist/src/config/schema.js.map +1 -1
- package/dist/src/core/errors.d.ts +1 -0
- package/dist/src/core/errors.js +6 -3
- package/dist/src/core/errors.js.map +1 -1
- package/dist/src/core/http-path.d.ts +1 -0
- package/dist/src/core/http-path.js +14 -0
- package/dist/src/core/http-path.js.map +1 -0
- package/dist/src/core/matcher.d.ts +3 -1
- package/dist/src/core/matcher.js +58 -2
- package/dist/src/core/matcher.js.map +1 -1
- package/dist/src/core/nonces.d.ts +2 -0
- package/dist/src/core/nonces.js +11 -1
- package/dist/src/core/nonces.js.map +1 -1
- package/dist/src/core/reporters.d.ts +5 -0
- package/dist/src/core/reporters.js +26 -2
- package/dist/src/core/reporters.js.map +1 -1
- package/dist/src/core/run.d.ts +3 -1
- package/dist/src/core/run.js +178 -66
- package/dist/src/core/run.js.map +1 -1
- package/dist/src/index.d.ts +12 -10
- package/dist/src/index.js +6 -5
- package/dist/src/index.js.map +1 -1
- package/dist/src/matrix-ids.d.ts +5 -0
- package/dist/src/matrix-ids.js +83 -0
- package/dist/src/matrix-ids.js.map +1 -0
- package/dist/src/openclaw/artifact-generation.d.ts +7 -6
- package/dist/src/openclaw/artifact-generation.js +385 -41
- package/dist/src/openclaw/artifact-generation.js.map +1 -1
- package/dist/src/openclaw/bridges/discord.d.ts +1 -0
- package/dist/src/openclaw/bridges/discord.js +149 -0
- package/dist/src/openclaw/bridges/discord.js.map +1 -0
- package/dist/src/openclaw/bridges/matrix.js +22 -5
- package/dist/src/openclaw/bridges/matrix.js.map +1 -1
- package/dist/src/openclaw/bridges/mattermost.js +14 -9
- package/dist/src/openclaw/bridges/mattermost.js.map +1 -1
- package/dist/src/openclaw/bridges/probe-response.d.ts +1 -0
- package/dist/src/openclaw/bridges/probe-response.js +5 -0
- package/dist/src/openclaw/bridges/probe-response.js.map +1 -0
- package/dist/src/openclaw/bridges/signal.js +16 -7
- package/dist/src/openclaw/bridges/signal.js.map +1 -1
- package/dist/src/openclaw/bridges/slack.js +117 -24
- package/dist/src/openclaw/bridges/slack.js.map +1 -1
- package/dist/src/openclaw/bridges/telegram.js +46 -20
- package/dist/src/openclaw/bridges/telegram.js.map +1 -1
- package/dist/src/openclaw/bridges/whatsapp.js +33 -17
- package/dist/src/openclaw/bridges/whatsapp.js.map +1 -1
- package/dist/src/openclaw/bridges/zalo.js +9 -4
- package/dist/src/openclaw/bridges/zalo.js.map +1 -1
- package/dist/src/openclaw/outbound-contract.js +3 -0
- package/dist/src/openclaw/outbound-contract.js.map +1 -1
- package/dist/src/openclaw/private-file.d.ts +38 -3
- package/dist/src/openclaw/private-file.js +2008 -87
- package/dist/src/openclaw/private-file.js.map +1 -1
- package/dist/src/openclaw/{smoke-lock.d.ts → provider-readiness-lock.d.ts} +14 -5
- package/dist/src/openclaw/provider-readiness-lock.js +1320 -0
- package/dist/src/openclaw/provider-readiness-lock.js.map +1 -0
- package/dist/src/openclaw/shared.d.ts +10 -17
- package/dist/src/openclaw/shared.js +53 -19
- package/dist/src/openclaw/shared.js.map +1 -1
- package/dist/src/openclaw.d.ts +3 -5
- package/dist/src/openclaw.js +245 -60
- package/dist/src/openclaw.js.map +1 -1
- package/dist/src/platform/process-owned-lock.d.ts +11 -0
- package/dist/src/platform/process-owned-lock.js +1698 -0
- package/dist/src/platform/process-owned-lock.js.map +1 -0
- package/dist/src/platform/recorder-directory.d.ts +1 -0
- package/dist/src/platform/recorder-directory.js +14 -0
- package/dist/src/platform/recorder-directory.js.map +1 -0
- package/dist/src/platform/windows-acl.d.ts +18 -0
- package/dist/src/platform/windows-acl.js +1367 -0
- package/dist/src/platform/windows-acl.js.map +1 -0
- package/dist/src/platform/windows-lock-root.d.ts +13 -0
- package/dist/src/platform/windows-lock-root.js +98 -0
- package/dist/src/platform/windows-lock-root.js.map +1 -0
- package/dist/src/providers/builtin/discord.d.ts +4 -0
- package/dist/src/providers/builtin/discord.js +52 -9
- package/dist/src/providers/builtin/discord.js.map +1 -1
- package/dist/src/providers/builtin/external-webhook-auth.d.ts +1 -0
- package/dist/src/providers/builtin/external-webhook-auth.js +38 -1
- package/dist/src/providers/builtin/external-webhook-auth.js.map +1 -1
- package/dist/src/providers/builtin/feishu.d.ts +1 -0
- package/dist/src/providers/builtin/feishu.js +96 -26
- package/dist/src/providers/builtin/feishu.js.map +1 -1
- package/dist/src/providers/builtin/googlechat.d.ts +1 -0
- package/dist/src/providers/builtin/googlechat.js +95 -26
- package/dist/src/providers/builtin/googlechat.js.map +1 -1
- package/dist/src/providers/builtin/imessage.js +60 -17
- package/dist/src/providers/builtin/imessage.js.map +1 -1
- package/dist/src/providers/builtin/loopback.js +88 -35
- package/dist/src/providers/builtin/loopback.js.map +1 -1
- package/dist/src/providers/builtin/matrix.d.ts +2 -2
- package/dist/src/providers/builtin/matrix.js +78 -21
- package/dist/src/providers/builtin/matrix.js.map +1 -1
- package/dist/src/providers/builtin/mattermost.d.ts +11 -7
- package/dist/src/providers/builtin/mattermost.js +138 -24
- package/dist/src/providers/builtin/mattermost.js.map +1 -1
- package/dist/src/providers/builtin/msteams.d.ts +1 -0
- package/dist/src/providers/builtin/msteams.js +118 -38
- package/dist/src/providers/builtin/msteams.js.map +1 -1
- package/dist/src/providers/builtin/native-local-mock.js +4 -4
- package/dist/src/providers/builtin/native-local-mock.js.map +1 -1
- package/dist/src/providers/builtin/script.js +1057 -146
- package/dist/src/providers/builtin/script.js.map +1 -1
- package/dist/src/providers/builtin/slack.d.ts +8 -1
- package/dist/src/providers/builtin/slack.js +327 -24
- package/dist/src/providers/builtin/slack.js.map +1 -1
- package/dist/src/providers/builtin/telegram.d.ts +1 -1
- package/dist/src/providers/builtin/telegram.js +55 -14
- package/dist/src/providers/builtin/telegram.js.map +1 -1
- package/dist/src/providers/builtin/whatsapp.d.ts +4 -3
- package/dist/src/providers/builtin/whatsapp.js +157 -29
- package/dist/src/providers/builtin/whatsapp.js.map +1 -1
- package/dist/src/providers/builtin/zalo.d.ts +5 -2
- package/dist/src/providers/builtin/zalo.js +31 -7
- package/dist/src/providers/builtin/zalo.js.map +1 -1
- package/dist/src/providers/catalog.d.ts +1 -1
- package/dist/src/providers/catalog.js +1 -1
- package/dist/src/providers/catalog.js.map +1 -1
- package/dist/src/providers/local-mock.d.ts +4 -0
- package/dist/src/providers/local-mock.js +162 -35
- package/dist/src/providers/local-mock.js.map +1 -1
- package/dist/src/providers/native-ids.d.ts +2 -0
- package/dist/src/providers/native-ids.js +3 -0
- package/dist/src/providers/native-ids.js.map +1 -1
- package/dist/src/providers/recorder.d.ts +14 -3
- package/dist/src/providers/recorder.js +521 -41
- package/dist/src/providers/recorder.js.map +1 -1
- package/dist/src/providers/registry.d.ts +1 -0
- package/dist/src/providers/registry.js +65 -20
- package/dist/src/providers/registry.js.map +1 -1
- package/dist/src/providers/signed-jwt.d.ts +6 -1
- package/dist/src/providers/signed-jwt.js +241 -50
- package/dist/src/providers/signed-jwt.js.map +1 -1
- package/dist/src/providers/slack-ids.d.ts +1 -0
- package/dist/src/providers/slack-ids.js +5 -0
- package/dist/src/providers/slack-ids.js.map +1 -1
- package/dist/src/providers/target-normalizers.d.ts +9 -1
- package/dist/src/providers/target-normalizers.js +177 -58
- package/dist/src/providers/target-normalizers.js.map +1 -1
- package/dist/src/providers/webhook-server.d.ts +3 -0
- package/dist/src/providers/webhook-server.js +268 -47
- package/dist/src/providers/webhook-server.js.map +1 -1
- package/dist/src/servers/discord.d.ts +40 -0
- package/dist/src/servers/discord.js +842 -0
- package/dist/src/servers/discord.js.map +1 -0
- package/dist/src/servers/http.d.ts +14 -2
- package/dist/src/servers/http.js +229 -58
- package/dist/src/servers/http.js.map +1 -1
- package/dist/src/servers/index.d.ts +10 -4
- package/dist/src/servers/index.js +4 -0
- package/dist/src/servers/index.js.map +1 -1
- package/dist/src/servers/matrix.d.ts +3 -0
- package/dist/src/servers/matrix.js +268 -110
- package/dist/src/servers/matrix.js.map +1 -1
- package/dist/src/servers/mattermost.d.ts +5 -0
- package/dist/src/servers/mattermost.js +389 -91
- package/dist/src/servers/mattermost.js.map +1 -1
- package/dist/src/servers/recorder.d.ts +11 -0
- package/dist/src/servers/recorder.js +1072 -69
- package/dist/src/servers/recorder.js.map +1 -1
- package/dist/src/servers/signal.d.ts +1 -0
- package/dist/src/servers/signal.js +279 -44
- package/dist/src/servers/signal.js.map +1 -1
- package/dist/src/servers/slack.d.ts +15 -0
- package/dist/src/servers/slack.js +270 -54
- package/dist/src/servers/slack.js.map +1 -1
- package/dist/src/servers/telegram-identity.d.ts +6 -0
- package/dist/src/servers/telegram-identity.js +27 -0
- package/dist/src/servers/telegram-identity.js.map +1 -0
- package/dist/src/servers/telegram.d.ts +17 -6
- package/dist/src/servers/telegram.js +1218 -107
- package/dist/src/servers/telegram.js.map +1 -1
- package/dist/src/servers/webhook-target.d.ts +12 -4
- package/dist/src/servers/webhook-target.js +226 -28
- package/dist/src/servers/webhook-target.js.map +1 -1
- package/dist/src/servers/whatsapp-baileys-websocket.d.ts +60 -1
- package/dist/src/servers/whatsapp-baileys-websocket.js +782 -112
- package/dist/src/servers/whatsapp-baileys-websocket.js.map +1 -1
- package/dist/src/servers/whatsapp-jid.d.ts +1 -0
- package/dist/src/servers/whatsapp-jid.js +9 -5
- package/dist/src/servers/whatsapp-jid.js.map +1 -1
- package/dist/src/servers/whatsapp-wire/binary-node.d.ts +1 -0
- package/dist/src/servers/whatsapp-wire/binary-node.js +37 -13
- package/dist/src/servers/whatsapp-wire/binary-node.js.map +1 -1
- package/dist/src/servers/whatsapp-wire/crypto.d.ts +3 -0
- package/dist/src/servers/whatsapp-wire/crypto.js +23 -8
- package/dist/src/servers/whatsapp-wire/crypto.js.map +1 -1
- package/dist/src/servers/whatsapp-wire/handshake.d.ts +9 -3
- package/dist/src/servers/whatsapp-wire/handshake.js +173 -12
- package/dist/src/servers/whatsapp-wire/handshake.js.map +1 -1
- package/dist/src/servers/whatsapp-wire/signal.js +3 -3
- package/dist/src/servers/whatsapp-wire/signal.js.map +1 -1
- package/dist/src/servers/whatsapp.d.ts +7 -1
- package/dist/src/servers/whatsapp.js +149 -25
- package/dist/src/servers/whatsapp.js.map +1 -1
- package/dist/src/servers/zalo.d.ts +1 -0
- package/dist/src/servers/zalo.js +193 -82
- package/dist/src/servers/zalo.js.map +1 -1
- package/docs/channel-setup.md +251 -64
- package/fixtures/examples/crabline.example.yaml +3 -2
- package/package.json +18 -10
- package/dist/src/openclaw/smoke-lock.js +0 -1004
- package/dist/src/openclaw/smoke-lock.js.map +0 -1
- package/fixtures/examples/openclaw-bridge.yaml +0 -125
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
import { canonicalConversationIdForInbound, createAdminInboundRequest, createOpenClawCrablineProviderBridge, DEFAULT_ACCOUNT_ID, isRecord, qaTargetForInbound, readNonBlankString, readString, } from "../shared.js";
|
|
2
2
|
import { mattermostId } from "../../servers/mattermost.js";
|
|
3
|
-
|
|
3
|
+
import { throwProbeHttpError } from "./probe-response.js";
|
|
4
|
+
function nativeId(value, label = "Mattermost target") {
|
|
4
5
|
const trimmed = value.trim();
|
|
5
|
-
if (
|
|
6
|
-
throw new Error(
|
|
6
|
+
if (!/^[a-z0-9]{26}$/u.test(trimmed)) {
|
|
7
|
+
throw new Error(`${label} must be exactly 26 lowercase alphanumeric characters.`);
|
|
7
8
|
}
|
|
8
|
-
return
|
|
9
|
+
return trimmed;
|
|
9
10
|
}
|
|
10
11
|
function directChannelId(botUserId, userId) {
|
|
11
12
|
return mattermostId(`dm:${[botUserId, userId].sort().join(":")}`);
|
|
@@ -14,8 +15,7 @@ function targetKey(channelId, rootId) {
|
|
|
14
15
|
return rootId ? `${channelId}:thread:${rootId}` : channelId;
|
|
15
16
|
}
|
|
16
17
|
function threadRootId(channelId, value) {
|
|
17
|
-
|
|
18
|
-
return /^[a-z0-9]{26}$/u.test(trimmed) ? trimmed : mattermostId(`thread:${channelId}:${trimmed}`);
|
|
18
|
+
return nativeId(value, `Mattermost root post for channel ${channelId}`);
|
|
19
19
|
}
|
|
20
20
|
export const MATTERMOST_OPENCLAW_CRABLINE_PROVIDER_BRIDGE = createOpenClawCrablineProviderBridge({
|
|
21
21
|
provider: "mattermost",
|
|
@@ -27,7 +27,7 @@ export const MATTERMOST_OPENCLAW_CRABLINE_PROVIDER_BRIDGE = createOpenClawCrabli
|
|
|
27
27
|
...(signal ? { signal } : {}),
|
|
28
28
|
});
|
|
29
29
|
if (!response.ok) {
|
|
30
|
-
|
|
30
|
+
await throwProbeHttpError(response, `Crabline Mattermost probe failed with HTTP ${response.status}.`);
|
|
31
31
|
}
|
|
32
32
|
const payload = await response.json();
|
|
33
33
|
if (!isRecord(payload) ||
|
|
@@ -44,7 +44,7 @@ export const MATTERMOST_OPENCLAW_CRABLINE_PROVIDER_BRIDGE = createOpenClawCrabli
|
|
|
44
44
|
return {
|
|
45
45
|
accountId: DEFAULT_ACCOUNT_ID,
|
|
46
46
|
channel: "mattermost",
|
|
47
|
-
|
|
47
|
+
createProviderReadinessEnv: (env) => ({ ...env, ...mattermost.env }),
|
|
48
48
|
createGatewayConfig: (openclawConfig = {}) => {
|
|
49
49
|
const channels = isRecord(openclawConfig.channels) ? openclawConfig.channels : {};
|
|
50
50
|
const mattermostConfig = isRecord(channels.mattermost) ? channels.mattermost : {};
|
|
@@ -86,10 +86,15 @@ export const MATTERMOST_OPENCLAW_CRABLINE_PROVIDER_BRIDGE = createOpenClawCrabli
|
|
|
86
86
|
throw new Error("Mattermost conversation id is required.");
|
|
87
87
|
}
|
|
88
88
|
const senderId = nativeId(input.senderId);
|
|
89
|
+
const recipientId = kind === "direct" ? nativeId(conversationId) : undefined;
|
|
90
|
+
if (recipientId !== undefined && recipientId !== senderId) {
|
|
91
|
+
throw new Error("Mattermost direct conversation and sender must identify the same recipient.");
|
|
92
|
+
}
|
|
89
93
|
const channelId = kind === "direct"
|
|
90
94
|
? directChannelId(mattermost.botUserId, senderId)
|
|
91
95
|
: nativeId(conversationId);
|
|
92
|
-
const
|
|
96
|
+
const threadId = input.threadId?.trim();
|
|
97
|
+
const rootId = threadId ? threadRootId(channelId, threadId) : undefined;
|
|
93
98
|
return {
|
|
94
99
|
...createAdminInboundRequest(mattermost),
|
|
95
100
|
providerBody: {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"mattermost.js","sourceRoot":"","sources":["../../../../src/openclaw/bridges/mattermost.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,iCAAiC,EACjC,yBAAyB,EACzB,oCAAoC,EACpC,kBAAkB,EAClB,QAAQ,EACR,kBAAkB,EAClB,kBAAkB,EAClB,UAAU,GACX,MAAM,cAAc,CAAC;AACtB,OAAO,EAAE,YAAY,EAAE,MAAM,6BAA6B,CAAC;AAE3D,SAAS,QAAQ,CAAC,KAAa;IAC7B,MAAM,OAAO,GAAG,KAAK,CAAC,IAAI,EAAE,CAAC;IAC7B,IAAI,CAAC,OAAO,EAAE,CAAC;QACb,MAAM,IAAI,KAAK,CAAC,gCAAgC,CAAC,CAAC;IACpD,CAAC;IACD,OAAO,iBAAiB,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,YAAY,CAAC,OAAO,CAAC,CAAC;AAC3E,CAAC;AAED,SAAS,eAAe,CAAC,SAAiB,EAAE,MAAc;IACxD,OAAO,YAAY,CAAC,MAAM,CAAC,SAAS,EAAE,MAAM,CAAC,CAAC,IAAI,EAAE,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;AACpE,CAAC;AAED,SAAS,SAAS,CAAC,SAAiB,EAAE,MAAe;IACnD,OAAO,MAAM,CAAC,CAAC,CAAC,GAAG,SAAS,WAAW,MAAM,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC;AAC9D,CAAC;AAED,SAAS,YAAY,CAAC,SAAiB,EAAE,KAAa;IACpD,MAAM,OAAO,GAAG,KAAK,CAAC,IAAI,EAAE,CAAC;IAC7B,OAAO,iBAAiB,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,YAAY,CAAC,UAAU,SAAS,IAAI,OAAO,EAAE,CAAC,CAAC;AACpG,CAAC;AAED,MAAM,CAAC,MAAM,4CAA4C,GAAG,oCAAoC,CAAC;IAC/F,QAAQ,EAAE,YAAY;IACtB,aAAa,CAAC,UAAU;QACtB,OAAO;YACL,KAAK,CAAC,KAAK,CAAC,MAAM;gBAChB,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,GAAG,UAAU,CAAC,SAAS,CAAC,OAAO,WAAW,EAAE;oBACvE,OAAO,EAAE,EAAE,aAAa,EAAE,UAAU,UAAU,CAAC,QAAQ,EAAE,EAAE;oBAC3D,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;iBAC9B,CAAC,CAAC;gBACH,IAAI,CAAC,QAAQ,CAAC,EAAE,EAAE,CAAC;oBACjB,MAAM,IAAI,KAAK,CAAC,8CAA8C,QAAQ,CAAC,MAAM,GAAG,CAAC,CAAC;gBACpF,CAAC;gBACD,MAAM,OAAO,GAAY,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAC;gBAC/C,IACE,CAAC,QAAQ,CAAC,OAAO,CAAC;oBAClB,UAAU,CAAC,OAAO,CAAC,EAAE,CAAC,KAAK,UAAU,CAAC,SAAS;oBAC/C,CAAC,kBAAkB,CAAC,OAAO,CAAC,QAAQ,CAAC;oBACrC,OAAO,OAAO,CAAC,SAAS,KAAK,QAAQ;oBACrC,CAAC,MAAM,CAAC,aAAa,CAAC,OAAO,CAAC,SAAS,CAAC;oBACxC,OAAO,CAAC,SAAS,GAAG,CAAC,EACrB,CAAC;oBACD,MAAM,IAAI,KAAK,CAAC,iEAAiE,CAAC,CAAC;gBACrF,CAAC;gBACD,OAAO,OAAO,CAAC;YACjB,CAAC;YACD,aAAa;gBACX,OAAO;oBACL,SAAS,EAAE,kBAAkB;oBAC7B,OAAO,EAAE,YAAY;oBACrB,2BAA2B,EAAE,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC,EAAE,GAAG,GAAG,EAAE,GAAG,UAAU,CAAC,GAAG,EAAE,CAAC;oBACrE,mBAAmB,EAAE,CAAC,cAAc,GAAG,EAAE,EAAE,EAAE;wBAC3C,MAAM,QAAQ,GAAG,QAAQ,CAAC,cAAc,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,cAAc,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,CAAC;wBAClF,MAAM,gBAAgB,GAAG,QAAQ,CAAC,QAAQ,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,UAAU,CAAC,CAAC,CAAC,EAAE,CAAC;wBAClF,OAAO;4BACL,GAAG,cAAc;4BACjB,QAAQ,EAAE;gCACR,GAAG,QAAQ;gCACX,UAAU,EAAE;oCACV,GAAG,gBAAgB;oCACnB,SAAS,EAAE,CAAC,GAAG,CAAC;oCAChB,OAAO,EAAE,UAAU,CAAC,OAAO;oCAC3B,QAAQ,EAAE,UAAU,CAAC,QAAQ;oCAC7B,QAAQ,EAAE,WAAW;oCACrB,QAAQ,EAAE,MAAM;oCAChB,OAAO,EAAE,IAAI;oCACb,cAAc,EAAE,CAAC,GAAG,CAAC;oCACrB,WAAW,EAAE,MAAM;oCACnB,OAAO,EAAE,EAAE,8BAA8B,EAAE,IAAI,EAAE;oCACjD,SAAS,EAAE,EAAE,IAAI,EAAE,KAAK,EAAE;iCAC3B;6BACF;yBACF,CAAC;oBACJ,CAAC;oBACD,iBAAiB,EAAE,CAAC,YAAY,CAAC;iBAClC,CAAC;YACJ,CAAC;YACD,mBAAmB,CAAC,MAAM;gBACxB,IAAI,MAAM,CAAC,QAAQ,EAAE,CAAC;oBACpB,MAAM,IAAI,KAAK,CAAC,kEAAkE,CAAC,CAAC;gBACtF,CAAC;gBACD,MAAM,EAAE,GAAG,QAAQ,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;gBAC/B,MAAM,EAAE,GAAG,MAAM,CAAC,IAAI,KAAK,QAAQ,CAAC,CAAC,CAAC,QAAQ,EAAE,EAAE,CAAC,CAAC,CAAC,WAAW,EAAE,EAAE,CAAC;gBACrE,OAAO,EAAE,OAAO,EAAE,YAAY,EAAE,YAAY,EAAE,YAAY,EAAE,OAAO,EAAE,EAAE,EAAE,EAAE,EAAE,CAAC;YAChF,CAAC;YACD,aAAa,CAAC,KAAK;gBACjB,MAAM,IAAI,GAAG,KAAK,CAAC,YAAY,CAAC,IAAI,KAAK,QAAQ,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,OAAO,CAAC;gBACvE,MAAM,cAAc,GAAG,iCAAiC,CAAC,KAAK,CAAC,CAAC;gBAChE,IAAI,CAAC,cAAc,EAAE,CAAC;oBACpB,MAAM,IAAI,KAAK,CAAC,yCAAyC,CAAC,CAAC;gBAC7D,CAAC;gBACD,MAAM,QAAQ,GAAG,QAAQ,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC;gBAC1C,MAAM,SAAS,GACb,IAAI,KAAK,QAAQ;oBACf,CAAC,CAAC,eAAe,CAAC,UAAU,CAAC,SAAS,EAAE,QAAQ,CAAC;oBACjD,CAAC,CAAC,QAAQ,CAAC,cAAc,CAAC,CAAC;gBAC/B,MAAM,MAAM,GAAG,KAAK,CAAC,QAAQ,CAAC,CAAC,CAAC,YAAY,CAAC,SAAS,EAAE,KAAK,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;gBACpF,OAAO;oBACL,GAAG,yBAAyB,CAAC,UAAU,CAAC;oBACxC,YAAY,EAAE;wBACZ,SAAS;wBACT,WAAW,EAAE,IAAI,KAAK,QAAQ,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG;wBAC1C,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;wBAC7B,QAAQ;wBACR,GAAG,CAAC,KAAK,CAAC,UAAU,CAAC,CAAC,CAAC,EAAE,UAAU,EAAE,KAAK,CAAC,UAAU,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;wBAC7D,IAAI,EAAE,KAAK,CAAC,IAAI;qBACjB;oBACD,iBAAiB,EAAE,SAAS,CAAC,SAAS,EAAE,MAAM,CAAC;oBAC/C,QAAQ,EAAE,kBAAkB,CAAC,KAAK,CAAC;oBACnC,iBAAiB,EAAE,EAAE,EAAE,EAAE,cAAc,EAAE,IAAI,EAAE;oBAC/C,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,QAAQ,EAAE,MAAM,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;iBACxC,CAAC;YACJ,CAAC;YACD,+BAA+B,CAAC,EAAE,KAAK,EAAE,sBAAsB,EAAE;gBAC/D,IACE,CAAC,QAAQ,CAAC,KAAK,CAAC;oBAChB,KAAK,CAAC,IAAI,KAAK,KAAK;oBACpB,KAAK,CAAC,MAAM,KAAK,MAAM;oBACvB,KAAK,CAAC,IAAI,KAAK,eAAe;oBAC9B,CAAC,QAAQ,CAAC,KAAK,CAAC,IAAI,CAAC,EACrB,CAAC;oBACD,OAAO,IAAI,CAAC;gBACd,CAAC;gBACD,MAAM,SAAS,GAAG,UAAU,CAAC,KAAK,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;gBACpD,MAAM,MAAM,GAAG,UAAU,CAAC,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;gBAC9C,MAAM,IAAI,GAAG,kBAAkB,CAAC,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;gBACpD,IAAI,CAAC,SAAS,IAAI,CAAC,IAAI,EAAE,CAAC;oBACxB,OAAO,IAAI,CAAC;gBACd,CAAC;gBACD,MAAM,MAAM,GAAG,sBAAsB,CAAC,GAAG,CAAC,SAAS,CAAC,SAAS,EAAE,MAAM,CAAC,CAAC,CAAC;gBACxE,IAAI,CAAC,MAAM,EAAE,CAAC;oBACZ,OAAO,IAAI,CAAC;gBACd,CAAC;gBACD,OAAO;oBACL,SAAS,EAAE,kBAAkB;oBAC7B,QAAQ,EAAE,UAAU,CAAC,SAAS;oBAC9B,UAAU,EAAE,aAAa;oBACzB,IAAI;oBACJ,EAAE,EAAE,MAAM;iBACX,CAAC;YACJ,CAAC;SACF,CAAC;IACJ,CAAC;CACF,CAAC,CAAC","sourcesContent":["import {\n canonicalConversationIdForInbound,\n createAdminInboundRequest,\n createOpenClawCrablineProviderBridge,\n DEFAULT_ACCOUNT_ID,\n isRecord,\n qaTargetForInbound,\n readNonBlankString,\n readString,\n} from \"../shared.js\";\nimport { mattermostId } from \"../../servers/mattermost.js\";\n\nfunction nativeId(value: string): string {\n const trimmed = value.trim();\n if (!trimmed) {\n throw new Error(\"Mattermost target is required.\");\n }\n return /^[a-z0-9]{26}$/u.test(trimmed) ? trimmed : mattermostId(trimmed);\n}\n\nfunction directChannelId(botUserId: string, userId: string): string {\n return mattermostId(`dm:${[botUserId, userId].sort().join(\":\")}`);\n}\n\nfunction targetKey(channelId: string, rootId?: string): string {\n return rootId ? `${channelId}:thread:${rootId}` : channelId;\n}\n\nfunction threadRootId(channelId: string, value: string): string {\n const trimmed = value.trim();\n return /^[a-z0-9]{26}$/u.test(trimmed) ? trimmed : mattermostId(`thread:${channelId}:${trimmed}`);\n}\n\nexport const MATTERMOST_OPENCLAW_CRABLINE_PROVIDER_BRIDGE = createOpenClawCrablineProviderBridge({\n provider: \"mattermost\",\n createAdapter(mattermost) {\n return {\n async probe(signal) {\n const response = await fetch(`${mattermost.endpoints.apiRoot}/users/me`, {\n headers: { authorization: `Bearer ${mattermost.botToken}` },\n ...(signal ? { signal } : {}),\n });\n if (!response.ok) {\n throw new Error(`Crabline Mattermost probe failed with HTTP ${response.status}.`);\n }\n const payload: unknown = await response.json();\n if (\n !isRecord(payload) ||\n readString(payload.id) !== mattermost.botUserId ||\n !readNonBlankString(payload.username) ||\n typeof payload.update_at !== \"number\" ||\n !Number.isSafeInteger(payload.update_at) ||\n payload.update_at < 0\n ) {\n throw new Error(\"Crabline Mattermost users/me probe returned an unexpected user.\");\n }\n return payload;\n },\n createBinding() {\n return {\n accountId: DEFAULT_ACCOUNT_ID,\n channel: \"mattermost\",\n createChannelDriverSmokeEnv: (env) => ({ ...env, ...mattermost.env }),\n createGatewayConfig: (openclawConfig = {}) => {\n const channels = isRecord(openclawConfig.channels) ? openclawConfig.channels : {};\n const mattermostConfig = isRecord(channels.mattermost) ? channels.mattermost : {};\n return {\n ...openclawConfig,\n channels: {\n ...channels,\n mattermost: {\n ...mattermostConfig,\n allowFrom: [\"*\"],\n baseUrl: mattermost.baseUrl,\n botToken: mattermost.botToken,\n chatmode: \"onmessage\",\n dmPolicy: \"open\",\n enabled: true,\n groupAllowFrom: [\"*\"],\n groupPolicy: \"open\",\n network: { dangerouslyAllowPrivateNetwork: true },\n streaming: { mode: \"off\" },\n },\n },\n };\n },\n requiredPluginIds: [\"mattermost\"],\n };\n },\n createAgentDelivery(parsed) {\n if (parsed.threadId) {\n throw new Error(\"Mattermost thread targets require OpenClaw QA thread forwarding.\");\n }\n const id = nativeId(parsed.id);\n const to = parsed.kind === \"direct\" ? `user:${id}` : `channel:${id}`;\n return { channel: \"mattermost\", replyChannel: \"mattermost\", replyTo: to, to };\n },\n createInbound(input) {\n const kind = input.conversation.kind === \"direct\" ? \"direct\" : \"group\";\n const conversationId = canonicalConversationIdForInbound(input);\n if (!conversationId) {\n throw new Error(\"Mattermost conversation id is required.\");\n }\n const senderId = nativeId(input.senderId);\n const channelId =\n kind === \"direct\"\n ? directChannelId(mattermost.botUserId, senderId)\n : nativeId(conversationId);\n const rootId = input.threadId ? threadRootId(channelId, input.threadId) : undefined;\n return {\n ...createAdminInboundRequest(mattermost),\n providerBody: {\n channelId,\n channelType: kind === \"direct\" ? \"D\" : \"O\",\n ...(rootId ? { rootId } : {}),\n senderId,\n ...(input.senderName ? { senderName: input.senderName } : {}),\n text: input.text,\n },\n providerTargetKey: targetKey(channelId, rootId),\n qaTarget: qaTargetForInbound(input),\n stateConversation: { id: conversationId, kind },\n ...(rootId ? { threadId: rootId } : {}),\n };\n },\n createOutboundFromRecorderEvent({ event, targetByProviderTarget }) {\n if (\n !isRecord(event) ||\n event.type !== \"api\" ||\n event.method !== \"POST\" ||\n event.path !== \"/api/v4/posts\" ||\n !isRecord(event.body)\n ) {\n return null;\n }\n const channelId = readString(event.body.channel_id);\n const rootId = readString(event.body.root_id);\n const text = readNonBlankString(event.body.message);\n if (!channelId || !text) {\n return null;\n }\n const target = targetByProviderTarget.get(targetKey(channelId, rootId));\n if (!target) {\n return null;\n }\n return {\n accountId: DEFAULT_ACCOUNT_ID,\n senderId: mattermost.botUserId,\n senderName: \"OpenClaw QA\",\n text,\n to: target,\n };\n },\n };\n },\n});\n"]}
|
|
1
|
+
{"version":3,"file":"mattermost.js","sourceRoot":"","sources":["../../../../src/openclaw/bridges/mattermost.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n canonicalConversationIdForInbound,\n createAdminInboundRequest,\n createOpenClawCrablineProviderBridge,\n DEFAULT_ACCOUNT_ID,\n isRecord,\n qaTargetForInbound,\n readNonBlankString,\n readString,\n} from \"../shared.js\";\nimport { mattermostId } from \"../../servers/mattermost.js\";\nimport { throwProbeHttpError } from \"./probe-response.js\";\n\nfunction nativeId(value: string, label = \"Mattermost target\"): string {\n const trimmed = value.trim();\n if (!/^[a-z0-9]{26}$/u.test(trimmed)) {\n throw new Error(`${label} must be exactly 26 lowercase alphanumeric characters.`);\n }\n return trimmed;\n}\n\nfunction directChannelId(botUserId: string, userId: string): string {\n return mattermostId(`dm:${[botUserId, userId].sort().join(\":\")}`);\n}\n\nfunction targetKey(channelId: string, rootId?: string): string {\n return rootId ? `${channelId}:thread:${rootId}` : channelId;\n}\n\nfunction threadRootId(channelId: string, value: string): string {\n return nativeId(value, `Mattermost root post for channel ${channelId}`);\n}\n\nexport const MATTERMOST_OPENCLAW_CRABLINE_PROVIDER_BRIDGE = createOpenClawCrablineProviderBridge({\n provider: \"mattermost\",\n createAdapter(mattermost) {\n return {\n async probe(signal) {\n const response = await fetch(`${mattermost.endpoints.apiRoot}/users/me`, {\n headers: { authorization: `Bearer ${mattermost.botToken}` },\n ...(signal ? { signal } : {}),\n });\n if (!response.ok) {\n await throwProbeHttpError(\n response,\n `Crabline Mattermost probe failed with HTTP ${response.status}.`,\n );\n }\n const payload: unknown = await response.json();\n if (\n !isRecord(payload) ||\n readString(payload.id) !== mattermost.botUserId ||\n !readNonBlankString(payload.username) ||\n typeof payload.update_at !== \"number\" ||\n !Number.isSafeInteger(payload.update_at) ||\n payload.update_at < 0\n ) {\n throw new Error(\"Crabline Mattermost users/me probe returned an unexpected user.\");\n }\n return payload;\n },\n createBinding() {\n return {\n accountId: DEFAULT_ACCOUNT_ID,\n channel: \"mattermost\",\n createProviderReadinessEnv: (env) => ({ ...env, ...mattermost.env }),\n createGatewayConfig: (openclawConfig = {}) => {\n const channels = isRecord(openclawConfig.channels) ? openclawConfig.channels : {};\n const mattermostConfig = isRecord(channels.mattermost) ? channels.mattermost : {};\n return {\n ...openclawConfig,\n channels: {\n ...channels,\n mattermost: {\n ...mattermostConfig,\n allowFrom: [\"*\"],\n baseUrl: mattermost.baseUrl,\n botToken: mattermost.botToken,\n chatmode: \"onmessage\",\n dmPolicy: \"open\",\n enabled: true,\n groupAllowFrom: [\"*\"],\n groupPolicy: \"open\",\n network: { dangerouslyAllowPrivateNetwork: true },\n streaming: { mode: \"off\" },\n },\n },\n };\n },\n requiredPluginIds: [\"mattermost\"],\n };\n },\n createAgentDelivery(parsed) {\n if (parsed.threadId) {\n throw new Error(\"Mattermost thread targets require OpenClaw QA thread forwarding.\");\n }\n const id = nativeId(parsed.id);\n const to = parsed.kind === \"direct\" ? `user:${id}` : `channel:${id}`;\n return { channel: \"mattermost\", replyChannel: \"mattermost\", replyTo: to, to };\n },\n createInbound(input) {\n const kind = input.conversation.kind === \"direct\" ? \"direct\" : \"group\";\n const conversationId = canonicalConversationIdForInbound(input);\n if (!conversationId) {\n throw new Error(\"Mattermost conversation id is required.\");\n }\n const senderId = nativeId(input.senderId);\n const recipientId = kind === \"direct\" ? nativeId(conversationId) : undefined;\n if (recipientId !== undefined && recipientId !== senderId) {\n throw new Error(\n \"Mattermost direct conversation and sender must identify the same recipient.\",\n );\n }\n const channelId =\n kind === \"direct\"\n ? directChannelId(mattermost.botUserId, senderId)\n : nativeId(conversationId);\n const threadId = input.threadId?.trim();\n const rootId = threadId ? threadRootId(channelId, threadId) : undefined;\n return {\n ...createAdminInboundRequest(mattermost),\n providerBody: {\n channelId,\n channelType: kind === \"direct\" ? \"D\" : \"O\",\n ...(rootId ? { rootId } : {}),\n senderId,\n ...(input.senderName ? { senderName: input.senderName } : {}),\n text: input.text,\n },\n providerTargetKey: targetKey(channelId, rootId),\n qaTarget: qaTargetForInbound(input),\n stateConversation: { id: conversationId, kind },\n ...(rootId ? { threadId: rootId } : {}),\n };\n },\n createOutboundFromRecorderEvent({ event, targetByProviderTarget }) {\n if (\n !isRecord(event) ||\n event.type !== \"api\" ||\n event.method !== \"POST\" ||\n event.path !== \"/api/v4/posts\" ||\n !isRecord(event.body)\n ) {\n return null;\n }\n const channelId = readString(event.body.channel_id);\n const rootId = readString(event.body.root_id);\n const text = readNonBlankString(event.body.message);\n if (!channelId || !text) {\n return null;\n }\n const target = targetByProviderTarget.get(targetKey(channelId, rootId));\n if (!target) {\n return null;\n }\n return {\n accountId: DEFAULT_ACCOUNT_ID,\n senderId: mattermost.botUserId,\n senderName: \"OpenClaw QA\",\n text,\n to: target,\n };\n },\n };\n },\n});\n"]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function throwProbeHttpError(response: Response, message: string): Promise<never>;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"probe-response.js","sourceRoot":"","sources":["../../../../src/openclaw/bridges/probe-response.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,KAAK,UAAU,mBAAmB,CAAC,QAAkB,EAAE,OAAe;IAC3E,KAAK,QAAQ,CAAC,IAAI,EAAE,MAAM,EAAE,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,SAAS,CAAC,CAAC;IACpD,MAAM,IAAI,KAAK,CAAC,OAAO,CAAC,CAAC;AAC3B,CAAC","sourcesContent":["export async function throwProbeHttpError(response: Response, message: string): Promise<never> {\n void response.body?.cancel().catch(() => undefined);\n throw new Error(message);\n}\n"]}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { createHash } from "node:crypto";
|
|
2
2
|
import { createAdminInboundRequest, createOpenClawCrablineProviderBridge, DEFAULT_ACCOUNT_ID, isRecord, qaTargetForInbound, readNonBlankString, readString, } from "../shared.js";
|
|
3
|
+
import { throwProbeHttpError } from "./probe-response.js";
|
|
3
4
|
const SIGNAL_UUID_RE = /^(?:uuid:)?([0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12})$/iu;
|
|
4
5
|
function deterministicSignalUuid(value) {
|
|
5
6
|
const bytes = createHash("sha256")
|
|
@@ -25,15 +26,18 @@ function signalRecipientValues(value) {
|
|
|
25
26
|
const values = Array.isArray(value) ? value : [value];
|
|
26
27
|
return values.map(readString).filter((entry) => entry !== undefined);
|
|
27
28
|
}
|
|
29
|
+
function signalDirectRecipientValues(value) {
|
|
30
|
+
return signalRecipientValues(value).map((id) => signalDirectIdentity(id).recipient);
|
|
31
|
+
}
|
|
28
32
|
function signalOutboundTargets(params, account) {
|
|
29
33
|
const targets = [
|
|
30
34
|
...signalRecipientValues(params.groupId).map((id) => `group:${id}`),
|
|
31
35
|
...signalRecipientValues(params.groupIds).map((id) => `group:${id}`),
|
|
32
|
-
...
|
|
33
|
-
...
|
|
34
|
-
...
|
|
35
|
-
...
|
|
36
|
-
...(params.noteToSelf === true ? [account] : []),
|
|
36
|
+
...signalDirectRecipientValues(params.recipient),
|
|
37
|
+
...signalDirectRecipientValues(params.recipients),
|
|
38
|
+
...signalDirectRecipientValues(params.username),
|
|
39
|
+
...signalDirectRecipientValues(params.usernames),
|
|
40
|
+
...(params.noteToSelf === true ? [signalDirectIdentity(account).recipient] : []),
|
|
37
41
|
];
|
|
38
42
|
return [...new Set(targets)];
|
|
39
43
|
}
|
|
@@ -53,15 +57,16 @@ export const SIGNAL_OPENCLAW_CRABLINE_PROVIDER_BRIDGE = createOpenClawCrablinePr
|
|
|
53
57
|
...(abortSignal ? { signal: abortSignal } : {}),
|
|
54
58
|
});
|
|
55
59
|
if (!response.ok) {
|
|
56
|
-
|
|
60
|
+
await throwProbeHttpError(response, `Crabline Signal check probe failed with HTTP ${response.status}.`);
|
|
57
61
|
}
|
|
62
|
+
await response.body?.cancel();
|
|
58
63
|
return { ok: true, status: response.status };
|
|
59
64
|
},
|
|
60
65
|
createBinding() {
|
|
61
66
|
return {
|
|
62
67
|
accountId: DEFAULT_ACCOUNT_ID,
|
|
63
68
|
channel: "signal",
|
|
64
|
-
|
|
69
|
+
createProviderReadinessEnv: (env) => env,
|
|
65
70
|
createGatewayConfig: (openclawConfig = {}) => {
|
|
66
71
|
const channels = isRecord(openclawConfig.channels) ? openclawConfig.channels : {};
|
|
67
72
|
const signalConfig = isRecord(channels.signal) ? channels.signal : {};
|
|
@@ -105,6 +110,10 @@ export const SIGNAL_OPENCLAW_CRABLINE_PROVIDER_BRIDGE = createOpenClawCrablinePr
|
|
|
105
110
|
throw new Error("Signal conversation and sender are required.");
|
|
106
111
|
}
|
|
107
112
|
const senderIdentity = signalDirectIdentity(senderId);
|
|
113
|
+
if (kind === "direct" &&
|
|
114
|
+
signalDirectIdentity(conversationId).recipient !== senderIdentity.recipient) {
|
|
115
|
+
throw new Error("Signal direct conversation and sender must identify the same recipient.");
|
|
116
|
+
}
|
|
108
117
|
return {
|
|
109
118
|
...createAdminInboundRequest(signal),
|
|
110
119
|
providerBody: {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"signal.js","sourceRoot":"","sources":["../../../../src/openclaw/bridges/signal.ts"],"names":[],"mappings":"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","sourcesContent":["import { createHash } from \"node:crypto\";\nimport {\n createAdminInboundRequest,\n createOpenClawCrablineProviderBridge,\n DEFAULT_ACCOUNT_ID,\n isRecord,\n qaTargetForInbound,\n readNonBlankString,\n readString,\n} from \"../shared.js\";\n\nconst SIGNAL_UUID_RE =\n /^(?:uuid:)?([0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12})$/iu;\n\ntype SignalDirectIdentity =\n | { recipient: string; sourceNumber: string }\n | { recipient: string; sourceUuid: string };\n\nfunction deterministicSignalUuid(value: string): string {\n const bytes = createHash(\"sha256\")\n .update(\"crabline:signal:direct\\0\")\n .update(value)\n .digest()\n .subarray(0, 16);\n bytes[6] = (bytes[6]! & 0x0f) | 0x80;\n bytes[8] = (bytes[8]! & 0x3f) | 0x80;\n const hex = bytes.toString(\"hex\");\n return `${hex.slice(0, 8)}-${hex.slice(8, 12)}-${hex.slice(12, 16)}-${hex.slice(16, 20)}-${hex.slice(20)}`;\n}\n\nfunction signalDirectIdentity(id: string): SignalDirectIdentity {\n const value = id.trim();\n if (/^\\+?[1-9]\\d{2,14}$/u.test(value)) {\n const sourceNumber = value.startsWith(\"+\") ? value : `+${value}`;\n return { recipient: sourceNumber, sourceNumber };\n }\n const sourceUuid =\n SIGNAL_UUID_RE.exec(value)?.[1]?.toLowerCase() ?? deterministicSignalUuid(value);\n return { recipient: sourceUuid, sourceUuid };\n}\n\nfunction signalRecipientValues(value: unknown): string[] {\n const values = Array.isArray(value) ? value : [value];\n return values.map(readString).filter((entry): entry is string => entry !== undefined);\n}\n\nfunction signalOutboundTargets(params: Record<string, unknown>, account: string): string[] {\n const targets = [\n ...signalRecipientValues(params.groupId).map((id) => `group:${id}`),\n ...signalRecipientValues(params.groupIds).map((id) => `group:${id}`),\n ...signalRecipientValues(params.recipient),\n ...signalRecipientValues(params.recipients),\n ...signalRecipientValues(params.username),\n ...signalRecipientValues(params.usernames),\n ...(params.noteToSelf === true ? [account] : []),\n ];\n return [...new Set(targets)];\n}\n\nfunction signalTarget(kind: \"direct\" | \"group\", id: string): string {\n const value = id.trim();\n if (!value) {\n throw new Error(\"Signal target is required.\");\n }\n return kind === \"group\" ? `group:${value}` : signalDirectIdentity(value).recipient;\n}\n\nexport const SIGNAL_OPENCLAW_CRABLINE_PROVIDER_BRIDGE = createOpenClawCrablineProviderBridge({\n provider: \"signal\",\n createAdapter(signal) {\n return {\n async probe(abortSignal) {\n const response = await fetch(`${signal.baseUrl}/api/v1/check`, {\n ...(abortSignal ? { signal: abortSignal } : {}),\n });\n if (!response.ok) {\n throw new Error(`Crabline Signal check probe failed with HTTP ${response.status}.`);\n }\n return { ok: true, status: response.status };\n },\n createBinding() {\n return {\n accountId: DEFAULT_ACCOUNT_ID,\n channel: \"signal\",\n createChannelDriverSmokeEnv: (env) => env,\n createGatewayConfig: (openclawConfig = {}) => {\n const channels = isRecord(openclawConfig.channels) ? openclawConfig.channels : {};\n const signalConfig = isRecord(channels.signal) ? channels.signal : {};\n return {\n ...openclawConfig,\n channels: {\n ...channels,\n signal: {\n ...signalConfig,\n account: signal.account,\n allowFrom: [\"*\"],\n apiMode: \"native\",\n autoStart: false,\n dmPolicy: \"open\",\n enabled: true,\n groupAllowFrom: [\"*\"],\n groupPolicy: \"open\",\n httpUrl: signal.baseUrl,\n },\n },\n };\n },\n requiredPluginIds: [\"signal\"],\n };\n },\n createAgentDelivery(parsed) {\n if (parsed.threadId !== undefined) {\n throw new Error(\"Signal does not support thread targets.\");\n }\n const to = signalTarget(parsed.kind, parsed.id);\n return { channel: \"signal\", replyChannel: \"signal\", replyTo: to, to };\n },\n createInbound(input) {\n if (input.threadId !== undefined) {\n throw new Error(\"Signal does not support thread targets.\");\n }\n const kind = input.conversation.kind === \"direct\" ? \"direct\" : \"group\";\n const conversationId = input.conversation.id.trim();\n const senderId = input.senderId.trim();\n if (!conversationId || !senderId) {\n throw new Error(\"Signal conversation and sender are required.\");\n }\n const senderIdentity = signalDirectIdentity(senderId);\n return {\n ...createAdminInboundRequest(signal),\n providerBody: {\n ...(kind === \"group\" ? { groupId: conversationId } : {}),\n ...(input.senderName ? { sourceName: input.senderName } : {}),\n ...(\"sourceNumber\" in senderIdentity\n ? { sourceNumber: senderIdentity.sourceNumber }\n : { sourceUuid: senderIdentity.sourceUuid }),\n text: input.text,\n },\n providerTargetKey:\n kind === \"group\" ? `group:${conversationId}` : senderIdentity.recipient,\n qaTarget: qaTargetForInbound(input),\n stateConversation: { id: conversationId, kind },\n };\n },\n createOutboundFromRecorderEvent({ event, targetByProviderTarget }) {\n if (\n !isRecord(event) ||\n event.type !== \"api\" ||\n event.path !== \"/api/v1/rpc\" ||\n !isRecord(event.body) ||\n event.body.method !== \"send\" ||\n !isRecord(event.body.params)\n ) {\n return null;\n }\n const text = readNonBlankString(event.body.params.message);\n const targets = signalOutboundTargets(event.body.params, signal.account);\n if (!text || targets.length !== 1) {\n return null;\n }\n const target = targets[0]!;\n return {\n accountId: DEFAULT_ACCOUNT_ID,\n senderId: \"openclaw\",\n senderName: \"OpenClaw QA\",\n text,\n to: targetByProviderTarget.get(target) ?? target,\n };\n },\n };\n },\n});\n"]}
|
|
1
|
+
{"version":3,"file":"signal.js","sourceRoot":"","sources":["../../../../src/openclaw/bridges/signal.ts"],"names":[],"mappings":"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","sourcesContent":["import { createHash } from \"node:crypto\";\nimport {\n createAdminInboundRequest,\n createOpenClawCrablineProviderBridge,\n DEFAULT_ACCOUNT_ID,\n isRecord,\n qaTargetForInbound,\n readNonBlankString,\n readString,\n} from \"../shared.js\";\nimport { throwProbeHttpError } from \"./probe-response.js\";\n\nconst SIGNAL_UUID_RE =\n /^(?:uuid:)?([0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12})$/iu;\n\ntype SignalDirectIdentity =\n | { recipient: string; sourceNumber: string }\n | { recipient: string; sourceUuid: string };\n\nfunction deterministicSignalUuid(value: string): string {\n const bytes = createHash(\"sha256\")\n .update(\"crabline:signal:direct\\0\")\n .update(value)\n .digest()\n .subarray(0, 16);\n bytes[6] = (bytes[6]! & 0x0f) | 0x80;\n bytes[8] = (bytes[8]! & 0x3f) | 0x80;\n const hex = bytes.toString(\"hex\");\n return `${hex.slice(0, 8)}-${hex.slice(8, 12)}-${hex.slice(12, 16)}-${hex.slice(16, 20)}-${hex.slice(20)}`;\n}\n\nfunction signalDirectIdentity(id: string): SignalDirectIdentity {\n const value = id.trim();\n if (/^\\+?[1-9]\\d{2,14}$/u.test(value)) {\n const sourceNumber = value.startsWith(\"+\") ? value : `+${value}`;\n return { recipient: sourceNumber, sourceNumber };\n }\n const sourceUuid =\n SIGNAL_UUID_RE.exec(value)?.[1]?.toLowerCase() ?? deterministicSignalUuid(value);\n return { recipient: sourceUuid, sourceUuid };\n}\n\nfunction signalRecipientValues(value: unknown): string[] {\n const values = Array.isArray(value) ? value : [value];\n return values.map(readString).filter((entry): entry is string => entry !== undefined);\n}\n\nfunction signalDirectRecipientValues(value: unknown): string[] {\n return signalRecipientValues(value).map((id) => signalDirectIdentity(id).recipient);\n}\n\nfunction signalOutboundTargets(params: Record<string, unknown>, account: string): string[] {\n const targets = [\n ...signalRecipientValues(params.groupId).map((id) => `group:${id}`),\n ...signalRecipientValues(params.groupIds).map((id) => `group:${id}`),\n ...signalDirectRecipientValues(params.recipient),\n ...signalDirectRecipientValues(params.recipients),\n ...signalDirectRecipientValues(params.username),\n ...signalDirectRecipientValues(params.usernames),\n ...(params.noteToSelf === true ? [signalDirectIdentity(account).recipient] : []),\n ];\n return [...new Set(targets)];\n}\n\nfunction signalTarget(kind: \"direct\" | \"group\", id: string): string {\n const value = id.trim();\n if (!value) {\n throw new Error(\"Signal target is required.\");\n }\n return kind === \"group\" ? `group:${value}` : signalDirectIdentity(value).recipient;\n}\n\nexport const SIGNAL_OPENCLAW_CRABLINE_PROVIDER_BRIDGE = createOpenClawCrablineProviderBridge({\n provider: \"signal\",\n createAdapter(signal) {\n return {\n async probe(abortSignal) {\n const response = await fetch(`${signal.baseUrl}/api/v1/check`, {\n ...(abortSignal ? { signal: abortSignal } : {}),\n });\n if (!response.ok) {\n await throwProbeHttpError(\n response,\n `Crabline Signal check probe failed with HTTP ${response.status}.`,\n );\n }\n await response.body?.cancel();\n return { ok: true, status: response.status };\n },\n createBinding() {\n return {\n accountId: DEFAULT_ACCOUNT_ID,\n channel: \"signal\",\n createProviderReadinessEnv: (env) => env,\n createGatewayConfig: (openclawConfig = {}) => {\n const channels = isRecord(openclawConfig.channels) ? openclawConfig.channels : {};\n const signalConfig = isRecord(channels.signal) ? channels.signal : {};\n return {\n ...openclawConfig,\n channels: {\n ...channels,\n signal: {\n ...signalConfig,\n account: signal.account,\n allowFrom: [\"*\"],\n apiMode: \"native\",\n autoStart: false,\n dmPolicy: \"open\",\n enabled: true,\n groupAllowFrom: [\"*\"],\n groupPolicy: \"open\",\n httpUrl: signal.baseUrl,\n },\n },\n };\n },\n requiredPluginIds: [\"signal\"],\n };\n },\n createAgentDelivery(parsed) {\n if (parsed.threadId !== undefined) {\n throw new Error(\"Signal does not support thread targets.\");\n }\n const to = signalTarget(parsed.kind, parsed.id);\n return { channel: \"signal\", replyChannel: \"signal\", replyTo: to, to };\n },\n createInbound(input) {\n if (input.threadId !== undefined) {\n throw new Error(\"Signal does not support thread targets.\");\n }\n const kind = input.conversation.kind === \"direct\" ? \"direct\" : \"group\";\n const conversationId = input.conversation.id.trim();\n const senderId = input.senderId.trim();\n if (!conversationId || !senderId) {\n throw new Error(\"Signal conversation and sender are required.\");\n }\n const senderIdentity = signalDirectIdentity(senderId);\n if (\n kind === \"direct\" &&\n signalDirectIdentity(conversationId).recipient !== senderIdentity.recipient\n ) {\n throw new Error(\n \"Signal direct conversation and sender must identify the same recipient.\",\n );\n }\n return {\n ...createAdminInboundRequest(signal),\n providerBody: {\n ...(kind === \"group\" ? { groupId: conversationId } : {}),\n ...(input.senderName ? { sourceName: input.senderName } : {}),\n ...(\"sourceNumber\" in senderIdentity\n ? { sourceNumber: senderIdentity.sourceNumber }\n : { sourceUuid: senderIdentity.sourceUuid }),\n text: input.text,\n },\n providerTargetKey:\n kind === \"group\" ? `group:${conversationId}` : senderIdentity.recipient,\n qaTarget: qaTargetForInbound(input),\n stateConversation: { id: conversationId, kind },\n };\n },\n createOutboundFromRecorderEvent({ event, targetByProviderTarget }) {\n if (\n !isRecord(event) ||\n event.type !== \"api\" ||\n event.path !== \"/api/v1/rpc\" ||\n !isRecord(event.body) ||\n event.body.method !== \"send\" ||\n !isRecord(event.body.params)\n ) {\n return null;\n }\n const text = readNonBlankString(event.body.params.message);\n const targets = signalOutboundTargets(event.body.params, signal.account);\n if (!text || targets.length !== 1) {\n return null;\n }\n const target = targets[0]!;\n return {\n accountId: DEFAULT_ACCOUNT_ID,\n senderId: \"openclaw\",\n senderName: \"OpenClaw QA\",\n text,\n to: targetByProviderTarget.get(target) ?? target,\n };\n },\n };\n },\n});\n"]}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
|
-
import { createAdminInboundRequest, createOpenClawCrablineProviderBridge, DEFAULT_ACCOUNT_ID, isRecord, qaTargetForInbound,
|
|
1
|
+
import { createAdminInboundRequest, createOpenClawCrablineProviderBridge, DEFAULT_ACCOUNT_ID, isRecord, qaTargetForInbound, readString, } from "../shared.js";
|
|
2
2
|
import { slackTargetKey, SLACK_CHANNEL_ID_RULE, SLACK_SEND_TARGET_ID_RULE, SLACK_TS_RULE, SLACK_USER_ID_RULE, } from "../../providers/slack-ids.js";
|
|
3
|
+
import { throwProbeHttpError } from "./probe-response.js";
|
|
3
4
|
function requireSlackSendTargetId(value, label) {
|
|
4
5
|
const trimmed = value.trim();
|
|
5
6
|
if (!SLACK_SEND_TARGET_ID_RULE.pattern.test(trimmed)) {
|
|
@@ -43,6 +44,11 @@ function requireSlackThreadTs(value, label) {
|
|
|
43
44
|
function slackConversationKind(channel) {
|
|
44
45
|
return channel.startsWith("D") ? "direct" : "group";
|
|
45
46
|
}
|
|
47
|
+
function pushSlackText(value, output) {
|
|
48
|
+
if (typeof value === "string" && value.trim()) {
|
|
49
|
+
output.push(value);
|
|
50
|
+
}
|
|
51
|
+
}
|
|
46
52
|
function structuredSlackValues(value) {
|
|
47
53
|
if (Array.isArray(value)) {
|
|
48
54
|
return value;
|
|
@@ -58,47 +64,131 @@ function structuredSlackValues(value) {
|
|
|
58
64
|
return [];
|
|
59
65
|
}
|
|
60
66
|
}
|
|
61
|
-
function
|
|
67
|
+
function slackInlineText(value) {
|
|
68
|
+
if (Array.isArray(value)) {
|
|
69
|
+
return value.map(slackInlineText).join("");
|
|
70
|
+
}
|
|
71
|
+
if (!isRecord(value)) {
|
|
72
|
+
return "";
|
|
73
|
+
}
|
|
74
|
+
if (value.type === "link" && typeof value.url === "string") {
|
|
75
|
+
return typeof value.text === "string" && value.text.length > 0 ? value.text : value.url;
|
|
76
|
+
}
|
|
77
|
+
if (value.type === "user" && typeof value.user_id === "string") {
|
|
78
|
+
return `<@${value.user_id}>`;
|
|
79
|
+
}
|
|
80
|
+
if (value.type === "channel" && typeof value.channel_id === "string") {
|
|
81
|
+
return `<#${value.channel_id}>`;
|
|
82
|
+
}
|
|
83
|
+
if (value.type === "usergroup" && typeof value.usergroup_id === "string") {
|
|
84
|
+
return `<!subteam^${value.usergroup_id}>`;
|
|
85
|
+
}
|
|
86
|
+
if (value.type === "emoji" && typeof value.name === "string") {
|
|
87
|
+
return `:${value.name}:`;
|
|
88
|
+
}
|
|
89
|
+
if (value.type === "broadcast" && typeof value.range === "string") {
|
|
90
|
+
return `<!${value.range}>`;
|
|
91
|
+
}
|
|
92
|
+
if (value.type === "date") {
|
|
93
|
+
if (typeof value.fallback === "string" && value.fallback.length > 0) {
|
|
94
|
+
return value.fallback;
|
|
95
|
+
}
|
|
96
|
+
if ((typeof value.timestamp === "number" || typeof value.timestamp === "string") &&
|
|
97
|
+
typeof value.format === "string") {
|
|
98
|
+
return `<!date^${value.timestamp}^${value.format}>`;
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
if (typeof value.text === "string") {
|
|
102
|
+
return value.text;
|
|
103
|
+
}
|
|
104
|
+
return slackInlineText(value.elements);
|
|
105
|
+
}
|
|
106
|
+
function collectSlackTextValue(value, output) {
|
|
107
|
+
if (typeof value === "string") {
|
|
108
|
+
pushSlackText(value, output);
|
|
109
|
+
return;
|
|
110
|
+
}
|
|
111
|
+
if (isRecord(value) && typeof value.text === "string") {
|
|
112
|
+
pushSlackText(value.text, output);
|
|
113
|
+
return;
|
|
114
|
+
}
|
|
115
|
+
collectSlackBlockText(value, output);
|
|
116
|
+
}
|
|
117
|
+
function collectSlackBlockText(value, output) {
|
|
62
118
|
if (Array.isArray(value)) {
|
|
63
119
|
for (const entry of value) {
|
|
64
|
-
|
|
120
|
+
collectSlackBlockText(entry, output);
|
|
65
121
|
}
|
|
66
122
|
return;
|
|
67
123
|
}
|
|
68
124
|
if (!isRecord(value)) {
|
|
69
125
|
return;
|
|
70
126
|
}
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
127
|
+
if (value.type === "rich_text_section" ||
|
|
128
|
+
value.type === "rich_text_preformatted" ||
|
|
129
|
+
value.type === "rich_text_quote") {
|
|
130
|
+
pushSlackText(slackInlineText(value.elements), output);
|
|
131
|
+
return;
|
|
132
|
+
}
|
|
133
|
+
for (const key of [
|
|
134
|
+
"alt_text",
|
|
135
|
+
"title",
|
|
136
|
+
"body",
|
|
137
|
+
"subtitle",
|
|
138
|
+
"subtext",
|
|
139
|
+
"details",
|
|
140
|
+
"output",
|
|
141
|
+
]) {
|
|
142
|
+
collectSlackTextValue(value[key], output);
|
|
143
|
+
}
|
|
144
|
+
collectSlackTextValue(value.text, output);
|
|
145
|
+
for (const key of [
|
|
146
|
+
"blocks",
|
|
147
|
+
"elements",
|
|
148
|
+
"fields",
|
|
149
|
+
"rows",
|
|
150
|
+
"tasks",
|
|
151
|
+
"actions",
|
|
152
|
+
"hero_image",
|
|
153
|
+
"icon",
|
|
154
|
+
]) {
|
|
155
|
+
collectSlackBlockText(value[key], output);
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
function collectSlackAttachmentText(value, output) {
|
|
159
|
+
if (Array.isArray(value)) {
|
|
160
|
+
for (const entry of value) {
|
|
161
|
+
collectSlackAttachmentText(entry, output);
|
|
75
162
|
}
|
|
163
|
+
return;
|
|
76
164
|
}
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
output.push(text);
|
|
165
|
+
if (!isRecord(value)) {
|
|
166
|
+
return;
|
|
80
167
|
}
|
|
81
|
-
|
|
82
|
-
|
|
168
|
+
for (const key of ["fallback", "pretext", "author_name", "title", "text", "footer"]) {
|
|
169
|
+
pushSlackText(value[key], output);
|
|
83
170
|
}
|
|
84
|
-
|
|
85
|
-
|
|
171
|
+
if (Array.isArray(value.fields)) {
|
|
172
|
+
for (const field of value.fields) {
|
|
173
|
+
if (!isRecord(field)) {
|
|
174
|
+
continue;
|
|
175
|
+
}
|
|
176
|
+
pushSlackText(field.title, output);
|
|
177
|
+
pushSlackText(field.value, output);
|
|
178
|
+
}
|
|
86
179
|
}
|
|
180
|
+
collectSlackBlockText(value.blocks, output);
|
|
87
181
|
}
|
|
88
182
|
function slackOutboundText(body) {
|
|
89
183
|
if (typeof body.text === "string") {
|
|
90
184
|
if (body.text.trim()) {
|
|
91
185
|
return body.text;
|
|
92
186
|
}
|
|
93
|
-
if (body.text.length > 0) {
|
|
94
|
-
return undefined;
|
|
95
|
-
}
|
|
96
187
|
}
|
|
97
188
|
const fallback = [];
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
return unique.length > 0 ? unique.join("\n") : undefined;
|
|
189
|
+
collectSlackBlockText(structuredSlackValues(body.blocks), fallback);
|
|
190
|
+
collectSlackAttachmentText(structuredSlackValues(body.attachments), fallback);
|
|
191
|
+
return fallback.length > 0 ? fallback.join("\n") : undefined;
|
|
102
192
|
}
|
|
103
193
|
export const SLACK_OPENCLAW_CRABLINE_PROVIDER_BRIDGE = createOpenClawCrablineProviderBridge({
|
|
104
194
|
provider: "slack",
|
|
@@ -111,7 +201,7 @@ export const SLACK_OPENCLAW_CRABLINE_PROVIDER_BRIDGE = createOpenClawCrablinePro
|
|
|
111
201
|
...(signal ? { signal } : {}),
|
|
112
202
|
});
|
|
113
203
|
if (!response.ok) {
|
|
114
|
-
|
|
204
|
+
await throwProbeHttpError(response, `Crabline Slack auth.test probe failed with HTTP ${response.status}.`);
|
|
115
205
|
}
|
|
116
206
|
const result = await response.json();
|
|
117
207
|
if (!isRecord(result) || result.ok !== true) {
|
|
@@ -124,7 +214,7 @@ export const SLACK_OPENCLAW_CRABLINE_PROVIDER_BRIDGE = createOpenClawCrablinePro
|
|
|
124
214
|
return {
|
|
125
215
|
accountId: DEFAULT_ACCOUNT_ID,
|
|
126
216
|
channel: "slack",
|
|
127
|
-
|
|
217
|
+
createProviderReadinessEnv: (env) => ({
|
|
128
218
|
...env,
|
|
129
219
|
SLACK_API_URL: slack.endpoints.apiRoot,
|
|
130
220
|
SLACK_BOT_TOKEN: slack.botToken,
|
|
@@ -165,8 +255,11 @@ export const SLACK_OPENCLAW_CRABLINE_PROVIDER_BRIDGE = createOpenClawCrablinePro
|
|
|
165
255
|
},
|
|
166
256
|
createAgentDelivery(parsed) {
|
|
167
257
|
const to = requireSlackSendTargetId(parsed.id, "Slack target");
|
|
168
|
-
requireSlackTargetKind(parsed, to);
|
|
169
258
|
const threadTs = requireSlackThreadTs(parsed.threadId, "Slack target thread");
|
|
259
|
+
if (threadTs && !SLACK_CHANNEL_ID_RULE.pattern.test(to)) {
|
|
260
|
+
throw new Error("Slack thread targets require a native parent conversation id.");
|
|
261
|
+
}
|
|
262
|
+
requireSlackTargetKind(parsed, to);
|
|
170
263
|
return {
|
|
171
264
|
channel: "slack",
|
|
172
265
|
to,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"slack.js","sourceRoot":"","sources":["../../../../src/openclaw/bridges/slack.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n createAdminInboundRequest,\n createOpenClawCrablineProviderBridge,\n DEFAULT_ACCOUNT_ID,\n isRecord,\n qaTargetForInbound,\n readNonBlankString,\n readString,\n} from \"../shared.js\";\nimport {\n slackTargetKey,\n SLACK_CHANNEL_ID_RULE,\n SLACK_SEND_TARGET_ID_RULE,\n SLACK_TS_RULE,\n SLACK_USER_ID_RULE,\n} from \"../../providers/slack-ids.js\";\n\nfunction requireSlackSendTargetId(value: string, label: string): string {\n const trimmed = value.trim();\n if (!SLACK_SEND_TARGET_ID_RULE.pattern.test(trimmed)) {\n throw new Error(`${label} must be a native Slack conversation or user id.`);\n }\n return trimmed;\n}\n\nfunction requireSlackTargetKind(\n parsed: { kind: \"direct\" | \"group\"; native: boolean; threadId?: string },\n targetId: string,\n): void {\n if (parsed.native || parsed.threadId !== undefined) {\n return;\n }\n const nativeKind = /^[DUW]/u.test(targetId) ? \"direct\" : \"group\";\n if (parsed.kind !== nativeKind) {\n throw new Error(\"Slack target kind does not match the native conversation id.\");\n }\n}\n\nfunction requireSlackChannelId(value: string, label: string): string {\n const trimmed = value.trim();\n if (!SLACK_CHANNEL_ID_RULE.pattern.test(trimmed)) {\n throw new Error(`${label} must be a native Slack conversation id.`);\n }\n return trimmed;\n}\n\nfunction requireSlackUserId(value: string, label: string): string {\n const trimmed = value.trim();\n if (!SLACK_USER_ID_RULE.pattern.test(trimmed)) {\n throw new Error(`${label} must be a native Slack user id.`);\n }\n return trimmed;\n}\n\nfunction requireSlackThreadTs(value: string | undefined, label: string): string | undefined {\n const trimmed = value?.trim();\n if (!trimmed) {\n return undefined;\n }\n if (!SLACK_TS_RULE.pattern.test(trimmed)) {\n throw new Error(`${label} must be a native Slack timestamp.`);\n }\n return trimmed;\n}\n\nfunction slackConversationKind(channel: string): \"direct\" | \"group\" {\n return channel.startsWith(\"D\") ? \"direct\" : \"group\";\n}\n\nfunction structuredSlackValues(value: unknown): unknown[] {\n if (Array.isArray(value)) {\n return value;\n }\n if (typeof value !== \"string\") {\n return [];\n }\n try {\n const parsed: unknown = JSON.parse(value);\n return Array.isArray(parsed) ? parsed : [];\n } catch {\n return [];\n }\n}\n\nfunction collectSlackFallbackText(value: unknown, output: string[]): void {\n if (Array.isArray(value)) {\n for (const entry of value) {\n collectSlackFallbackText(entry, output);\n }\n return;\n }\n if (!isRecord(value)) {\n return;\n }\n for (const key of [\"fallback\", \"title\", \"alt_text\"] as const) {\n const text = readNonBlankString(value[key]);\n if (text) {\n output.push(text);\n }\n }\n const text = value.text;\n if (typeof text === \"string\" && text.trim()) {\n output.push(text);\n } else if (isRecord(text)) {\n collectSlackFallbackText(text, output);\n }\n for (const key of [\"blocks\", \"elements\", \"fields\"] as const) {\n collectSlackFallbackText(value[key], output);\n }\n}\n\nfunction slackOutboundText(body: Record<string, unknown>): string | undefined {\n if (typeof body.text === \"string\") {\n if (body.text.trim()) {\n return body.text;\n }\n if (body.text.length > 0) {\n return undefined;\n }\n }\n const fallback: string[] = [];\n collectSlackFallbackText(structuredSlackValues(body.blocks), fallback);\n collectSlackFallbackText(structuredSlackValues(body.attachments), fallback);\n const unique = [...new Set(fallback)];\n return unique.length > 0 ? unique.join(\"\\n\") : undefined;\n}\n\nexport const SLACK_OPENCLAW_CRABLINE_PROVIDER_BRIDGE = createOpenClawCrablineProviderBridge({\n provider: \"slack\",\n createAdapter(slack) {\n return {\n async probe(signal) {\n const response = await fetch(`${slack.endpoints.apiRoot}auth.test`, {\n headers: { authorization: `Bearer ${slack.botToken}` },\n method: \"POST\",\n ...(signal ? { signal } : {}),\n });\n if (!response.ok) {\n throw new Error(`Crabline Slack auth.test probe failed with HTTP ${response.status}.`);\n }\n const result: unknown = await response.json();\n if (!isRecord(result) || result.ok !== true) {\n const error = isRecord(result) ? readString(result.error) : undefined;\n throw new Error(`Crabline Slack auth.test probe failed: ${error ?? \"unknown_error\"}.`);\n }\n return result;\n },\n createBinding() {\n return {\n accountId: DEFAULT_ACCOUNT_ID,\n channel: \"slack\",\n createChannelDriverSmokeEnv: (env) => ({\n ...env,\n SLACK_API_URL: slack.endpoints.apiRoot,\n SLACK_BOT_TOKEN: slack.botToken,\n SLACK_SIGNING_SECRET: slack.signingSecret,\n }),\n createGatewayConfig: (openclawConfig = {}) => {\n const channels = isRecord(openclawConfig.channels) ? openclawConfig.channels : {};\n const slackConfig = isRecord(channels.slack) ? channels.slack : {};\n const slackChannels = isRecord(slackConfig.channels) ? slackConfig.channels : {};\n const defaultSlackChannel = isRecord(slackChannels[\"*\"]) ? slackChannels[\"*\"] : {};\n\n return {\n ...openclawConfig,\n channels: {\n ...channels,\n slack: {\n ...slackConfig,\n enabled: true,\n mode: \"http\",\n botToken: slack.botToken,\n signingSecret: slack.signingSecret,\n webhookPath: \"/slack/events\",\n dmPolicy: \"open\",\n allowFrom: [\"*\"],\n groupPolicy: \"open\",\n channels: {\n ...slackChannels,\n \"*\": {\n ...defaultSlackChannel,\n requireMention: false,\n },\n },\n },\n },\n };\n },\n requiredPluginIds: [\"slack\"],\n };\n },\n createAgentDelivery(parsed) {\n const to = requireSlackSendTargetId(parsed.id, \"Slack target\");\n requireSlackTargetKind(parsed, to);\n const threadTs = requireSlackThreadTs(parsed.threadId, \"Slack target thread\");\n return {\n channel: \"slack\",\n to,\n replyChannel: \"slack\",\n replyTo: slackTargetKey(to, threadTs),\n };\n },\n createInbound(input) {\n const channel = requireSlackChannelId(input.conversation.id, \"Slack conversation\");\n const kind = slackConversationKind(channel);\n if (input.conversation.kind !== kind) {\n throw new Error(\"Slack inbound conversation kind does not match the native channel id.\");\n }\n const user = requireSlackUserId(input.senderId, \"Slack sender\");\n const threadTs = requireSlackThreadTs(input.threadId, \"Slack thread\");\n return {\n ...createAdminInboundRequest(slack),\n providerBody: {\n channel,\n user,\n ...(input.senderName ? { username: input.senderName } : {}),\n ...(threadTs ? { threadTs } : {}),\n text: input.text,\n },\n providerTargetKey: slackTargetKey(channel, threadTs),\n qaTarget: qaTargetForInbound(input),\n stateConversation: {\n id: channel,\n kind,\n },\n ...(threadTs ? { threadId: threadTs } : {}),\n };\n },\n createOutboundFromRecorderEvent({ event, targetByProviderTarget }) {\n if (!isRecord(event) || event.type !== \"api\" || typeof event.path !== \"string\") {\n return null;\n }\n if (!event.path.endsWith(\"/api/chat.postMessage\") || !isRecord(event.body)) {\n return null;\n }\n const channel = readString(event.body.channel);\n const text = slackOutboundText(event.body);\n if (!channel || !text) {\n return null;\n }\n const threadTs = readString(event.body.thread_ts);\n const providerTargetKey = slackTargetKey(channel, threadTs);\n return {\n accountId: DEFAULT_ACCOUNT_ID,\n senderId: \"openclaw\",\n senderName: \"OpenClaw QA\",\n text,\n to: targetByProviderTarget.get(providerTargetKey) ?? providerTargetKey,\n };\n },\n };\n },\n});\n"]}
|
|
1
|
+
{"version":3,"file":"slack.js","sourceRoot":"","sources":["../../../../src/openclaw/bridges/slack.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,yBAAyB,EACzB,oCAAoC,EACpC,kBAAkB,EAClB,QAAQ,EACR,kBAAkB,EAClB,UAAU,GACX,MAAM,cAAc,CAAC;AACtB,OAAO,EACL,cAAc,EACd,qBAAqB,EACrB,yBAAyB,EACzB,aAAa,EACb,kBAAkB,GACnB,MAAM,8BAA8B,CAAC;AACtC,OAAO,EAAE,mBAAmB,EAAE,MAAM,qBAAqB,CAAC;AAE1D,SAAS,wBAAwB,CAAC,KAAa,EAAE,KAAa;IAC5D,MAAM,OAAO,GAAG,KAAK,CAAC,IAAI,EAAE,CAAC;IAC7B,IAAI,CAAC,yBAAyB,CAAC,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC;QACrD,MAAM,IAAI,KAAK,CAAC,GAAG,KAAK,kDAAkD,CAAC,CAAC;IAC9E,CAAC;IACD,OAAO,OAAO,CAAC;AACjB,CAAC;AAED,SAAS,sBAAsB,CAC7B,MAAwE,EACxE,QAAgB;IAEhB,IAAI,MAAM,CAAC,MAAM,IAAI,MAAM,CAAC,QAAQ,KAAK,SAAS,EAAE,CAAC;QACnD,OAAO;IACT,CAAC;IACD,MAAM,UAAU,GAAG,SAAS,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,OAAO,CAAC;IACjE,IAAI,MAAM,CAAC,IAAI,KAAK,UAAU,EAAE,CAAC;QAC/B,MAAM,IAAI,KAAK,CAAC,8DAA8D,CAAC,CAAC;IAClF,CAAC;AACH,CAAC;AAED,SAAS,qBAAqB,CAAC,KAAa,EAAE,KAAa;IACzD,MAAM,OAAO,GAAG,KAAK,CAAC,IAAI,EAAE,CAAC;IAC7B,IAAI,CAAC,qBAAqB,CAAC,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC;QACjD,MAAM,IAAI,KAAK,CAAC,GAAG,KAAK,0CAA0C,CAAC,CAAC;IACtE,CAAC;IACD,OAAO,OAAO,CAAC;AACjB,CAAC;AAED,SAAS,kBAAkB,CAAC,KAAa,EAAE,KAAa;IACtD,MAAM,OAAO,GAAG,KAAK,CAAC,IAAI,EAAE,CAAC;IAC7B,IAAI,CAAC,kBAAkB,CAAC,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC;QAC9C,MAAM,IAAI,KAAK,CAAC,GAAG,KAAK,kCAAkC,CAAC,CAAC;IAC9D,CAAC;IACD,OAAO,OAAO,CAAC;AACjB,CAAC;AAED,SAAS,oBAAoB,CAAC,KAAyB,EAAE,KAAa;IACpE,MAAM,OAAO,GAAG,KAAK,EAAE,IAAI,EAAE,CAAC;IAC9B,IAAI,CAAC,OAAO,EAAE,CAAC;QACb,OAAO,SAAS,CAAC;IACnB,CAAC;IACD,IAAI,CAAC,aAAa,CAAC,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC;QACzC,MAAM,IAAI,KAAK,CAAC,GAAG,KAAK,oCAAoC,CAAC,CAAC;IAChE,CAAC;IACD,OAAO,OAAO,CAAC;AACjB,CAAC;AAED,SAAS,qBAAqB,CAAC,OAAe;IAC5C,OAAO,OAAO,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,OAAO,CAAC;AACtD,CAAC;AAED,SAAS,aAAa,CAAC,KAAc,EAAE,MAAgB;IACrD,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,CAAC,IAAI,EAAE,EAAE,CAAC;QAC9C,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IACrB,CAAC;AACH,CAAC;AAED,SAAS,qBAAqB,CAAC,KAAc;IAC3C,IAAI,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC;QACzB,OAAO,KAAK,CAAC;IACf,CAAC;IACD,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE,CAAC;QAC9B,OAAO,EAAE,CAAC;IACZ,CAAC;IACD,IAAI,CAAC;QACH,MAAM,MAAM,GAAY,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;QAC1C,OAAO,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC;IAC7C,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,EAAE,CAAC;IACZ,CAAC;AACH,CAAC;AAED,SAAS,eAAe,CAAC,KAAc;IACrC,IAAI,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC;QACzB,OAAO,KAAK,CAAC,GAAG,CAAC,eAAe,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IAC7C,CAAC;IACD,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,EAAE,CAAC;QACrB,OAAO,EAAE,CAAC;IACZ,CAAC;IACD,IAAI,KAAK,CAAC,IAAI,KAAK,MAAM,IAAI,OAAO,KAAK,CAAC,GAAG,KAAK,QAAQ,EAAE,CAAC;QAC3D,OAAO,OAAO,KAAK,CAAC,IAAI,KAAK,QAAQ,IAAI,KAAK,CAAC,IAAI,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC;IAC1F,CAAC;IACD,IAAI,KAAK,CAAC,IAAI,KAAK,MAAM,IAAI,OAAO,KAAK,CAAC,OAAO,KAAK,QAAQ,EAAE,CAAC;QAC/D,OAAO,KAAK,KAAK,CAAC,OAAO,GAAG,CAAC;IAC/B,CAAC;IACD,IAAI,KAAK,CAAC,IAAI,KAAK,SAAS,IAAI,OAAO,KAAK,CAAC,UAAU,KAAK,QAAQ,EAAE,CAAC;QACrE,OAAO,KAAK,KAAK,CAAC,UAAU,GAAG,CAAC;IAClC,CAAC;IACD,IAAI,KAAK,CAAC,IAAI,KAAK,WAAW,IAAI,OAAO,KAAK,CAAC,YAAY,KAAK,QAAQ,EAAE,CAAC;QACzE,OAAO,aAAa,KAAK,CAAC,YAAY,GAAG,CAAC;IAC5C,CAAC;IACD,IAAI,KAAK,CAAC,IAAI,KAAK,OAAO,IAAI,OAAO,KAAK,CAAC,IAAI,KAAK,QAAQ,EAAE,CAAC;QAC7D,OAAO,IAAI,KAAK,CAAC,IAAI,GAAG,CAAC;IAC3B,CAAC;IACD,IAAI,KAAK,CAAC,IAAI,KAAK,WAAW,IAAI,OAAO,KAAK,CAAC,KAAK,KAAK,QAAQ,EAAE,CAAC;QAClE,OAAO,KAAK,KAAK,CAAC,KAAK,GAAG,CAAC;IAC7B,CAAC;IACD,IAAI,KAAK,CAAC,IAAI,KAAK,MAAM,EAAE,CAAC;QAC1B,IAAI,OAAO,KAAK,CAAC,QAAQ,KAAK,QAAQ,IAAI,KAAK,CAAC,QAAQ,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YACpE,OAAO,KAAK,CAAC,QAAQ,CAAC;QACxB,CAAC;QACD,IACE,CAAC,OAAO,KAAK,CAAC,SAAS,KAAK,QAAQ,IAAI,OAAO,KAAK,CAAC,SAAS,KAAK,QAAQ,CAAC;YAC5E,OAAO,KAAK,CAAC,MAAM,KAAK,QAAQ,EAChC,CAAC;YACD,OAAO,UAAU,KAAK,CAAC,SAAS,IAAI,KAAK,CAAC,MAAM,GAAG,CAAC;QACtD,CAAC;IACH,CAAC;IACD,IAAI,OAAO,KAAK,CAAC,IAAI,KAAK,QAAQ,EAAE,CAAC;QACnC,OAAO,KAAK,CAAC,IAAI,CAAC;IACpB,CAAC;IACD,OAAO,eAAe,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC;AACzC,CAAC;AAED,SAAS,qBAAqB,CAAC,KAAc,EAAE,MAAgB;IAC7D,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE,CAAC;QAC9B,aAAa,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC;QAC7B,OAAO;IACT,CAAC;IACD,IAAI,QAAQ,CAAC,KAAK,CAAC,IAAI,OAAO,KAAK,CAAC,IAAI,KAAK,QAAQ,EAAE,CAAC;QACtD,aAAa,CAAC,KAAK,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;QAClC,OAAO;IACT,CAAC;IACD,qBAAqB,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC;AACvC,CAAC;AAED,SAAS,qBAAqB,CAAC,KAAc,EAAE,MAAgB;IAC7D,IAAI,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC;QACzB,KAAK,MAAM,KAAK,IAAI,KAAK,EAAE,CAAC;YAC1B,qBAAqB,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC;QACvC,CAAC;QACD,OAAO;IACT,CAAC;IACD,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,EAAE,CAAC;QACrB,OAAO;IACT,CAAC;IACD,IACE,KAAK,CAAC,IAAI,KAAK,mBAAmB;QAClC,KAAK,CAAC,IAAI,KAAK,wBAAwB;QACvC,KAAK,CAAC,IAAI,KAAK,iBAAiB,EAChC,CAAC;QACD,aAAa,CAAC,eAAe,CAAC,KAAK,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAC,CAAC;QACvD,OAAO;IACT,CAAC;IACD,KAAK,MAAM,GAAG,IAAI;QAChB,UAAU;QACV,OAAO;QACP,MAAM;QACN,UAAU;QACV,SAAS;QACT,SAAS;QACT,QAAQ;KACA,EAAE,CAAC;QACX,qBAAqB,CAAC,KAAK,CAAC,GAAG,CAAC,EAAE,MAAM,CAAC,CAAC;IAC5C,CAAC;IACD,qBAAqB,CAAC,KAAK,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;IAC1C,KAAK,MAAM,GAAG,IAAI;QAChB,QAAQ;QACR,UAAU;QACV,QAAQ;QACR,MAAM;QACN,OAAO;QACP,SAAS;QACT,YAAY;QACZ,MAAM;KACE,EAAE,CAAC;QACX,qBAAqB,CAAC,KAAK,CAAC,GAAG,CAAC,EAAE,MAAM,CAAC,CAAC;IAC5C,CAAC;AACH,CAAC;AAED,SAAS,0BAA0B,CAAC,KAAc,EAAE,MAAgB;IAClE,IAAI,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC;QACzB,KAAK,MAAM,KAAK,IAAI,KAAK,EAAE,CAAC;YAC1B,0BAA0B,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC;QAC5C,CAAC;QACD,OAAO;IACT,CAAC;IACD,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,EAAE,CAAC;QACrB,OAAO;IACT,CAAC;IACD,KAAK,MAAM,GAAG,IAAI,CAAC,UAAU,EAAE,SAAS,EAAE,aAAa,EAAE,OAAO,EAAE,MAAM,EAAE,QAAQ,CAAU,EAAE,CAAC;QAC7F,aAAa,CAAC,KAAK,CAAC,GAAG,CAAC,EAAE,MAAM,CAAC,CAAC;IACpC,CAAC;IACD,IAAI,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,MAAM,CAAC,EAAE,CAAC;QAChC,KAAK,MAAM,KAAK,IAAI,KAAK,CAAC,MAAM,EAAE,CAAC;YACjC,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,EAAE,CAAC;gBACrB,SAAS;YACX,CAAC;YACD,aAAa,CAAC,KAAK,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC;YACnC,aAAa,CAAC,KAAK,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC;QACrC,CAAC;IACH,CAAC;IACD,qBAAqB,CAAC,KAAK,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;AAC9C,CAAC;AAED,SAAS,iBAAiB,CAAC,IAA6B;IACtD,IAAI,OAAO,IAAI,CAAC,IAAI,KAAK,QAAQ,EAAE,CAAC;QAClC,IAAI,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,EAAE,CAAC;YACrB,OAAO,IAAI,CAAC,IAAI,CAAC;QACnB,CAAC;IACH,CAAC;IACD,MAAM,QAAQ,GAAa,EAAE,CAAC;IAC9B,qBAAqB,CAAC,qBAAqB,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,QAAQ,CAAC,CAAC;IACpE,0BAA0B,CAAC,qBAAqB,CAAC,IAAI,CAAC,WAAW,CAAC,EAAE,QAAQ,CAAC,CAAC;IAC9E,OAAO,QAAQ,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;AAC/D,CAAC;AAED,MAAM,CAAC,MAAM,uCAAuC,GAAG,oCAAoC,CAAC;IAC1F,QAAQ,EAAE,OAAO;IACjB,aAAa,CAAC,KAAK;QACjB,OAAO;YACL,KAAK,CAAC,KAAK,CAAC,MAAM;gBAChB,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,GAAG,KAAK,CAAC,SAAS,CAAC,OAAO,WAAW,EAAE;oBAClE,OAAO,EAAE,EAAE,aAAa,EAAE,UAAU,KAAK,CAAC,QAAQ,EAAE,EAAE;oBACtD,MAAM,EAAE,MAAM;oBACd,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;iBAC9B,CAAC,CAAC;gBACH,IAAI,CAAC,QAAQ,CAAC,EAAE,EAAE,CAAC;oBACjB,MAAM,mBAAmB,CACvB,QAAQ,EACR,mDAAmD,QAAQ,CAAC,MAAM,GAAG,CACtE,CAAC;gBACJ,CAAC;gBACD,MAAM,MAAM,GAAY,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAC;gBAC9C,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,IAAI,MAAM,CAAC,EAAE,KAAK,IAAI,EAAE,CAAC;oBAC5C,MAAM,KAAK,GAAG,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;oBACtE,MAAM,IAAI,KAAK,CAAC,0CAA0C,KAAK,IAAI,eAAe,GAAG,CAAC,CAAC;gBACzF,CAAC;gBACD,OAAO,MAAM,CAAC;YAChB,CAAC;YACD,aAAa;gBACX,OAAO;oBACL,SAAS,EAAE,kBAAkB;oBAC7B,OAAO,EAAE,OAAO;oBAChB,0BAA0B,EAAE,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC;wBACpC,GAAG,GAAG;wBACN,aAAa,EAAE,KAAK,CAAC,SAAS,CAAC,OAAO;wBACtC,eAAe,EAAE,KAAK,CAAC,QAAQ;wBAC/B,oBAAoB,EAAE,KAAK,CAAC,aAAa;qBAC1C,CAAC;oBACF,mBAAmB,EAAE,CAAC,cAAc,GAAG,EAAE,EAAE,EAAE;wBAC3C,MAAM,QAAQ,GAAG,QAAQ,CAAC,cAAc,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,cAAc,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,CAAC;wBAClF,MAAM,WAAW,GAAG,QAAQ,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC;wBACnE,MAAM,aAAa,GAAG,QAAQ,CAAC,WAAW,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,WAAW,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,CAAC;wBACjF,MAAM,mBAAmB,GAAG,QAAQ,CAAC,aAAa,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,aAAa,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;wBAEnF,OAAO;4BACL,GAAG,cAAc;4BACjB,QAAQ,EAAE;gCACR,GAAG,QAAQ;gCACX,KAAK,EAAE;oCACL,GAAG,WAAW;oCACd,OAAO,EAAE,IAAI;oCACb,IAAI,EAAE,MAAM;oCACZ,QAAQ,EAAE,KAAK,CAAC,QAAQ;oCACxB,aAAa,EAAE,KAAK,CAAC,aAAa;oCAClC,WAAW,EAAE,eAAe;oCAC5B,QAAQ,EAAE,MAAM;oCAChB,SAAS,EAAE,CAAC,GAAG,CAAC;oCAChB,WAAW,EAAE,MAAM;oCACnB,QAAQ,EAAE;wCACR,GAAG,aAAa;wCAChB,GAAG,EAAE;4CACH,GAAG,mBAAmB;4CACtB,cAAc,EAAE,KAAK;yCACtB;qCACF;iCACF;6BACF;yBACF,CAAC;oBACJ,CAAC;oBACD,iBAAiB,EAAE,CAAC,OAAO,CAAC;iBAC7B,CAAC;YACJ,CAAC;YACD,mBAAmB,CAAC,MAAM;gBACxB,MAAM,EAAE,GAAG,wBAAwB,CAAC,MAAM,CAAC,EAAE,EAAE,cAAc,CAAC,CAAC;gBAC/D,MAAM,QAAQ,GAAG,oBAAoB,CAAC,MAAM,CAAC,QAAQ,EAAE,qBAAqB,CAAC,CAAC;gBAC9E,IAAI,QAAQ,IAAI,CAAC,qBAAqB,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE,CAAC;oBACxD,MAAM,IAAI,KAAK,CAAC,+DAA+D,CAAC,CAAC;gBACnF,CAAC;gBACD,sBAAsB,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC;gBACnC,OAAO;oBACL,OAAO,EAAE,OAAO;oBAChB,EAAE;oBACF,YAAY,EAAE,OAAO;oBACrB,OAAO,EAAE,cAAc,CAAC,EAAE,EAAE,QAAQ,CAAC;iBACtC,CAAC;YACJ,CAAC;YACD,aAAa,CAAC,KAAK;gBACjB,MAAM,OAAO,GAAG,qBAAqB,CAAC,KAAK,CAAC,YAAY,CAAC,EAAE,EAAE,oBAAoB,CAAC,CAAC;gBACnF,MAAM,IAAI,GAAG,qBAAqB,CAAC,OAAO,CAAC,CAAC;gBAC5C,IAAI,KAAK,CAAC,YAAY,CAAC,IAAI,KAAK,IAAI,EAAE,CAAC;oBACrC,MAAM,IAAI,KAAK,CAAC,uEAAuE,CAAC,CAAC;gBAC3F,CAAC;gBACD,MAAM,IAAI,GAAG,kBAAkB,CAAC,KAAK,CAAC,QAAQ,EAAE,cAAc,CAAC,CAAC;gBAChE,MAAM,QAAQ,GAAG,oBAAoB,CAAC,KAAK,CAAC,QAAQ,EAAE,cAAc,CAAC,CAAC;gBACtE,OAAO;oBACL,GAAG,yBAAyB,CAAC,KAAK,CAAC;oBACnC,YAAY,EAAE;wBACZ,OAAO;wBACP,IAAI;wBACJ,GAAG,CAAC,KAAK,CAAC,UAAU,CAAC,CAAC,CAAC,EAAE,QAAQ,EAAE,KAAK,CAAC,UAAU,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;wBAC3D,GAAG,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,QAAQ,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;wBACjC,IAAI,EAAE,KAAK,CAAC,IAAI;qBACjB;oBACD,iBAAiB,EAAE,cAAc,CAAC,OAAO,EAAE,QAAQ,CAAC;oBACpD,QAAQ,EAAE,kBAAkB,CAAC,KAAK,CAAC;oBACnC,iBAAiB,EAAE;wBACjB,EAAE,EAAE,OAAO;wBACX,IAAI;qBACL;oBACD,GAAG,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,QAAQ,EAAE,QAAQ,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;iBAC5C,CAAC;YACJ,CAAC;YACD,+BAA+B,CAAC,EAAE,KAAK,EAAE,sBAAsB,EAAE;gBAC/D,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,IAAI,KAAK,CAAC,IAAI,KAAK,KAAK,IAAI,OAAO,KAAK,CAAC,IAAI,KAAK,QAAQ,EAAE,CAAC;oBAC/E,OAAO,IAAI,CAAC;gBACd,CAAC;gBACD,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,QAAQ,CAAC,uBAAuB,CAAC,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC;oBAC3E,OAAO,IAAI,CAAC;gBACd,CAAC;gBACD,MAAM,OAAO,GAAG,UAAU,CAAC,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;gBAC/C,MAAM,IAAI,GAAG,iBAAiB,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;gBAC3C,IAAI,CAAC,OAAO,IAAI,CAAC,IAAI,EAAE,CAAC;oBACtB,OAAO,IAAI,CAAC;gBACd,CAAC;gBACD,MAAM,QAAQ,GAAG,UAAU,CAAC,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;gBAClD,MAAM,iBAAiB,GAAG,cAAc,CAAC,OAAO,EAAE,QAAQ,CAAC,CAAC;gBAC5D,OAAO;oBACL,SAAS,EAAE,kBAAkB;oBAC7B,QAAQ,EAAE,UAAU;oBACpB,UAAU,EAAE,aAAa;oBACzB,IAAI;oBACJ,EAAE,EAAE,sBAAsB,CAAC,GAAG,CAAC,iBAAiB,CAAC,IAAI,iBAAiB;iBACvE,CAAC;YACJ,CAAC;SACF,CAAC;IACJ,CAAC;CACF,CAAC,CAAC","sourcesContent":["import {\n createAdminInboundRequest,\n createOpenClawCrablineProviderBridge,\n DEFAULT_ACCOUNT_ID,\n isRecord,\n qaTargetForInbound,\n readString,\n} from \"../shared.js\";\nimport {\n slackTargetKey,\n SLACK_CHANNEL_ID_RULE,\n SLACK_SEND_TARGET_ID_RULE,\n SLACK_TS_RULE,\n SLACK_USER_ID_RULE,\n} from \"../../providers/slack-ids.js\";\nimport { throwProbeHttpError } from \"./probe-response.js\";\n\nfunction requireSlackSendTargetId(value: string, label: string): string {\n const trimmed = value.trim();\n if (!SLACK_SEND_TARGET_ID_RULE.pattern.test(trimmed)) {\n throw new Error(`${label} must be a native Slack conversation or user id.`);\n }\n return trimmed;\n}\n\nfunction requireSlackTargetKind(\n parsed: { kind: \"direct\" | \"group\"; native: boolean; threadId?: string },\n targetId: string,\n): void {\n if (parsed.native || parsed.threadId !== undefined) {\n return;\n }\n const nativeKind = /^[DUW]/u.test(targetId) ? \"direct\" : \"group\";\n if (parsed.kind !== nativeKind) {\n throw new Error(\"Slack target kind does not match the native conversation id.\");\n }\n}\n\nfunction requireSlackChannelId(value: string, label: string): string {\n const trimmed = value.trim();\n if (!SLACK_CHANNEL_ID_RULE.pattern.test(trimmed)) {\n throw new Error(`${label} must be a native Slack conversation id.`);\n }\n return trimmed;\n}\n\nfunction requireSlackUserId(value: string, label: string): string {\n const trimmed = value.trim();\n if (!SLACK_USER_ID_RULE.pattern.test(trimmed)) {\n throw new Error(`${label} must be a native Slack user id.`);\n }\n return trimmed;\n}\n\nfunction requireSlackThreadTs(value: string | undefined, label: string): string | undefined {\n const trimmed = value?.trim();\n if (!trimmed) {\n return undefined;\n }\n if (!SLACK_TS_RULE.pattern.test(trimmed)) {\n throw new Error(`${label} must be a native Slack timestamp.`);\n }\n return trimmed;\n}\n\nfunction slackConversationKind(channel: string): \"direct\" | \"group\" {\n return channel.startsWith(\"D\") ? \"direct\" : \"group\";\n}\n\nfunction pushSlackText(value: unknown, output: string[]): void {\n if (typeof value === \"string\" && value.trim()) {\n output.push(value);\n }\n}\n\nfunction structuredSlackValues(value: unknown): unknown[] {\n if (Array.isArray(value)) {\n return value;\n }\n if (typeof value !== \"string\") {\n return [];\n }\n try {\n const parsed: unknown = JSON.parse(value);\n return Array.isArray(parsed) ? parsed : [];\n } catch {\n return [];\n }\n}\n\nfunction slackInlineText(value: unknown): string {\n if (Array.isArray(value)) {\n return value.map(slackInlineText).join(\"\");\n }\n if (!isRecord(value)) {\n return \"\";\n }\n if (value.type === \"link\" && typeof value.url === \"string\") {\n return typeof value.text === \"string\" && value.text.length > 0 ? value.text : value.url;\n }\n if (value.type === \"user\" && typeof value.user_id === \"string\") {\n return `<@${value.user_id}>`;\n }\n if (value.type === \"channel\" && typeof value.channel_id === \"string\") {\n return `<#${value.channel_id}>`;\n }\n if (value.type === \"usergroup\" && typeof value.usergroup_id === \"string\") {\n return `<!subteam^${value.usergroup_id}>`;\n }\n if (value.type === \"emoji\" && typeof value.name === \"string\") {\n return `:${value.name}:`;\n }\n if (value.type === \"broadcast\" && typeof value.range === \"string\") {\n return `<!${value.range}>`;\n }\n if (value.type === \"date\") {\n if (typeof value.fallback === \"string\" && value.fallback.length > 0) {\n return value.fallback;\n }\n if (\n (typeof value.timestamp === \"number\" || typeof value.timestamp === \"string\") &&\n typeof value.format === \"string\"\n ) {\n return `<!date^${value.timestamp}^${value.format}>`;\n }\n }\n if (typeof value.text === \"string\") {\n return value.text;\n }\n return slackInlineText(value.elements);\n}\n\nfunction collectSlackTextValue(value: unknown, output: string[]): void {\n if (typeof value === \"string\") {\n pushSlackText(value, output);\n return;\n }\n if (isRecord(value) && typeof value.text === \"string\") {\n pushSlackText(value.text, output);\n return;\n }\n collectSlackBlockText(value, output);\n}\n\nfunction collectSlackBlockText(value: unknown, output: string[]): void {\n if (Array.isArray(value)) {\n for (const entry of value) {\n collectSlackBlockText(entry, output);\n }\n return;\n }\n if (!isRecord(value)) {\n return;\n }\n if (\n value.type === \"rich_text_section\" ||\n value.type === \"rich_text_preformatted\" ||\n value.type === \"rich_text_quote\"\n ) {\n pushSlackText(slackInlineText(value.elements), output);\n return;\n }\n for (const key of [\n \"alt_text\",\n \"title\",\n \"body\",\n \"subtitle\",\n \"subtext\",\n \"details\",\n \"output\",\n ] as const) {\n collectSlackTextValue(value[key], output);\n }\n collectSlackTextValue(value.text, output);\n for (const key of [\n \"blocks\",\n \"elements\",\n \"fields\",\n \"rows\",\n \"tasks\",\n \"actions\",\n \"hero_image\",\n \"icon\",\n ] as const) {\n collectSlackBlockText(value[key], output);\n }\n}\n\nfunction collectSlackAttachmentText(value: unknown, output: string[]): void {\n if (Array.isArray(value)) {\n for (const entry of value) {\n collectSlackAttachmentText(entry, output);\n }\n return;\n }\n if (!isRecord(value)) {\n return;\n }\n for (const key of [\"fallback\", \"pretext\", \"author_name\", \"title\", \"text\", \"footer\"] as const) {\n pushSlackText(value[key], output);\n }\n if (Array.isArray(value.fields)) {\n for (const field of value.fields) {\n if (!isRecord(field)) {\n continue;\n }\n pushSlackText(field.title, output);\n pushSlackText(field.value, output);\n }\n }\n collectSlackBlockText(value.blocks, output);\n}\n\nfunction slackOutboundText(body: Record<string, unknown>): string | undefined {\n if (typeof body.text === \"string\") {\n if (body.text.trim()) {\n return body.text;\n }\n }\n const fallback: string[] = [];\n collectSlackBlockText(structuredSlackValues(body.blocks), fallback);\n collectSlackAttachmentText(structuredSlackValues(body.attachments), fallback);\n return fallback.length > 0 ? fallback.join(\"\\n\") : undefined;\n}\n\nexport const SLACK_OPENCLAW_CRABLINE_PROVIDER_BRIDGE = createOpenClawCrablineProviderBridge({\n provider: \"slack\",\n createAdapter(slack) {\n return {\n async probe(signal) {\n const response = await fetch(`${slack.endpoints.apiRoot}auth.test`, {\n headers: { authorization: `Bearer ${slack.botToken}` },\n method: \"POST\",\n ...(signal ? { signal } : {}),\n });\n if (!response.ok) {\n await throwProbeHttpError(\n response,\n `Crabline Slack auth.test probe failed with HTTP ${response.status}.`,\n );\n }\n const result: unknown = await response.json();\n if (!isRecord(result) || result.ok !== true) {\n const error = isRecord(result) ? readString(result.error) : undefined;\n throw new Error(`Crabline Slack auth.test probe failed: ${error ?? \"unknown_error\"}.`);\n }\n return result;\n },\n createBinding() {\n return {\n accountId: DEFAULT_ACCOUNT_ID,\n channel: \"slack\",\n createProviderReadinessEnv: (env) => ({\n ...env,\n SLACK_API_URL: slack.endpoints.apiRoot,\n SLACK_BOT_TOKEN: slack.botToken,\n SLACK_SIGNING_SECRET: slack.signingSecret,\n }),\n createGatewayConfig: (openclawConfig = {}) => {\n const channels = isRecord(openclawConfig.channels) ? openclawConfig.channels : {};\n const slackConfig = isRecord(channels.slack) ? channels.slack : {};\n const slackChannels = isRecord(slackConfig.channels) ? slackConfig.channels : {};\n const defaultSlackChannel = isRecord(slackChannels[\"*\"]) ? slackChannels[\"*\"] : {};\n\n return {\n ...openclawConfig,\n channels: {\n ...channels,\n slack: {\n ...slackConfig,\n enabled: true,\n mode: \"http\",\n botToken: slack.botToken,\n signingSecret: slack.signingSecret,\n webhookPath: \"/slack/events\",\n dmPolicy: \"open\",\n allowFrom: [\"*\"],\n groupPolicy: \"open\",\n channels: {\n ...slackChannels,\n \"*\": {\n ...defaultSlackChannel,\n requireMention: false,\n },\n },\n },\n },\n };\n },\n requiredPluginIds: [\"slack\"],\n };\n },\n createAgentDelivery(parsed) {\n const to = requireSlackSendTargetId(parsed.id, \"Slack target\");\n const threadTs = requireSlackThreadTs(parsed.threadId, \"Slack target thread\");\n if (threadTs && !SLACK_CHANNEL_ID_RULE.pattern.test(to)) {\n throw new Error(\"Slack thread targets require a native parent conversation id.\");\n }\n requireSlackTargetKind(parsed, to);\n return {\n channel: \"slack\",\n to,\n replyChannel: \"slack\",\n replyTo: slackTargetKey(to, threadTs),\n };\n },\n createInbound(input) {\n const channel = requireSlackChannelId(input.conversation.id, \"Slack conversation\");\n const kind = slackConversationKind(channel);\n if (input.conversation.kind !== kind) {\n throw new Error(\"Slack inbound conversation kind does not match the native channel id.\");\n }\n const user = requireSlackUserId(input.senderId, \"Slack sender\");\n const threadTs = requireSlackThreadTs(input.threadId, \"Slack thread\");\n return {\n ...createAdminInboundRequest(slack),\n providerBody: {\n channel,\n user,\n ...(input.senderName ? { username: input.senderName } : {}),\n ...(threadTs ? { threadTs } : {}),\n text: input.text,\n },\n providerTargetKey: slackTargetKey(channel, threadTs),\n qaTarget: qaTargetForInbound(input),\n stateConversation: {\n id: channel,\n kind,\n },\n ...(threadTs ? { threadId: threadTs } : {}),\n };\n },\n createOutboundFromRecorderEvent({ event, targetByProviderTarget }) {\n if (!isRecord(event) || event.type !== \"api\" || typeof event.path !== \"string\") {\n return null;\n }\n if (!event.path.endsWith(\"/api/chat.postMessage\") || !isRecord(event.body)) {\n return null;\n }\n const channel = readString(event.body.channel);\n const text = slackOutboundText(event.body);\n if (!channel || !text) {\n return null;\n }\n const threadTs = readString(event.body.thread_ts);\n const providerTargetKey = slackTargetKey(channel, threadTs);\n return {\n accountId: DEFAULT_ACCOUNT_ID,\n senderId: \"openclaw\",\n senderName: \"OpenClaw QA\",\n text,\n to: targetByProviderTarget.get(providerTargetKey) ?? providerTargetKey,\n };\n },\n };\n },\n});\n"]}
|