@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,12 +1,11 @@
|
|
|
1
1
|
import { createHash } from "node:crypto";
|
|
2
2
|
import { createAdminInboundRequest, createOpenClawCrablineProviderBridge, DEFAULT_ACCOUNT_ID, isRecord, qaTargetForInbound, readNonBlankString, readString, } from "../shared.js";
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
const
|
|
6
|
-
const
|
|
3
|
+
import { canonicalizeTelegramUsername, TELEGRAM_BOT_USERNAME_PATTERN, TELEGRAM_CHAT_USERNAME_PATTERN, TELEGRAM_NATIVE_CHAT_ID_MAX, telegramUsernameChatId, } from "../../servers/telegram-identity.js";
|
|
4
|
+
import { throwProbeHttpError } from "./probe-response.js";
|
|
5
|
+
const TELEGRAM_SYMBOLIC_ID_BASE = TELEGRAM_NATIVE_CHAT_ID_MAX + 1n;
|
|
6
|
+
const TELEGRAM_SYMBOLIC_ID_RANGE = 1n << 50n;
|
|
7
7
|
const TELEGRAM_OUTBOUND_METHOD_RE = /\/(sendAnimation|sendAudio|sendDocument|sendMessage|sendPhoto|sendVideo)$/iu;
|
|
8
|
-
|
|
9
|
-
function normalizeTelegramChatId(kind, id) {
|
|
8
|
+
function normalizeTelegramChatId(kind, id, options) {
|
|
10
9
|
const value = id.trim();
|
|
11
10
|
if (!value) {
|
|
12
11
|
throw new Error("Telegram target is required.");
|
|
@@ -20,19 +19,32 @@ function normalizeTelegramChatId(kind, id) {
|
|
|
20
19
|
numericId > BigInt(Number.MAX_SAFE_INTEGER)) {
|
|
21
20
|
throw new Error("Telegram numeric target must be a safe integer.");
|
|
22
21
|
}
|
|
22
|
+
if (numericId < -TELEGRAM_NATIVE_CHAT_ID_MAX || numericId > TELEGRAM_NATIVE_CHAT_ID_MAX) {
|
|
23
|
+
throw new Error("Telegram native numeric targets must fit within 52 significant bits.");
|
|
24
|
+
}
|
|
23
25
|
return numericId.toString();
|
|
24
26
|
}
|
|
25
|
-
if (kind === "group" && TELEGRAM_USERNAME_RE.test(value)) {
|
|
26
|
-
return value;
|
|
27
|
-
}
|
|
28
27
|
if (value.startsWith("@")) {
|
|
29
|
-
|
|
28
|
+
const username = canonicalizeTelegramUsername(value);
|
|
29
|
+
if (!username) {
|
|
30
|
+
throw new Error("Telegram usernames must contain 4-32 letters, digits, or underscores.");
|
|
31
|
+
}
|
|
32
|
+
if (kind === "group" && options.preserveGroupUsername) {
|
|
33
|
+
return username;
|
|
34
|
+
}
|
|
35
|
+
if (kind === "group") {
|
|
36
|
+
return String(telegramUsernameChatId(username));
|
|
37
|
+
}
|
|
38
|
+
return syntheticTelegramChatId(kind, username);
|
|
30
39
|
}
|
|
40
|
+
return syntheticTelegramChatId(kind, value);
|
|
41
|
+
}
|
|
42
|
+
function syntheticTelegramChatId(kind, value) {
|
|
31
43
|
const hash = createHash("sha256").update(`${kind}:${value}`).digest().readBigUInt64BE();
|
|
32
44
|
if (kind === "group") {
|
|
33
|
-
return String(-(
|
|
45
|
+
return String(-(TELEGRAM_SYMBOLIC_ID_BASE + (hash % TELEGRAM_SYMBOLIC_ID_RANGE)));
|
|
34
46
|
}
|
|
35
|
-
return String(
|
|
47
|
+
return String(TELEGRAM_SYMBOLIC_ID_BASE + (hash % TELEGRAM_SYMBOLIC_ID_RANGE));
|
|
36
48
|
}
|
|
37
49
|
function telegramTargetKey(chatId, threadId) {
|
|
38
50
|
return threadId === undefined ? chatId : `${chatId}:topic:${threadId}`;
|
|
@@ -51,7 +63,8 @@ function canonicalTelegramRecorderChatId(value) {
|
|
|
51
63
|
}
|
|
52
64
|
return numericId.toString();
|
|
53
65
|
}
|
|
54
|
-
|
|
66
|
+
const usernameChatId = telegramUsernameChatId(chatId);
|
|
67
|
+
return usernameChatId === undefined ? undefined : String(usernameChatId);
|
|
55
68
|
}
|
|
56
69
|
function telegramBotCommandEntity(text, commandName) {
|
|
57
70
|
if (!/^[a-z0-9_]{1,32}$/u.test(commandName)) {
|
|
@@ -89,9 +102,10 @@ export const TELEGRAM_OPENCLAW_CRABLINE_PROVIDER_BRIDGE = createOpenClawCrabline
|
|
|
89
102
|
createAdapter(telegram) {
|
|
90
103
|
return {
|
|
91
104
|
async probe(signal) {
|
|
105
|
+
const configuredBotId = /^([1-9]\d*):/u.exec(telegram.botToken)?.[1];
|
|
92
106
|
const response = await fetch(`${telegram.endpoints.apiRoot}/bot${telegram.botToken}/getMe`, signal ? { signal } : {});
|
|
93
107
|
if (!response.ok) {
|
|
94
|
-
|
|
108
|
+
await throwProbeHttpError(response, `Crabline Telegram getMe probe failed with HTTP ${response.status}.`);
|
|
95
109
|
}
|
|
96
110
|
const payload = await response.json();
|
|
97
111
|
if (!isRecord(payload) || payload.ok !== true) {
|
|
@@ -105,11 +119,12 @@ export const TELEGRAM_OPENCLAW_CRABLINE_PROVIDER_BRIDGE = createOpenClawCrabline
|
|
|
105
119
|
typeof result.id !== "number" ||
|
|
106
120
|
!Number.isSafeInteger(result.id) ||
|
|
107
121
|
result.id <= 0 ||
|
|
122
|
+
configuredBotId !== String(result.id) ||
|
|
108
123
|
result.is_bot !== true ||
|
|
109
124
|
!readNonBlankString(result.first_name) ||
|
|
110
125
|
(result.username !== undefined &&
|
|
111
126
|
(typeof result.username !== "string" ||
|
|
112
|
-
!
|
|
127
|
+
!TELEGRAM_BOT_USERNAME_PATTERN.test(`@${result.username}`)))) {
|
|
113
128
|
throw new Error("Crabline Telegram getMe probe failed: invalid response.");
|
|
114
129
|
}
|
|
115
130
|
return payload;
|
|
@@ -118,7 +133,7 @@ export const TELEGRAM_OPENCLAW_CRABLINE_PROVIDER_BRIDGE = createOpenClawCrabline
|
|
|
118
133
|
return {
|
|
119
134
|
accountId: DEFAULT_ACCOUNT_ID,
|
|
120
135
|
channel: "telegram",
|
|
121
|
-
|
|
136
|
+
createProviderReadinessEnv: (env) => ({
|
|
122
137
|
...env,
|
|
123
138
|
TELEGRAM_BOT_TOKEN: telegram.botToken,
|
|
124
139
|
}),
|
|
@@ -166,10 +181,13 @@ export const TELEGRAM_OPENCLAW_CRABLINE_PROVIDER_BRIDGE = createOpenClawCrabline
|
|
|
166
181
|
},
|
|
167
182
|
createAgentDelivery(parsed) {
|
|
168
183
|
const kind = parsed.native &&
|
|
169
|
-
(/^-\d+$/u.test(parsed.id.trim()) ||
|
|
184
|
+
(/^-\d+$/u.test(parsed.id.trim()) ||
|
|
185
|
+
TELEGRAM_CHAT_USERNAME_PATTERN.test(parsed.id.trim()))
|
|
170
186
|
? "group"
|
|
171
187
|
: parsed.kind;
|
|
172
|
-
const chatId = normalizeTelegramChatId(kind, parsed.id
|
|
188
|
+
const chatId = normalizeTelegramChatId(kind, parsed.id, {
|
|
189
|
+
preserveGroupUsername: true,
|
|
190
|
+
});
|
|
173
191
|
const threadId = parseTelegramThreadTargetId(parsed.threadId);
|
|
174
192
|
const to = telegramTargetKey(chatId, threadId);
|
|
175
193
|
return {
|
|
@@ -181,13 +199,21 @@ export const TELEGRAM_OPENCLAW_CRABLINE_PROVIDER_BRIDGE = createOpenClawCrabline
|
|
|
181
199
|
},
|
|
182
200
|
createInbound(input) {
|
|
183
201
|
const kind = input.conversation.kind === "direct" ? "direct" : "group";
|
|
184
|
-
const chatId = normalizeTelegramChatId(kind, input.conversation.id
|
|
202
|
+
const chatId = normalizeTelegramChatId(kind, input.conversation.id, {
|
|
203
|
+
preserveGroupUsername: false,
|
|
204
|
+
});
|
|
205
|
+
const senderId = normalizeTelegramChatId("direct", input.senderId, {
|
|
206
|
+
preserveGroupUsername: false,
|
|
207
|
+
});
|
|
208
|
+
if (kind === "direct" && chatId !== senderId) {
|
|
209
|
+
throw new Error("Telegram direct conversation and sender must normalize to the same identity.");
|
|
210
|
+
}
|
|
185
211
|
const threadId = parseTelegramThreadTargetId(input.threadId);
|
|
186
212
|
return {
|
|
187
213
|
...createAdminInboundRequest(telegram),
|
|
188
214
|
providerBody: {
|
|
189
215
|
chatId,
|
|
190
|
-
fromId: Number(
|
|
216
|
+
fromId: Number(senderId),
|
|
191
217
|
fromName: input.senderName ?? input.senderId,
|
|
192
218
|
...(threadId !== undefined ? { messageThreadId: threadId } : {}),
|
|
193
219
|
...(input.nativeCommand
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"telegram.js","sourceRoot":"","sources":["../../../../src/openclaw/bridges/telegram.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 TELEGRAM_SYMBOLIC_DIRECT_ID_BASE = 1n << 51n;\nconst TELEGRAM_SYMBOLIC_DIRECT_ID_MASK = TELEGRAM_SYMBOLIC_DIRECT_ID_BASE - 1n;\nconst TELEGRAM_SYMBOLIC_GROUP_ID_BASE = 1_000_000_000_000n;\nconst TELEGRAM_SYMBOLIC_GROUP_ID_RANGE = 10_000_000_000n;\nconst TELEGRAM_OUTBOUND_METHOD_RE =\n /\\/(sendAnimation|sendAudio|sendDocument|sendMessage|sendPhoto|sendVideo)$/iu;\nconst TELEGRAM_USERNAME_RE = /^@[A-Za-z][A-Za-z0-9_]{3,31}$/u;\n\nfunction normalizeTelegramChatId(kind: \"direct\" | \"group\", id: string): string {\n const value = id.trim();\n if (!value) {\n throw new Error(\"Telegram target is required.\");\n }\n if (/^-?\\d+$/u.test(value)) {\n const numericId = BigInt(value);\n if (numericId === 0n || (kind === \"direct\" ? numericId < 0n : numericId > 0n)) {\n throw new Error(\"Telegram numeric target sign does not match the declared target kind.\");\n }\n if (\n numericId < BigInt(Number.MIN_SAFE_INTEGER) ||\n numericId > BigInt(Number.MAX_SAFE_INTEGER)\n ) {\n throw new Error(\"Telegram numeric target must be a safe integer.\");\n }\n return numericId.toString();\n }\n if (kind === \"group\" && TELEGRAM_USERNAME_RE.test(value)) {\n return value;\n }\n if (value.startsWith(\"@\")) {\n throw new Error(\"Telegram usernames must contain 4-32 letters, digits, or underscores.\");\n }\n const hash = createHash(\"sha256\").update(`${kind}:${value}`).digest().readBigUInt64BE();\n if (kind === \"group\") {\n return String(-(TELEGRAM_SYMBOLIC_GROUP_ID_BASE + (hash % TELEGRAM_SYMBOLIC_GROUP_ID_RANGE)));\n }\n return String(TELEGRAM_SYMBOLIC_DIRECT_ID_BASE + (hash & TELEGRAM_SYMBOLIC_DIRECT_ID_MASK));\n}\n\nfunction telegramTargetKey(chatId: string, threadId?: number) {\n return threadId === undefined ? chatId : `${chatId}:topic:${threadId}`;\n}\n\nfunction canonicalTelegramRecorderChatId(value: unknown): string | undefined {\n const chatId = readString(value);\n if (!chatId) {\n return undefined;\n }\n if (/^-?\\d+$/u.test(chatId)) {\n const numericId = BigInt(chatId);\n if (\n numericId === 0n ||\n numericId < BigInt(Number.MIN_SAFE_INTEGER) ||\n numericId > BigInt(Number.MAX_SAFE_INTEGER)\n ) {\n return undefined;\n }\n return numericId.toString();\n }\n return TELEGRAM_USERNAME_RE.test(chatId) ? chatId : undefined;\n}\n\nfunction telegramBotCommandEntity(text: string, commandName: string) {\n if (!/^[a-z0-9_]{1,32}$/u.test(commandName)) {\n throw new Error(\n \"Telegram native command names must contain 1-32 lowercase letters, digits, or underscores.\",\n );\n }\n const commandPrefix = `/${commandName}`;\n const token = text.match(/^\\S+/u)?.[0];\n if (\n !token ||\n (token.toLowerCase() !== commandPrefix &&\n !new RegExp(`^/${commandName}@[A-Za-z][A-Za-z0-9_]{4,31}$`, \"iu\").test(token))\n ) {\n throw new Error(`Telegram native command text must start with ${commandPrefix}.`);\n }\n return {\n length: token.length,\n offset: 0,\n type: \"bot_command\",\n } as const;\n}\n\nfunction parseTelegramThreadTargetId(value: unknown): number | undefined {\n if (value === undefined) {\n return undefined;\n }\n const trimmed = readString(value);\n if (!trimmed || !/^[1-9]\\d*$/u.test(trimmed)) {\n throw new Error(\"Telegram thread target must be a safe positive integer.\");\n }\n const threadId = Number(trimmed);\n if (!Number.isSafeInteger(threadId)) {\n throw new Error(\"Telegram thread target must be a safe positive integer.\");\n }\n return threadId;\n}\n\nexport const TELEGRAM_OPENCLAW_CRABLINE_PROVIDER_BRIDGE = createOpenClawCrablineProviderBridge({\n provider: \"telegram\",\n createAdapter(telegram) {\n return {\n async probe(signal) {\n const response = await fetch(\n `${telegram.endpoints.apiRoot}/bot${telegram.botToken}/getMe`,\n signal ? { signal } : {},\n );\n if (!response.ok) {\n throw new Error(`Crabline Telegram getMe probe failed with HTTP ${response.status}.`);\n }\n const payload: unknown = await response.json();\n if (!isRecord(payload) || payload.ok !== true) {\n const errorCode = readString(isRecord(payload) ? payload.error_code : undefined);\n const description = readNonBlankString(\n isRecord(payload) ? payload.description : undefined,\n );\n const detail = description ?? (errorCode ? `error ${errorCode}` : \"invalid response\");\n throw new Error(`Crabline Telegram getMe probe failed: ${detail}.`);\n }\n const result = payload.result;\n if (\n !isRecord(result) ||\n typeof result.id !== \"number\" ||\n !Number.isSafeInteger(result.id) ||\n result.id <= 0 ||\n result.is_bot !== true ||\n !readNonBlankString(result.first_name) ||\n (result.username !== undefined &&\n (typeof result.username !== \"string\" ||\n !TELEGRAM_USERNAME_RE.test(`@${result.username}`)))\n ) {\n throw new Error(\"Crabline Telegram getMe probe failed: invalid response.\");\n }\n return payload;\n },\n createBinding() {\n return {\n accountId: DEFAULT_ACCOUNT_ID,\n channel: \"telegram\",\n createChannelDriverSmokeEnv: (env) => ({\n ...env,\n TELEGRAM_BOT_TOKEN: telegram.botToken,\n }),\n createGatewayConfig: (openclawConfig = {}) => {\n const channels = isRecord(openclawConfig.channels) ? openclawConfig.channels : {};\n const telegramConfig = isRecord(channels.telegram) ? channels.telegram : {};\n const groups = isRecord(telegramConfig.groups) ? telegramConfig.groups : {};\n const defaultGroup = isRecord(groups[\"*\"]) ? groups[\"*\"] : {};\n const messages = isRecord(openclawConfig.messages) ? openclawConfig.messages : {};\n const groupChat = isRecord(messages.groupChat) ? messages.groupChat : {};\n\n return {\n ...openclawConfig,\n channels: {\n ...channels,\n telegram: {\n ...telegramConfig,\n enabled: true,\n botToken: telegram.botToken,\n apiRoot: telegram.endpoints.apiRoot,\n dmPolicy: \"open\",\n groupPolicy: \"open\",\n allowFrom: [\"*\"],\n groupAllowFrom: [\"*\"],\n groups: {\n ...groups,\n \"*\": {\n ...defaultGroup,\n requireMention: false,\n },\n },\n },\n },\n messages: {\n ...messages,\n groupChat: {\n ...groupChat,\n mentionPatterns: [\"\\\\b@?openclaw\\\\b\"],\n visibleReplies: \"automatic\",\n },\n },\n };\n },\n requiredPluginIds: [\"telegram\"],\n };\n },\n createAgentDelivery(parsed) {\n const kind =\n parsed.native &&\n (/^-\\d+$/u.test(parsed.id.trim()) || TELEGRAM_USERNAME_RE.test(parsed.id.trim()))\n ? \"group\"\n : parsed.kind;\n const chatId = normalizeTelegramChatId(kind, parsed.id);\n const threadId = parseTelegramThreadTargetId(parsed.threadId);\n const to = telegramTargetKey(chatId, threadId);\n return {\n channel: \"telegram\",\n to,\n replyChannel: \"telegram\",\n replyTo: to,\n };\n },\n createInbound(input) {\n const kind = input.conversation.kind === \"direct\" ? \"direct\" : \"group\";\n const chatId = normalizeTelegramChatId(kind, input.conversation.id);\n const threadId = parseTelegramThreadTargetId(input.threadId);\n return {\n ...createAdminInboundRequest(telegram),\n providerBody: {\n chatId,\n fromId: Number(normalizeTelegramChatId(\"direct\", input.senderId)),\n fromName: input.senderName ?? input.senderId,\n ...(threadId !== undefined ? { messageThreadId: threadId } : {}),\n ...(input.nativeCommand\n ? {\n entities: [telegramBotCommandEntity(input.text, input.nativeCommand.name)],\n }\n : {}),\n text: input.text,\n },\n providerTargetKey: telegramTargetKey(chatId, threadId),\n qaTarget: qaTargetForInbound(input),\n stateConversation: {\n id: chatId,\n kind: kind === \"group\" ? \"group\" : \"direct\",\n },\n ...(threadId !== undefined ? { threadId: String(threadId) } : {}),\n };\n },\n createOutboundFromRecorderEvent({ event, targetByProviderTarget }) {\n if (!isRecord(event) || event.type !== \"api\" || typeof event.path !== \"string\") {\n return null;\n }\n const method = TELEGRAM_OUTBOUND_METHOD_RE.exec(event.path)?.[1]?.toLowerCase();\n if (!method || !isRecord(event.body)) {\n return null;\n }\n const chatId = canonicalTelegramRecorderChatId(event.body.chat_id);\n const text =\n method === \"sendmessage\"\n ? readNonBlankString(event.body.text)\n : readNonBlankString(event.body.caption);\n if (!chatId || !text) {\n return null;\n }\n let threadId: number | undefined;\n try {\n threadId = parseTelegramThreadTargetId(event.body.message_thread_id);\n } catch {\n return null;\n }\n const providerTargetKey = telegramTargetKey(chatId, threadId);\n return {\n accountId: DEFAULT_ACCOUNT_ID,\n senderId: \"openclaw\",\n senderName: \"OpenClaw QA\",\n text,\n to:\n targetByProviderTarget.get(providerTargetKey) ??\n (threadId === undefined ? chatId : providerTargetKey),\n };\n },\n };\n },\n});\n"]}
|
|
1
|
+
{"version":3,"file":"telegram.js","sourceRoot":"","sources":["../../../../src/openclaw/bridges/telegram.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 {\n canonicalizeTelegramUsername,\n TELEGRAM_BOT_USERNAME_PATTERN,\n TELEGRAM_CHAT_USERNAME_PATTERN,\n TELEGRAM_NATIVE_CHAT_ID_MAX,\n telegramUsernameChatId,\n} from \"../../servers/telegram-identity.js\";\nimport { throwProbeHttpError } from \"./probe-response.js\";\n\nconst TELEGRAM_SYMBOLIC_ID_BASE = TELEGRAM_NATIVE_CHAT_ID_MAX + 1n;\nconst TELEGRAM_SYMBOLIC_ID_RANGE = 1n << 50n;\nconst TELEGRAM_OUTBOUND_METHOD_RE =\n /\\/(sendAnimation|sendAudio|sendDocument|sendMessage|sendPhoto|sendVideo)$/iu;\nfunction normalizeTelegramChatId(\n kind: \"direct\" | \"group\",\n id: string,\n options: { preserveGroupUsername: boolean },\n): string {\n const value = id.trim();\n if (!value) {\n throw new Error(\"Telegram target is required.\");\n }\n if (/^-?\\d+$/u.test(value)) {\n const numericId = BigInt(value);\n if (numericId === 0n || (kind === \"direct\" ? numericId < 0n : numericId > 0n)) {\n throw new Error(\"Telegram numeric target sign does not match the declared target kind.\");\n }\n if (\n numericId < BigInt(Number.MIN_SAFE_INTEGER) ||\n numericId > BigInt(Number.MAX_SAFE_INTEGER)\n ) {\n throw new Error(\"Telegram numeric target must be a safe integer.\");\n }\n if (numericId < -TELEGRAM_NATIVE_CHAT_ID_MAX || numericId > TELEGRAM_NATIVE_CHAT_ID_MAX) {\n throw new Error(\"Telegram native numeric targets must fit within 52 significant bits.\");\n }\n return numericId.toString();\n }\n if (value.startsWith(\"@\")) {\n const username = canonicalizeTelegramUsername(value);\n if (!username) {\n throw new Error(\"Telegram usernames must contain 4-32 letters, digits, or underscores.\");\n }\n if (kind === \"group\" && options.preserveGroupUsername) {\n return username;\n }\n if (kind === \"group\") {\n return String(telegramUsernameChatId(username));\n }\n return syntheticTelegramChatId(kind, username);\n }\n return syntheticTelegramChatId(kind, value);\n}\n\nfunction syntheticTelegramChatId(kind: \"direct\" | \"group\", value: string): string {\n const hash = createHash(\"sha256\").update(`${kind}:${value}`).digest().readBigUInt64BE();\n if (kind === \"group\") {\n return String(-(TELEGRAM_SYMBOLIC_ID_BASE + (hash % TELEGRAM_SYMBOLIC_ID_RANGE)));\n }\n return String(TELEGRAM_SYMBOLIC_ID_BASE + (hash % TELEGRAM_SYMBOLIC_ID_RANGE));\n}\n\nfunction telegramTargetKey(chatId: string, threadId?: number) {\n return threadId === undefined ? chatId : `${chatId}:topic:${threadId}`;\n}\n\nfunction canonicalTelegramRecorderChatId(value: unknown): string | undefined {\n const chatId = readString(value);\n if (!chatId) {\n return undefined;\n }\n if (/^-?\\d+$/u.test(chatId)) {\n const numericId = BigInt(chatId);\n if (\n numericId === 0n ||\n numericId < BigInt(Number.MIN_SAFE_INTEGER) ||\n numericId > BigInt(Number.MAX_SAFE_INTEGER)\n ) {\n return undefined;\n }\n return numericId.toString();\n }\n const usernameChatId = telegramUsernameChatId(chatId);\n return usernameChatId === undefined ? undefined : String(usernameChatId);\n}\n\nfunction telegramBotCommandEntity(text: string, commandName: string) {\n if (!/^[a-z0-9_]{1,32}$/u.test(commandName)) {\n throw new Error(\n \"Telegram native command names must contain 1-32 lowercase letters, digits, or underscores.\",\n );\n }\n const commandPrefix = `/${commandName}`;\n const token = text.match(/^\\S+/u)?.[0];\n if (\n !token ||\n (token.toLowerCase() !== commandPrefix &&\n !new RegExp(`^/${commandName}@[A-Za-z][A-Za-z0-9_]{4,31}$`, \"iu\").test(token))\n ) {\n throw new Error(`Telegram native command text must start with ${commandPrefix}.`);\n }\n return {\n length: token.length,\n offset: 0,\n type: \"bot_command\",\n } as const;\n}\n\nfunction parseTelegramThreadTargetId(value: unknown): number | undefined {\n if (value === undefined) {\n return undefined;\n }\n const trimmed = readString(value);\n if (!trimmed || !/^[1-9]\\d*$/u.test(trimmed)) {\n throw new Error(\"Telegram thread target must be a safe positive integer.\");\n }\n const threadId = Number(trimmed);\n if (!Number.isSafeInteger(threadId)) {\n throw new Error(\"Telegram thread target must be a safe positive integer.\");\n }\n return threadId;\n}\n\nexport const TELEGRAM_OPENCLAW_CRABLINE_PROVIDER_BRIDGE = createOpenClawCrablineProviderBridge({\n provider: \"telegram\",\n createAdapter(telegram) {\n return {\n async probe(signal) {\n const configuredBotId = /^([1-9]\\d*):/u.exec(telegram.botToken)?.[1];\n const response = await fetch(\n `${telegram.endpoints.apiRoot}/bot${telegram.botToken}/getMe`,\n signal ? { signal } : {},\n );\n if (!response.ok) {\n await throwProbeHttpError(\n response,\n `Crabline Telegram getMe probe failed with HTTP ${response.status}.`,\n );\n }\n const payload: unknown = await response.json();\n if (!isRecord(payload) || payload.ok !== true) {\n const errorCode = readString(isRecord(payload) ? payload.error_code : undefined);\n const description = readNonBlankString(\n isRecord(payload) ? payload.description : undefined,\n );\n const detail = description ?? (errorCode ? `error ${errorCode}` : \"invalid response\");\n throw new Error(`Crabline Telegram getMe probe failed: ${detail}.`);\n }\n const result = payload.result;\n if (\n !isRecord(result) ||\n typeof result.id !== \"number\" ||\n !Number.isSafeInteger(result.id) ||\n result.id <= 0 ||\n configuredBotId !== String(result.id) ||\n result.is_bot !== true ||\n !readNonBlankString(result.first_name) ||\n (result.username !== undefined &&\n (typeof result.username !== \"string\" ||\n !TELEGRAM_BOT_USERNAME_PATTERN.test(`@${result.username}`)))\n ) {\n throw new Error(\"Crabline Telegram getMe probe failed: invalid response.\");\n }\n return payload;\n },\n createBinding() {\n return {\n accountId: DEFAULT_ACCOUNT_ID,\n channel: \"telegram\",\n createProviderReadinessEnv: (env) => ({\n ...env,\n TELEGRAM_BOT_TOKEN: telegram.botToken,\n }),\n createGatewayConfig: (openclawConfig = {}) => {\n const channels = isRecord(openclawConfig.channels) ? openclawConfig.channels : {};\n const telegramConfig = isRecord(channels.telegram) ? channels.telegram : {};\n const groups = isRecord(telegramConfig.groups) ? telegramConfig.groups : {};\n const defaultGroup = isRecord(groups[\"*\"]) ? groups[\"*\"] : {};\n const messages = isRecord(openclawConfig.messages) ? openclawConfig.messages : {};\n const groupChat = isRecord(messages.groupChat) ? messages.groupChat : {};\n\n return {\n ...openclawConfig,\n channels: {\n ...channels,\n telegram: {\n ...telegramConfig,\n enabled: true,\n botToken: telegram.botToken,\n apiRoot: telegram.endpoints.apiRoot,\n dmPolicy: \"open\",\n groupPolicy: \"open\",\n allowFrom: [\"*\"],\n groupAllowFrom: [\"*\"],\n groups: {\n ...groups,\n \"*\": {\n ...defaultGroup,\n requireMention: false,\n },\n },\n },\n },\n messages: {\n ...messages,\n groupChat: {\n ...groupChat,\n mentionPatterns: [\"\\\\b@?openclaw\\\\b\"],\n visibleReplies: \"automatic\",\n },\n },\n };\n },\n requiredPluginIds: [\"telegram\"],\n };\n },\n createAgentDelivery(parsed) {\n const kind =\n parsed.native &&\n (/^-\\d+$/u.test(parsed.id.trim()) ||\n TELEGRAM_CHAT_USERNAME_PATTERN.test(parsed.id.trim()))\n ? \"group\"\n : parsed.kind;\n const chatId = normalizeTelegramChatId(kind, parsed.id, {\n preserveGroupUsername: true,\n });\n const threadId = parseTelegramThreadTargetId(parsed.threadId);\n const to = telegramTargetKey(chatId, threadId);\n return {\n channel: \"telegram\",\n to,\n replyChannel: \"telegram\",\n replyTo: to,\n };\n },\n createInbound(input) {\n const kind = input.conversation.kind === \"direct\" ? \"direct\" : \"group\";\n const chatId = normalizeTelegramChatId(kind, input.conversation.id, {\n preserveGroupUsername: false,\n });\n const senderId = normalizeTelegramChatId(\"direct\", input.senderId, {\n preserveGroupUsername: false,\n });\n if (kind === \"direct\" && chatId !== senderId) {\n throw new Error(\n \"Telegram direct conversation and sender must normalize to the same identity.\",\n );\n }\n const threadId = parseTelegramThreadTargetId(input.threadId);\n return {\n ...createAdminInboundRequest(telegram),\n providerBody: {\n chatId,\n fromId: Number(senderId),\n fromName: input.senderName ?? input.senderId,\n ...(threadId !== undefined ? { messageThreadId: threadId } : {}),\n ...(input.nativeCommand\n ? {\n entities: [telegramBotCommandEntity(input.text, input.nativeCommand.name)],\n }\n : {}),\n text: input.text,\n },\n providerTargetKey: telegramTargetKey(chatId, threadId),\n qaTarget: qaTargetForInbound(input),\n stateConversation: {\n id: chatId,\n kind: kind === \"group\" ? \"group\" : \"direct\",\n },\n ...(threadId !== undefined ? { threadId: String(threadId) } : {}),\n };\n },\n createOutboundFromRecorderEvent({ event, targetByProviderTarget }) {\n if (!isRecord(event) || event.type !== \"api\" || typeof event.path !== \"string\") {\n return null;\n }\n const method = TELEGRAM_OUTBOUND_METHOD_RE.exec(event.path)?.[1]?.toLowerCase();\n if (!method || !isRecord(event.body)) {\n return null;\n }\n const chatId = canonicalTelegramRecorderChatId(event.body.chat_id);\n const text =\n method === \"sendmessage\"\n ? readNonBlankString(event.body.text)\n : readNonBlankString(event.body.caption);\n if (!chatId || !text) {\n return null;\n }\n let threadId: number | undefined;\n try {\n threadId = parseTelegramThreadTargetId(event.body.message_thread_id);\n } catch {\n return null;\n }\n const providerTargetKey = telegramTargetKey(chatId, threadId);\n return {\n accountId: DEFAULT_ACCOUNT_ID,\n senderId: \"openclaw\",\n senderName: \"OpenClaw QA\",\n text,\n to:\n targetByProviderTarget.get(providerTargetKey) ??\n (threadId === undefined ? chatId : providerTargetKey),\n };\n },\n };\n },\n});\n"]}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { createAdminInboundRequest, createOpenClawCrablineProviderBridge, DEFAULT_ACCOUNT_ID, isRecord, qaTargetForInbound, readNonBlankString, readString, } from "../shared.js";
|
|
2
|
-
import { canonicalizeWhatsAppChatJid, canonicalizeWhatsAppUserCorrelationJid, canonicalizeWhatsAppUserJid, } from "../../servers/whatsapp-jid.js";
|
|
2
|
+
import { canonicalizeWhatsAppChatCorrelationJid, canonicalizeWhatsAppChatJid, canonicalizeWhatsAppUserCorrelationJid, canonicalizeWhatsAppUserJid, } from "../../servers/whatsapp-jid.js";
|
|
3
|
+
import { throwProbeHttpError } from "./probe-response.js";
|
|
3
4
|
function requireWhatsAppJid(value, label, userOnly = false) {
|
|
4
5
|
const canonical = userOnly
|
|
5
6
|
? canonicalizeWhatsAppUserJid(value)
|
|
@@ -37,7 +38,7 @@ export const WHATSAPP_OPENCLAW_CRABLINE_PROVIDER_BRIDGE = createOpenClawCrabline
|
|
|
37
38
|
...(signal ? { signal } : {}),
|
|
38
39
|
});
|
|
39
40
|
if (!response.ok) {
|
|
40
|
-
|
|
41
|
+
await throwProbeHttpError(response, `Crabline WhatsApp probe failed with HTTP ${response.status}.`);
|
|
41
42
|
}
|
|
42
43
|
const payload = await response.json();
|
|
43
44
|
if (!isRecord(payload) || readString(payload.id) !== whatsapp.phoneNumberId) {
|
|
@@ -49,7 +50,7 @@ export const WHATSAPP_OPENCLAW_CRABLINE_PROVIDER_BRIDGE = createOpenClawCrabline
|
|
|
49
50
|
return {
|
|
50
51
|
accountId: DEFAULT_ACCOUNT_ID,
|
|
51
52
|
channel: "whatsapp",
|
|
52
|
-
|
|
53
|
+
createProviderReadinessEnv: (env) => ({
|
|
53
54
|
...env,
|
|
54
55
|
CRABLINE_WHATSAPP_ADMIN_TOKEN: whatsapp.adminToken,
|
|
55
56
|
CRABLINE_WHATSAPP_RECORDER_PATH: whatsapp.recorderPath,
|
|
@@ -90,11 +91,12 @@ export const WHATSAPP_OPENCLAW_CRABLINE_PROVIDER_BRIDGE = createOpenClawCrabline
|
|
|
90
91
|
if (parsed.threadId !== undefined) {
|
|
91
92
|
throw new Error("WhatsApp does not support thread targets.");
|
|
92
93
|
}
|
|
93
|
-
const
|
|
94
|
-
requireWhatsAppTargetKind(parsed,
|
|
95
|
-
if (
|
|
94
|
+
const nativeTo = requireWhatsAppJid(parsed.id, "WhatsApp target");
|
|
95
|
+
requireWhatsAppTargetKind(parsed, nativeTo);
|
|
96
|
+
if (nativeTo.endsWith("@g.us")) {
|
|
96
97
|
throw new Error("WhatsApp Crabline WebSocket outbound supports direct targets only.");
|
|
97
98
|
}
|
|
99
|
+
const to = canonicalizeWhatsAppUserCorrelationJid(nativeTo);
|
|
98
100
|
return {
|
|
99
101
|
channel: "whatsapp",
|
|
100
102
|
to,
|
|
@@ -106,25 +108,31 @@ export const WHATSAPP_OPENCLAW_CRABLINE_PROVIDER_BRIDGE = createOpenClawCrabline
|
|
|
106
108
|
if (input.threadId !== undefined) {
|
|
107
109
|
throw new Error("WhatsApp does not support thread targets.");
|
|
108
110
|
}
|
|
109
|
-
const
|
|
110
|
-
requireWhatsAppConversationKind(input.conversation.kind,
|
|
111
|
-
const
|
|
111
|
+
const nativeChatJid = requireWhatsAppJid(input.conversation.id, "WhatsApp conversation");
|
|
112
|
+
requireWhatsAppConversationKind(input.conversation.kind, nativeChatJid);
|
|
113
|
+
const nativeSenderJid = requireWhatsAppJid(input.senderId, "WhatsApp sender", true);
|
|
114
|
+
const providerTargetKey = canonicalizeWhatsAppChatCorrelationJid(nativeChatJid);
|
|
115
|
+
if (input.conversation.kind === "direct" &&
|
|
116
|
+
canonicalizeWhatsAppUserCorrelationJid(nativeChatJid) !==
|
|
117
|
+
canonicalizeWhatsAppUserCorrelationJid(nativeSenderJid)) {
|
|
118
|
+
throw new Error("WhatsApp direct conversation and sender must identify the same recipient.");
|
|
119
|
+
}
|
|
112
120
|
return {
|
|
113
121
|
...createAdminInboundRequest(whatsapp),
|
|
114
122
|
providerBody: {
|
|
115
|
-
chatJid,
|
|
116
|
-
senderJid,
|
|
123
|
+
chatJid: nativeChatJid,
|
|
124
|
+
senderJid: nativeSenderJid,
|
|
117
125
|
...(input.senderName ? { pushName: input.senderName } : {}),
|
|
118
126
|
text: input.text,
|
|
119
127
|
},
|
|
120
|
-
providerTargetKey
|
|
128
|
+
providerTargetKey,
|
|
121
129
|
qaTarget: qaTargetForInbound({
|
|
122
130
|
...input,
|
|
123
|
-
conversation: { ...input.conversation, id:
|
|
131
|
+
conversation: { ...input.conversation, id: providerTargetKey },
|
|
124
132
|
}),
|
|
125
133
|
stateConversation: {
|
|
126
|
-
id:
|
|
127
|
-
kind:
|
|
134
|
+
id: nativeChatJid,
|
|
135
|
+
kind: nativeChatJid.endsWith("@g.us") ? "group" : "direct",
|
|
128
136
|
},
|
|
129
137
|
};
|
|
130
138
|
},
|
|
@@ -141,7 +149,15 @@ export const WHATSAPP_OPENCLAW_CRABLINE_PROVIDER_BRIDGE = createOpenClawCrabline
|
|
|
141
149
|
const baileysKey = isRecord(event.body.key) ? event.body.key : undefined;
|
|
142
150
|
const baileysMessage = isRecord(event.body.message) ? event.body.message : undefined;
|
|
143
151
|
const isBaileysSend = event.method === "WEBSOCKET" && event.path === "/ws/chat";
|
|
144
|
-
|
|
152
|
+
const messagingProduct = readString(event.body.messaging_product);
|
|
153
|
+
const messageType = readString(event.body.type);
|
|
154
|
+
const isCloudTextSend = event.method === "POST" &&
|
|
155
|
+
event.path === messagesPath &&
|
|
156
|
+
(!("messaging_product" in event.body) || messagingProduct === "whatsapp") &&
|
|
157
|
+
(!("type" in event.body) || messageType === "text") &&
|
|
158
|
+
!("status" in event.body) &&
|
|
159
|
+
!("message_id" in event.body);
|
|
160
|
+
if (!isBaileysSend && !isCloudTextSend) {
|
|
145
161
|
return null;
|
|
146
162
|
}
|
|
147
163
|
const to = isBaileysSend ? readString(baileysKey?.remoteJid) : readString(event.body.to);
|
|
@@ -155,7 +171,7 @@ export const WHATSAPP_OPENCLAW_CRABLINE_PROVIDER_BRIDGE = createOpenClawCrabline
|
|
|
155
171
|
return null;
|
|
156
172
|
}
|
|
157
173
|
const providerTarget = isBaileysSend
|
|
158
|
-
?
|
|
174
|
+
? canonicalizeWhatsAppChatCorrelationJid(to)
|
|
159
175
|
: (canonicalizeWhatsAppChatJid(to) ??
|
|
160
176
|
(/^\d{7,15}$/u.test(to) ? `${to}@s.whatsapp.net` : to));
|
|
161
177
|
if (!providerTarget) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"whatsapp.js","sourceRoot":"","sources":["../../../../src/openclaw/bridges/whatsapp.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 canonicalizeWhatsAppChatJid,\n canonicalizeWhatsAppUserCorrelationJid,\n canonicalizeWhatsAppUserJid,\n} from \"../../servers/whatsapp-jid.js\";\n\nfunction requireWhatsAppJid(value: string, label: string, userOnly = false): string {\n const canonical = userOnly\n ? canonicalizeWhatsAppUserJid(value)\n : canonicalizeWhatsAppChatJid(value);\n if (!canonical) {\n throw new Error(`${label} must be a native WhatsApp JID.`);\n }\n return canonical;\n}\n\nfunction requireWhatsAppTargetKind(\n parsed: { kind: \"direct\" | \"group\"; native: boolean },\n targetId: string,\n): void {\n if (parsed.native) {\n return;\n }\n const nativeKind = targetId.endsWith(\"@g.us\") ? \"group\" : \"direct\";\n if (parsed.kind !== nativeKind) {\n throw new Error(\"WhatsApp target kind does not match the native JID.\");\n }\n}\n\nfunction requireWhatsAppConversationKind(kind: \"direct\" | \"group\", targetId: string): void {\n const nativeKind = targetId.endsWith(\"@g.us\") ? \"group\" : \"direct\";\n if (kind !== nativeKind) {\n throw new Error(\"WhatsApp inbound conversation kind does not match the native JID.\");\n }\n}\n\nexport const WHATSAPP_OPENCLAW_CRABLINE_PROVIDER_BRIDGE = createOpenClawCrablineProviderBridge({\n provider: \"whatsapp\",\n createAdapter(whatsapp) {\n const messagesPath = new URL(whatsapp.endpoints.messagesUrl).pathname;\n return {\n async probe(signal) {\n const response = await fetch(whatsapp.endpoints.phoneNumberUrl, {\n headers: {\n authorization: `Bearer ${whatsapp.accessToken}`,\n },\n ...(signal ? { signal } : {}),\n });\n if (!response.ok) {\n throw new Error(`Crabline WhatsApp probe failed with HTTP ${response.status}.`);\n }\n const payload: unknown = await response.json();\n if (!isRecord(payload) || readString(payload.id) !== whatsapp.phoneNumberId) {\n throw new Error(\"Crabline WhatsApp probe returned an unexpected phone number.\");\n }\n return payload;\n },\n createBinding() {\n return {\n accountId: DEFAULT_ACCOUNT_ID,\n channel: \"whatsapp\",\n createChannelDriverSmokeEnv: (env) => ({\n ...env,\n CRABLINE_WHATSAPP_ADMIN_TOKEN: whatsapp.adminToken,\n CRABLINE_WHATSAPP_RECORDER_PATH: whatsapp.recorderPath,\n CRABLINE_WHATSAPP_SELF_JID: whatsapp.selfJid,\n OPENCLAW_WHATSAPP_WEB_SOCKET_URL: whatsapp.endpoints.baileysWebSocketUrl,\n }),\n createGatewayConfig: (openclawConfig = {}) => {\n const channels = isRecord(openclawConfig.channels) ? openclawConfig.channels : {};\n const whatsappConfig = isRecord(channels.whatsapp) ? channels.whatsapp : {};\n const groups = isRecord(whatsappConfig.groups) ? whatsappConfig.groups : {};\n const defaultGroup = isRecord(groups[\"*\"]) ? groups[\"*\"] : {};\n\n return {\n ...openclawConfig,\n channels: {\n ...channels,\n whatsapp: {\n ...whatsappConfig,\n enabled: true,\n dmPolicy: \"open\",\n groupPolicy: \"open\",\n allowFrom: [\"*\"],\n groupAllowFrom: [\"*\"],\n groups: {\n ...groups,\n \"*\": {\n ...defaultGroup,\n requireMention: false,\n },\n },\n },\n },\n };\n },\n requiredPluginIds: [\"whatsapp\"],\n };\n },\n createAgentDelivery(parsed) {\n if (parsed.threadId !== undefined) {\n throw new Error(\"WhatsApp does not support thread targets.\");\n }\n const to = requireWhatsAppJid(parsed.id, \"WhatsApp target\");\n requireWhatsAppTargetKind(parsed, to);\n if (to.endsWith(\"@g.us\")) {\n throw new Error(\"WhatsApp Crabline WebSocket outbound supports direct targets only.\");\n }\n return {\n channel: \"whatsapp\",\n to,\n replyChannel: \"whatsapp\",\n replyTo: to,\n };\n },\n createInbound(input) {\n if (input.threadId !== undefined) {\n throw new Error(\"WhatsApp does not support thread targets.\");\n }\n const chatJid = requireWhatsAppJid(input.conversation.id, \"WhatsApp conversation\");\n requireWhatsAppConversationKind(input.conversation.kind, chatJid);\n const senderJid = requireWhatsAppJid(input.senderId, \"WhatsApp sender\", true);\n return {\n ...createAdminInboundRequest(whatsapp),\n providerBody: {\n chatJid,\n senderJid,\n ...(input.senderName ? { pushName: input.senderName } : {}),\n text: input.text,\n },\n providerTargetKey: chatJid,\n qaTarget: qaTargetForInbound({\n ...input,\n conversation: { ...input.conversation, id: chatJid },\n }),\n stateConversation: {\n id: chatJid,\n kind: chatJid.endsWith(\"@g.us\") ? \"group\" : \"direct\",\n },\n };\n },\n createOutboundFromRecorderEvent({ event, targetByProviderTarget }) {\n if (\n !isRecord(event) ||\n event.type !== \"api\" ||\n event.accepted !== true ||\n typeof event.path !== \"string\"\n ) {\n return null;\n }\n if (!isRecord(event.body)) {\n return null;\n }\n const baileysKey = isRecord(event.body.key) ? event.body.key : undefined;\n const baileysMessage = isRecord(event.body.message) ? event.body.message : undefined;\n const isBaileysSend = event.method === \"WEBSOCKET\" && event.path === \"/ws/chat\";\n if (!isBaileysSend && event.path !== messagesPath) {\n return null;\n }\n const to = isBaileysSend ? readString(baileysKey?.remoteJid) : readString(event.body.to);\n const textPayload = event.body.text;\n const text = isBaileysSend\n ? readNonBlankString(baileysMessage?.conversation)\n : isRecord(textPayload)\n ? readNonBlankString(textPayload.body)\n : undefined;\n if (!to || !text) {\n return null;\n }\n const providerTarget = isBaileysSend\n ? canonicalizeWhatsAppUserCorrelationJid(to)\n : (canonicalizeWhatsAppChatJid(to) ??\n (/^\\d{7,15}$/u.test(to) ? `${to}@s.whatsapp.net` : to));\n if (!providerTarget) {\n return null;\n }\n return {\n accountId: DEFAULT_ACCOUNT_ID,\n senderId: \"openclaw\",\n senderName: \"OpenClaw QA\",\n text,\n to: targetByProviderTarget.get(providerTarget) ?? providerTarget,\n };\n },\n };\n },\n});\n"]}
|
|
1
|
+
{"version":3,"file":"whatsapp.js","sourceRoot":"","sources":["../../../../src/openclaw/bridges/whatsapp.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 canonicalizeWhatsAppChatCorrelationJid,\n canonicalizeWhatsAppChatJid,\n canonicalizeWhatsAppUserCorrelationJid,\n canonicalizeWhatsAppUserJid,\n} from \"../../servers/whatsapp-jid.js\";\nimport { throwProbeHttpError } from \"./probe-response.js\";\n\nfunction requireWhatsAppJid(value: string, label: string, userOnly = false): string {\n const canonical = userOnly\n ? canonicalizeWhatsAppUserJid(value)\n : canonicalizeWhatsAppChatJid(value);\n if (!canonical) {\n throw new Error(`${label} must be a native WhatsApp JID.`);\n }\n return canonical;\n}\n\nfunction requireWhatsAppTargetKind(\n parsed: { kind: \"direct\" | \"group\"; native: boolean },\n targetId: string,\n): void {\n if (parsed.native) {\n return;\n }\n const nativeKind = targetId.endsWith(\"@g.us\") ? \"group\" : \"direct\";\n if (parsed.kind !== nativeKind) {\n throw new Error(\"WhatsApp target kind does not match the native JID.\");\n }\n}\n\nfunction requireWhatsAppConversationKind(kind: \"direct\" | \"group\", targetId: string): void {\n const nativeKind = targetId.endsWith(\"@g.us\") ? \"group\" : \"direct\";\n if (kind !== nativeKind) {\n throw new Error(\"WhatsApp inbound conversation kind does not match the native JID.\");\n }\n}\n\nexport const WHATSAPP_OPENCLAW_CRABLINE_PROVIDER_BRIDGE = createOpenClawCrablineProviderBridge({\n provider: \"whatsapp\",\n createAdapter(whatsapp) {\n const messagesPath = new URL(whatsapp.endpoints.messagesUrl).pathname;\n return {\n async probe(signal) {\n const response = await fetch(whatsapp.endpoints.phoneNumberUrl, {\n headers: {\n authorization: `Bearer ${whatsapp.accessToken}`,\n },\n ...(signal ? { signal } : {}),\n });\n if (!response.ok) {\n await throwProbeHttpError(\n response,\n `Crabline WhatsApp probe failed with HTTP ${response.status}.`,\n );\n }\n const payload: unknown = await response.json();\n if (!isRecord(payload) || readString(payload.id) !== whatsapp.phoneNumberId) {\n throw new Error(\"Crabline WhatsApp probe returned an unexpected phone number.\");\n }\n return payload;\n },\n createBinding() {\n return {\n accountId: DEFAULT_ACCOUNT_ID,\n channel: \"whatsapp\",\n createProviderReadinessEnv: (env) => ({\n ...env,\n CRABLINE_WHATSAPP_ADMIN_TOKEN: whatsapp.adminToken,\n CRABLINE_WHATSAPP_RECORDER_PATH: whatsapp.recorderPath,\n CRABLINE_WHATSAPP_SELF_JID: whatsapp.selfJid,\n OPENCLAW_WHATSAPP_WEB_SOCKET_URL: whatsapp.endpoints.baileysWebSocketUrl,\n }),\n createGatewayConfig: (openclawConfig = {}) => {\n const channels = isRecord(openclawConfig.channels) ? openclawConfig.channels : {};\n const whatsappConfig = isRecord(channels.whatsapp) ? channels.whatsapp : {};\n const groups = isRecord(whatsappConfig.groups) ? whatsappConfig.groups : {};\n const defaultGroup = isRecord(groups[\"*\"]) ? groups[\"*\"] : {};\n\n return {\n ...openclawConfig,\n channels: {\n ...channels,\n whatsapp: {\n ...whatsappConfig,\n enabled: true,\n dmPolicy: \"open\",\n groupPolicy: \"open\",\n allowFrom: [\"*\"],\n groupAllowFrom: [\"*\"],\n groups: {\n ...groups,\n \"*\": {\n ...defaultGroup,\n requireMention: false,\n },\n },\n },\n },\n };\n },\n requiredPluginIds: [\"whatsapp\"],\n };\n },\n createAgentDelivery(parsed) {\n if (parsed.threadId !== undefined) {\n throw new Error(\"WhatsApp does not support thread targets.\");\n }\n const nativeTo = requireWhatsAppJid(parsed.id, \"WhatsApp target\");\n requireWhatsAppTargetKind(parsed, nativeTo);\n if (nativeTo.endsWith(\"@g.us\")) {\n throw new Error(\"WhatsApp Crabline WebSocket outbound supports direct targets only.\");\n }\n const to = canonicalizeWhatsAppUserCorrelationJid(nativeTo)!;\n return {\n channel: \"whatsapp\",\n to,\n replyChannel: \"whatsapp\",\n replyTo: to,\n };\n },\n createInbound(input) {\n if (input.threadId !== undefined) {\n throw new Error(\"WhatsApp does not support thread targets.\");\n }\n const nativeChatJid = requireWhatsAppJid(input.conversation.id, \"WhatsApp conversation\");\n requireWhatsAppConversationKind(input.conversation.kind, nativeChatJid);\n const nativeSenderJid = requireWhatsAppJid(input.senderId, \"WhatsApp sender\", true);\n const providerTargetKey = canonicalizeWhatsAppChatCorrelationJid(nativeChatJid)!;\n if (\n input.conversation.kind === \"direct\" &&\n canonicalizeWhatsAppUserCorrelationJid(nativeChatJid) !==\n canonicalizeWhatsAppUserCorrelationJid(nativeSenderJid)\n ) {\n throw new Error(\n \"WhatsApp direct conversation and sender must identify the same recipient.\",\n );\n }\n return {\n ...createAdminInboundRequest(whatsapp),\n providerBody: {\n chatJid: nativeChatJid,\n senderJid: nativeSenderJid,\n ...(input.senderName ? { pushName: input.senderName } : {}),\n text: input.text,\n },\n providerTargetKey,\n qaTarget: qaTargetForInbound({\n ...input,\n conversation: { ...input.conversation, id: providerTargetKey },\n }),\n stateConversation: {\n id: nativeChatJid,\n kind: nativeChatJid.endsWith(\"@g.us\") ? \"group\" : \"direct\",\n },\n };\n },\n createOutboundFromRecorderEvent({ event, targetByProviderTarget }) {\n if (\n !isRecord(event) ||\n event.type !== \"api\" ||\n event.accepted !== true ||\n typeof event.path !== \"string\"\n ) {\n return null;\n }\n if (!isRecord(event.body)) {\n return null;\n }\n const baileysKey = isRecord(event.body.key) ? event.body.key : undefined;\n const baileysMessage = isRecord(event.body.message) ? event.body.message : undefined;\n const isBaileysSend = event.method === \"WEBSOCKET\" && event.path === \"/ws/chat\";\n const messagingProduct = readString(event.body.messaging_product);\n const messageType = readString(event.body.type);\n const isCloudTextSend =\n event.method === \"POST\" &&\n event.path === messagesPath &&\n (!(\"messaging_product\" in event.body) || messagingProduct === \"whatsapp\") &&\n (!(\"type\" in event.body) || messageType === \"text\") &&\n !(\"status\" in event.body) &&\n !(\"message_id\" in event.body);\n if (!isBaileysSend && !isCloudTextSend) {\n return null;\n }\n const to = isBaileysSend ? readString(baileysKey?.remoteJid) : readString(event.body.to);\n const textPayload = event.body.text;\n const text = isBaileysSend\n ? readNonBlankString(baileysMessage?.conversation)\n : isRecord(textPayload)\n ? readNonBlankString(textPayload.body)\n : undefined;\n if (!to || !text) {\n return null;\n }\n const providerTarget = isBaileysSend\n ? canonicalizeWhatsAppChatCorrelationJid(to)\n : (canonicalizeWhatsAppChatJid(to) ??\n (/^\\d{7,15}$/u.test(to) ? `${to}@s.whatsapp.net` : to));\n if (!providerTarget) {\n return null;\n }\n return {\n accountId: DEFAULT_ACCOUNT_ID,\n senderId: \"openclaw\",\n senderName: \"OpenClaw QA\",\n text,\n to: targetByProviderTarget.get(providerTarget) ?? providerTarget,\n };\n },\n };\n },\n});\n"]}
|
|
@@ -1,9 +1,14 @@
|
|
|
1
|
+
import { ZALO_ID_RULE, ZALO_UNSUPPORTED_THREAD_TARGET_ERROR, } from "../../providers/target-normalizers.js";
|
|
1
2
|
import { createAdminInboundRequest, createOpenClawCrablineProviderBridge, DEFAULT_ACCOUNT_ID, isRecord, qaTargetForInbound, readNonBlankString, readString, } from "../shared.js";
|
|
3
|
+
import { throwProbeHttpError } from "./probe-response.js";
|
|
2
4
|
function nativeId(value) {
|
|
3
5
|
const id = value.trim();
|
|
4
6
|
if (!id) {
|
|
5
7
|
throw new Error("Zalo target is required.");
|
|
6
8
|
}
|
|
9
|
+
if (!ZALO_ID_RULE.pattern.test(id)) {
|
|
10
|
+
throw new Error("Zalo target must be a native Zalo string id without whitespace.");
|
|
11
|
+
}
|
|
7
12
|
return id;
|
|
8
13
|
}
|
|
9
14
|
export const ZALO_OPENCLAW_CRABLINE_PROVIDER_BRIDGE = createOpenClawCrablineProviderBridge({
|
|
@@ -16,7 +21,7 @@ export const ZALO_OPENCLAW_CRABLINE_PROVIDER_BRIDGE = createOpenClawCrablineProv
|
|
|
16
21
|
...(signal ? { signal } : {}),
|
|
17
22
|
});
|
|
18
23
|
if (!response.ok) {
|
|
19
|
-
|
|
24
|
+
await throwProbeHttpError(response, `Crabline Zalo getMe probe failed with HTTP ${response.status}.`);
|
|
20
25
|
}
|
|
21
26
|
const result = await response.json();
|
|
22
27
|
const bot = isRecord(result) && isRecord(result.result) ? result.result : undefined;
|
|
@@ -32,7 +37,7 @@ export const ZALO_OPENCLAW_CRABLINE_PROVIDER_BRIDGE = createOpenClawCrablineProv
|
|
|
32
37
|
return {
|
|
33
38
|
accountId: DEFAULT_ACCOUNT_ID,
|
|
34
39
|
channel: "zalo",
|
|
35
|
-
|
|
40
|
+
createProviderReadinessEnv: (env) => ({ ...env, ...zalo.env }),
|
|
36
41
|
createGatewayConfig: (openclawConfig = {}) => {
|
|
37
42
|
const channels = isRecord(openclawConfig.channels) ? openclawConfig.channels : {};
|
|
38
43
|
const zaloConfig = isRecord(channels.zalo) ? channels.zalo : {};
|
|
@@ -57,14 +62,14 @@ export const ZALO_OPENCLAW_CRABLINE_PROVIDER_BRIDGE = createOpenClawCrablineProv
|
|
|
57
62
|
},
|
|
58
63
|
createAgentDelivery(parsed) {
|
|
59
64
|
if (parsed.threadId) {
|
|
60
|
-
throw new Error(
|
|
65
|
+
throw new Error(ZALO_UNSUPPORTED_THREAD_TARGET_ERROR);
|
|
61
66
|
}
|
|
62
67
|
const to = nativeId(parsed.id);
|
|
63
68
|
return { channel: "zalo", replyChannel: "zalo", replyTo: to, to };
|
|
64
69
|
},
|
|
65
70
|
createInbound(input) {
|
|
66
71
|
if (input.threadId) {
|
|
67
|
-
throw new Error(
|
|
72
|
+
throw new Error(ZALO_UNSUPPORTED_THREAD_TARGET_ERROR);
|
|
68
73
|
}
|
|
69
74
|
const kind = input.conversation.kind === "direct" ? "direct" : "group";
|
|
70
75
|
const chatId = nativeId(input.conversation.id);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"zalo.js","sourceRoot":"","sources":["../../../../src/openclaw/bridges/zalo.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,yBAAyB,EACzB,oCAAoC,EACpC,kBAAkB,EAClB,QAAQ,EACR,kBAAkB,EAClB,kBAAkB,EAClB,UAAU,GACX,MAAM,cAAc,CAAC;
|
|
1
|
+
{"version":3,"file":"zalo.js","sourceRoot":"","sources":["../../../../src/openclaw/bridges/zalo.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n ZALO_ID_RULE,\n ZALO_UNSUPPORTED_THREAD_TARGET_ERROR,\n} from \"../../providers/target-normalizers.js\";\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\nfunction nativeId(value: string): string {\n const id = value.trim();\n if (!id) {\n throw new Error(\"Zalo target is required.\");\n }\n if (!ZALO_ID_RULE.pattern.test(id)) {\n throw new Error(\"Zalo target must be a native Zalo string id without whitespace.\");\n }\n return id;\n}\n\nexport const ZALO_OPENCLAW_CRABLINE_PROVIDER_BRIDGE = createOpenClawCrablineProviderBridge({\n provider: \"zalo\",\n createAdapter(zalo) {\n return {\n async probe(signal) {\n const response = await fetch(`${zalo.endpoints.apiRoot}/bot${zalo.botToken}/getMe`, {\n method: \"POST\",\n ...(signal ? { signal } : {}),\n });\n if (!response.ok) {\n await throwProbeHttpError(\n response,\n `Crabline Zalo getMe probe failed with HTTP ${response.status}.`,\n );\n }\n const result = await response.json();\n const bot = isRecord(result) && isRecord(result.result) ? result.result : undefined;\n if (!isRecord(result) || result.ok !== true || readNonBlankString(bot?.id) !== zalo.botId) {\n const detail =\n (isRecord(result) ? readNonBlankString(result.description) : undefined) ??\n (isRecord(result) ? readNonBlankString(result.error) : undefined) ??\n \"invalid response\";\n throw new Error(`Crabline Zalo getMe probe failed: ${detail}.`);\n }\n return result;\n },\n createBinding() {\n return {\n accountId: DEFAULT_ACCOUNT_ID,\n channel: \"zalo\",\n createProviderReadinessEnv: (env) => ({ ...env, ...zalo.env }),\n createGatewayConfig: (openclawConfig = {}) => {\n const channels = isRecord(openclawConfig.channels) ? openclawConfig.channels : {};\n const zaloConfig = isRecord(channels.zalo) ? channels.zalo : {};\n return {\n ...openclawConfig,\n channels: {\n ...channels,\n zalo: {\n ...zaloConfig,\n allowFrom: [\"*\"],\n botToken: zalo.botToken,\n dmPolicy: \"open\",\n enabled: true,\n groupAllowFrom: [\"*\"],\n groupPolicy: \"open\",\n },\n },\n };\n },\n requiredPluginIds: [\"zalo\"],\n };\n },\n createAgentDelivery(parsed) {\n if (parsed.threadId) {\n throw new Error(ZALO_UNSUPPORTED_THREAD_TARGET_ERROR);\n }\n const to = nativeId(parsed.id);\n return { channel: \"zalo\", replyChannel: \"zalo\", replyTo: to, to };\n },\n createInbound(input) {\n if (input.threadId) {\n throw new Error(ZALO_UNSUPPORTED_THREAD_TARGET_ERROR);\n }\n const kind = input.conversation.kind === \"direct\" ? \"direct\" : \"group\";\n const chatId = nativeId(input.conversation.id);\n return {\n ...createAdminInboundRequest(zalo),\n providerBody: {\n chatId,\n chatType: kind === \"direct\" ? \"PRIVATE\" : \"GROUP\",\n senderId: nativeId(input.senderId),\n ...(input.senderName ? { senderName: input.senderName } : {}),\n text: input.text,\n },\n providerTargetKey: chatId,\n qaTarget: qaTargetForInbound(input),\n stateConversation: { id: chatId, kind },\n };\n },\n createOutboundFromRecorderEvent({ event, targetByProviderTarget }) {\n if (\n !isRecord(event) ||\n event.type !== \"api\" ||\n (event.method !== \"GET\" && event.method !== \"POST\") ||\n !isRecord(event.body) ||\n (event.path !== \"/bot<redacted>/sendMessage\" && event.path !== \"/bot<redacted>/sendPhoto\")\n ) {\n return null;\n }\n const chatId = readString(event.body.chat_id);\n const text =\n event.path === \"/bot<redacted>/sendMessage\"\n ? readNonBlankString(event.body.text)\n : readNonBlankString(event.body.caption);\n if (!chatId || !text) {\n return null;\n }\n return {\n accountId: DEFAULT_ACCOUNT_ID,\n senderId: zalo.botId,\n senderName: \"OpenClaw QA\",\n text,\n to: targetByProviderTarget.get(chatId) ?? chatId,\n };\n },\n };\n },\n});\n"]}
|
|
@@ -3,6 +3,7 @@ import { isRecord, readNonBlankString } from "./shared.js";
|
|
|
3
3
|
const MATRIX_SEND_PATH_RE = /^\/_matrix\/client\/(?:v3|r0)\/rooms\/[^/]+\/send\/m\.room\.message\/[^/]+$/u;
|
|
4
4
|
const TELEGRAM_SEND_PATH_RE = /^\/bot<redacted>\/(?:sendAnimation|sendAudio|sendDocument|sendMessage|sendPhoto|sendVideo)$/iu;
|
|
5
5
|
const ZALO_SEND_PATH_RE = /^\/bot<redacted>\/(?:sendMessage|sendPhoto)$/u;
|
|
6
|
+
const DISCORD_SEND_PATH_RE = /^\/api\/v10\/channels\/\d{17,20}\/messages$/u;
|
|
6
7
|
export function isAcceptedOpenClawCrablineOutbound(params) {
|
|
7
8
|
if (!isRecord(params.event) || params.event.type !== "api" || params.event.accepted !== true) {
|
|
8
9
|
return false;
|
|
@@ -13,6 +14,8 @@ export function isAcceptedOpenClawCrablineOutbound(params) {
|
|
|
13
14
|
return false;
|
|
14
15
|
}
|
|
15
16
|
switch (params.manifest.provider) {
|
|
17
|
+
case "discord":
|
|
18
|
+
return method === "POST" && DISCORD_SEND_PATH_RE.test(requestPath);
|
|
16
19
|
case "mattermost":
|
|
17
20
|
return method === "POST" && requestPath === "/api/v4/posts";
|
|
18
21
|
case "matrix":
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"outbound-contract.js","sourceRoot":"","sources":["../../../src/openclaw/outbound-contract.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,sCAAsC,EAAE,MAAM,4BAA4B,CAAC;AACpF,OAAO,EAAE,QAAQ,EAAE,kBAAkB,EAAE,MAAM,aAAa,CAAC;AAE3D,MAAM,mBAAmB,GACvB,8EAA8E,CAAC;AACjF,MAAM,qBAAqB,GACzB,+FAA+F,CAAC;AAClG,MAAM,iBAAiB,GAAG,+CAA+C,CAAC;
|
|
1
|
+
{"version":3,"file":"outbound-contract.js","sourceRoot":"","sources":["../../../src/openclaw/outbound-contract.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,sCAAsC,EAAE,MAAM,4BAA4B,CAAC;AACpF,OAAO,EAAE,QAAQ,EAAE,kBAAkB,EAAE,MAAM,aAAa,CAAC;AAE3D,MAAM,mBAAmB,GACvB,8EAA8E,CAAC;AACjF,MAAM,qBAAqB,GACzB,+FAA+F,CAAC;AAClG,MAAM,iBAAiB,GAAG,+CAA+C,CAAC;AAC1E,MAAM,oBAAoB,GAAG,8CAA8C,CAAC;AAE5E,MAAM,UAAU,kCAAkC,CAAC,MAGlD;IACC,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,MAAM,CAAC,KAAK,CAAC,IAAI,KAAK,KAAK,IAAI,MAAM,CAAC,KAAK,CAAC,QAAQ,KAAK,IAAI,EAAE,CAAC;QAC7F,OAAO,KAAK,CAAC;IACf,CAAC;IACD,MAAM,MAAM,GAAG,kBAAkB,CAAC,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;IACvD,MAAM,WAAW,GAAG,kBAAkB,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;IAC1D,IAAI,CAAC,MAAM,IAAI,CAAC,WAAW,EAAE,CAAC;QAC5B,OAAO,KAAK,CAAC;IACf,CAAC;IAED,QAAQ,MAAM,CAAC,QAAQ,CAAC,QAAQ,EAAE,CAAC;QACjC,KAAK,SAAS;YACZ,OAAO,MAAM,KAAK,MAAM,IAAI,oBAAoB,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC;QACrE,KAAK,YAAY;YACf,OAAO,MAAM,KAAK,MAAM,IAAI,WAAW,KAAK,eAAe,CAAC;QAC9D,KAAK,QAAQ;YACX,OAAO,MAAM,KAAK,KAAK,IAAI,mBAAmB,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC;QACnE,KAAK,QAAQ;YACX,OAAO,MAAM,KAAK,MAAM,IAAI,WAAW,KAAK,aAAa,CAAC;QAC5D,KAAK,OAAO;YACV,OAAO,MAAM,KAAK,MAAM,IAAI,WAAW,KAAK,uBAAuB,CAAC;QACtE,KAAK,UAAU;YACb,OAAO,CAAC,MAAM,KAAK,KAAK,IAAI,MAAM,KAAK,MAAM,CAAC,IAAI,qBAAqB,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC;QAC5F,KAAK,UAAU,EAAE,CAAC;YAChB,MAAM,YAAY,GAAG,IAAI,GAAG,CAAC,MAAM,CAAC,QAAQ,CAAC,SAAS,CAAC,WAAW,CAAC,CAAC,QAAQ,CAAC;YAC7E,MAAM,IAAI,GAAG,QAAQ,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,SAAS,CAAC;YACzE,MAAM,GAAG,GAAG,QAAQ,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,SAAS,CAAC;YACvD,MAAM,qBAAqB,GAAG,sCAAsC,CAClE,kBAAkB,CAAC,GAAG,EAAE,SAAS,CAAC,IAAI,EAAE,CACzC,CAAC;YACF,OAAO,CACL,CAAC,MAAM,KAAK,MAAM,IAAI,WAAW,KAAK,YAAY,CAAC;gBACnD,CAAC,MAAM,KAAK,WAAW;oBACrB,WAAW,KAAK,UAAU;oBAC1B,qBAAqB,KAAK,SAAS,CAAC,CACvC,CAAC;QACJ,CAAC;QACD,KAAK,MAAM;YACT,OAAO,CAAC,MAAM,KAAK,KAAK,IAAI,MAAM,KAAK,MAAM,CAAC,IAAI,iBAAiB,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC;IAC1F,CAAC;AACH,CAAC","sourcesContent":["import type { CrablineServerManifest } from \"../servers/index.js\";\nimport { canonicalizeWhatsAppUserCorrelationJid } from \"../servers/whatsapp-jid.js\";\nimport { isRecord, readNonBlankString } from \"./shared.js\";\n\nconst MATRIX_SEND_PATH_RE =\n /^\\/_matrix\\/client\\/(?:v3|r0)\\/rooms\\/[^/]+\\/send\\/m\\.room\\.message\\/[^/]+$/u;\nconst TELEGRAM_SEND_PATH_RE =\n /^\\/bot<redacted>\\/(?:sendAnimation|sendAudio|sendDocument|sendMessage|sendPhoto|sendVideo)$/iu;\nconst ZALO_SEND_PATH_RE = /^\\/bot<redacted>\\/(?:sendMessage|sendPhoto)$/u;\nconst DISCORD_SEND_PATH_RE = /^\\/api\\/v10\\/channels\\/\\d{17,20}\\/messages$/u;\n\nexport function isAcceptedOpenClawCrablineOutbound(params: {\n event: unknown;\n manifest: CrablineServerManifest;\n}): boolean {\n if (!isRecord(params.event) || params.event.type !== \"api\" || params.event.accepted !== true) {\n return false;\n }\n const method = readNonBlankString(params.event.method);\n const requestPath = readNonBlankString(params.event.path);\n if (!method || !requestPath) {\n return false;\n }\n\n switch (params.manifest.provider) {\n case \"discord\":\n return method === \"POST\" && DISCORD_SEND_PATH_RE.test(requestPath);\n case \"mattermost\":\n return method === \"POST\" && requestPath === \"/api/v4/posts\";\n case \"matrix\":\n return method === \"PUT\" && MATRIX_SEND_PATH_RE.test(requestPath);\n case \"signal\":\n return method === \"POST\" && requestPath === \"/api/v1/rpc\";\n case \"slack\":\n return method === \"POST\" && requestPath === \"/api/chat.postMessage\";\n case \"telegram\":\n return (method === \"GET\" || method === \"POST\") && TELEGRAM_SEND_PATH_RE.test(requestPath);\n case \"whatsapp\": {\n const messagesPath = new URL(params.manifest.endpoints.messagesUrl).pathname;\n const body = isRecord(params.event.body) ? params.event.body : undefined;\n const key = isRecord(body?.key) ? body.key : undefined;\n const directWebSocketTarget = canonicalizeWhatsAppUserCorrelationJid(\n readNonBlankString(key?.remoteJid) ?? \"\",\n );\n return (\n (method === \"POST\" && requestPath === messagesPath) ||\n (method === \"WEBSOCKET\" &&\n requestPath === \"/ws/chat\" &&\n directWebSocketTarget !== undefined)\n );\n }\n case \"zalo\":\n return (method === \"GET\" || method === \"POST\") && ZALO_SEND_PATH_RE.test(requestPath);\n }\n}\n"]}
|