@openclaw/crabline 0.1.0 → 0.1.3
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 +68 -1
- package/dist/src/cli/program.js +62 -12
- package/dist/src/cli/program.js.map +1 -1
- package/dist/src/fake-servers/http.d.ts +30 -0
- package/dist/src/fake-servers/http.js +130 -0
- package/dist/src/fake-servers/http.js.map +1 -0
- package/dist/src/fake-servers/index.d.ts +21 -6
- package/dist/src/fake-servers/index.js +19 -5
- package/dist/src/fake-servers/index.js.map +1 -1
- package/dist/src/fake-servers/slack.d.ts +34 -0
- package/dist/src/fake-servers/slack.js +445 -0
- package/dist/src/fake-servers/slack.js.map +1 -0
- package/dist/src/fake-servers/telegram.js +3 -20
- package/dist/src/fake-servers/telegram.js.map +1 -1
- package/dist/src/fake-servers/whatsapp-socket-factory.d.ts +34 -0
- package/dist/src/fake-servers/whatsapp-socket-factory.js +225 -0
- package/dist/src/fake-servers/whatsapp-socket-factory.js.map +1 -0
- package/dist/src/fake-servers/whatsapp.d.ts +96 -0
- package/dist/src/fake-servers/whatsapp.js +474 -0
- package/dist/src/fake-servers/whatsapp.js.map +1 -0
- package/dist/src/index.d.ts +6 -0
- package/dist/src/index.js +3 -0
- package/dist/src/index.js.map +1 -1
- package/dist/src/openclaw/bridges/slack.d.ts +1 -0
- package/dist/src/openclaw/bridges/slack.js +150 -0
- package/dist/src/openclaw/bridges/slack.js.map +1 -0
- package/dist/src/openclaw/bridges/telegram.d.ts +1 -0
- package/dist/src/openclaw/bridges/telegram.js +137 -0
- package/dist/src/openclaw/bridges/telegram.js.map +1 -0
- package/dist/src/openclaw/bridges/whatsapp.d.ts +1 -0
- package/dist/src/openclaw/bridges/whatsapp.js +115 -0
- package/dist/src/openclaw/bridges/whatsapp.js.map +1 -0
- package/dist/src/openclaw/shared.d.ts +125 -0
- package/dist/src/openclaw/shared.js +78 -0
- package/dist/src/openclaw/shared.js.map +1 -0
- package/dist/src/openclaw.d.ts +3 -76
- package/dist/src/openclaw.js +31 -196
- package/dist/src/openclaw.js.map +1 -1
- package/dist/src/providers/builtin/native-local-mock.d.ts +2 -5
- package/dist/src/providers/builtin/native-local-mock.js.map +1 -1
- package/dist/src/providers/builtin/slack.js +1 -10
- package/dist/src/providers/builtin/slack.js.map +1 -1
- package/dist/src/providers/native-ids.d.ts +5 -0
- package/dist/src/providers/native-ids.js +2 -0
- package/dist/src/providers/native-ids.js.map +1 -0
- package/dist/src/providers/slack-ids.d.ts +6 -0
- package/dist/src/providers/slack-ids.js +24 -0
- package/dist/src/providers/slack-ids.js.map +1 -0
- package/docs/channel-setup.md +82 -1
- package/package.json +5 -1
|
@@ -0,0 +1,150 @@
|
|
|
1
|
+
import { createAdminInboundRequest, createOpenClawCrablineProviderBridge, DEFAULT_ACCOUNT_ID, isRecord, qaTargetForInbound, readString, } from "../shared.js";
|
|
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
|
+
function requireSlackSendTargetId(value, label) {
|
|
4
|
+
const trimmed = value.trim();
|
|
5
|
+
if (!SLACK_SEND_TARGET_ID_RULE.pattern.test(trimmed)) {
|
|
6
|
+
throw new Error(`${label} must be a native Slack conversation or user id.`);
|
|
7
|
+
}
|
|
8
|
+
return trimmed;
|
|
9
|
+
}
|
|
10
|
+
function requireSlackChannelId(value, label) {
|
|
11
|
+
const trimmed = value.trim();
|
|
12
|
+
if (!SLACK_CHANNEL_ID_RULE.pattern.test(trimmed)) {
|
|
13
|
+
throw new Error(`${label} must be a native Slack conversation id.`);
|
|
14
|
+
}
|
|
15
|
+
return trimmed;
|
|
16
|
+
}
|
|
17
|
+
function requireSlackUserId(value, label) {
|
|
18
|
+
const trimmed = value.trim();
|
|
19
|
+
if (!SLACK_USER_ID_RULE.pattern.test(trimmed)) {
|
|
20
|
+
throw new Error(`${label} must be a native Slack user id.`);
|
|
21
|
+
}
|
|
22
|
+
return trimmed;
|
|
23
|
+
}
|
|
24
|
+
function requireSlackThreadTs(value, label) {
|
|
25
|
+
const trimmed = value?.trim();
|
|
26
|
+
if (!trimmed) {
|
|
27
|
+
return undefined;
|
|
28
|
+
}
|
|
29
|
+
if (!SLACK_TS_RULE.pattern.test(trimmed)) {
|
|
30
|
+
throw new Error(`${label} must be a native Slack timestamp.`);
|
|
31
|
+
}
|
|
32
|
+
return trimmed;
|
|
33
|
+
}
|
|
34
|
+
export const SLACK_OPENCLAW_CRABLINE_PROVIDER_BRIDGE = createOpenClawCrablineProviderBridge({
|
|
35
|
+
provider: "slack",
|
|
36
|
+
createAdapter(slack) {
|
|
37
|
+
return {
|
|
38
|
+
async probe() {
|
|
39
|
+
const response = await fetch(`${slack.endpoints.apiRoot}auth.test`, {
|
|
40
|
+
headers: { authorization: `Bearer ${slack.botToken}` },
|
|
41
|
+
method: "POST",
|
|
42
|
+
});
|
|
43
|
+
if (!response.ok) {
|
|
44
|
+
throw new Error(`Crabline Slack auth.test probe failed with HTTP ${response.status}.`);
|
|
45
|
+
}
|
|
46
|
+
return await response.json();
|
|
47
|
+
},
|
|
48
|
+
createBinding() {
|
|
49
|
+
return {
|
|
50
|
+
accountId: DEFAULT_ACCOUNT_ID,
|
|
51
|
+
channel: "slack",
|
|
52
|
+
createChannelDriverSmokeEnv: (env) => ({
|
|
53
|
+
...env,
|
|
54
|
+
SLACK_API_URL: slack.endpoints.apiRoot,
|
|
55
|
+
SLACK_BOT_TOKEN: slack.botToken,
|
|
56
|
+
SLACK_SIGNING_SECRET: slack.signingSecret,
|
|
57
|
+
}),
|
|
58
|
+
createGatewayConfig: (openclawConfig = {}) => {
|
|
59
|
+
const channels = isRecord(openclawConfig.channels) ? openclawConfig.channels : {};
|
|
60
|
+
const slackConfig = isRecord(channels.slack) ? channels.slack : {};
|
|
61
|
+
const slackChannels = isRecord(slackConfig.channels) ? slackConfig.channels : {};
|
|
62
|
+
const defaultSlackChannel = isRecord(slackChannels["*"]) ? slackChannels["*"] : {};
|
|
63
|
+
return {
|
|
64
|
+
...openclawConfig,
|
|
65
|
+
channels: {
|
|
66
|
+
...channels,
|
|
67
|
+
slack: {
|
|
68
|
+
...slackConfig,
|
|
69
|
+
enabled: true,
|
|
70
|
+
mode: "http",
|
|
71
|
+
botToken: slack.botToken,
|
|
72
|
+
signingSecret: slack.signingSecret,
|
|
73
|
+
webhookPath: "/slack/events",
|
|
74
|
+
dmPolicy: "open",
|
|
75
|
+
allowFrom: ["*"],
|
|
76
|
+
groupPolicy: "open",
|
|
77
|
+
channels: {
|
|
78
|
+
...slackChannels,
|
|
79
|
+
"*": {
|
|
80
|
+
...defaultSlackChannel,
|
|
81
|
+
requireMention: false,
|
|
82
|
+
},
|
|
83
|
+
},
|
|
84
|
+
},
|
|
85
|
+
},
|
|
86
|
+
};
|
|
87
|
+
},
|
|
88
|
+
requiredPluginIds: ["slack"],
|
|
89
|
+
};
|
|
90
|
+
},
|
|
91
|
+
createAgentDelivery(parsed) {
|
|
92
|
+
const to = requireSlackSendTargetId(parsed.id, "Slack target");
|
|
93
|
+
const threadTs = requireSlackThreadTs(parsed.threadId, "Slack target thread");
|
|
94
|
+
return {
|
|
95
|
+
channel: "slack",
|
|
96
|
+
to,
|
|
97
|
+
replyChannel: "slack",
|
|
98
|
+
replyTo: slackTargetKey(to, threadTs),
|
|
99
|
+
};
|
|
100
|
+
},
|
|
101
|
+
createInbound(input) {
|
|
102
|
+
const channel = requireSlackChannelId(input.conversation.id, "Slack conversation");
|
|
103
|
+
const user = requireSlackUserId(input.senderId, "Slack sender");
|
|
104
|
+
const threadTs = requireSlackThreadTs(input.threadId, "Slack thread");
|
|
105
|
+
return {
|
|
106
|
+
...createAdminInboundRequest(slack),
|
|
107
|
+
providerBody: {
|
|
108
|
+
channel,
|
|
109
|
+
user,
|
|
110
|
+
...(input.senderName ? { username: input.senderName } : {}),
|
|
111
|
+
...(threadTs ? { threadTs } : {}),
|
|
112
|
+
text: input.text,
|
|
113
|
+
},
|
|
114
|
+
providerTargetKey: slackTargetKey(channel, threadTs),
|
|
115
|
+
qaTarget: qaTargetForInbound(input),
|
|
116
|
+
stateConversation: {
|
|
117
|
+
id: channel,
|
|
118
|
+
kind: channel.startsWith("D") ? "direct" : "group",
|
|
119
|
+
},
|
|
120
|
+
...(threadTs ? { threadId: threadTs } : {}),
|
|
121
|
+
};
|
|
122
|
+
},
|
|
123
|
+
createOutboundFromRecorderEvent({ event, targetByProviderTarget }) {
|
|
124
|
+
if (!isRecord(event) || event.type !== "api" || typeof event.path !== "string") {
|
|
125
|
+
return null;
|
|
126
|
+
}
|
|
127
|
+
if (!event.path.endsWith("/api/chat.postMessage") || !isRecord(event.body)) {
|
|
128
|
+
return null;
|
|
129
|
+
}
|
|
130
|
+
const channel = readString(event.body.channel);
|
|
131
|
+
const text = typeof event.body.text === "string" && event.body.text.trim()
|
|
132
|
+
? event.body.text
|
|
133
|
+
: undefined;
|
|
134
|
+
if (!channel || !text) {
|
|
135
|
+
return null;
|
|
136
|
+
}
|
|
137
|
+
const threadTs = readString(event.body.thread_ts);
|
|
138
|
+
const providerTargetKey = slackTargetKey(channel, threadTs);
|
|
139
|
+
return {
|
|
140
|
+
accountId: DEFAULT_ACCOUNT_ID,
|
|
141
|
+
senderId: "openclaw",
|
|
142
|
+
senderName: "OpenClaw QA",
|
|
143
|
+
text,
|
|
144
|
+
to: targetByProviderTarget.get(providerTargetKey) ?? providerTargetKey,
|
|
145
|
+
};
|
|
146
|
+
},
|
|
147
|
+
};
|
|
148
|
+
},
|
|
149
|
+
});
|
|
150
|
+
//# sourceMappingURL=slack.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"slack.js","sourceRoot":"","sources":["../../../../src/openclaw/bridges/slack.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare const TELEGRAM_OPENCLAW_CRABLINE_PROVIDER_BRIDGE: import("../shared.js").OpenClawCrablineProviderBridge<import("../../index.js").TelegramFakeServerManifest>;
|
|
@@ -0,0 +1,137 @@
|
|
|
1
|
+
import { createAdminInboundRequest, createOpenClawCrablineProviderBridge, DEFAULT_ACCOUNT_ID, isRecord, qaTargetForInbound, readInteger, readString, } from "../shared.js";
|
|
2
|
+
const TELEGRAM_DIRECT_CHAT_ID = "100001";
|
|
3
|
+
const TELEGRAM_GROUP_CHAT_ID = "-1001234567890";
|
|
4
|
+
const TELEGRAM_DEFAULT_SENDER_ID = 100001;
|
|
5
|
+
function normalizeTelegramChatId(kind, id) {
|
|
6
|
+
return /^-?\d+$/u.test(id.trim())
|
|
7
|
+
? id.trim()
|
|
8
|
+
: kind === "group"
|
|
9
|
+
? TELEGRAM_GROUP_CHAT_ID
|
|
10
|
+
: TELEGRAM_DIRECT_CHAT_ID;
|
|
11
|
+
}
|
|
12
|
+
function telegramTargetKey(chatId, threadId) {
|
|
13
|
+
return threadId === undefined ? chatId : `${chatId}:topic:${threadId}`;
|
|
14
|
+
}
|
|
15
|
+
export const TELEGRAM_OPENCLAW_CRABLINE_PROVIDER_BRIDGE = createOpenClawCrablineProviderBridge({
|
|
16
|
+
provider: "telegram",
|
|
17
|
+
createAdapter(telegram) {
|
|
18
|
+
return {
|
|
19
|
+
async probe() {
|
|
20
|
+
const response = await fetch(`${telegram.endpoints.apiRoot}/bot${telegram.botToken}/getMe`);
|
|
21
|
+
if (!response.ok) {
|
|
22
|
+
throw new Error(`Crabline Telegram getMe probe failed with HTTP ${response.status}.`);
|
|
23
|
+
}
|
|
24
|
+
return await response.json();
|
|
25
|
+
},
|
|
26
|
+
createBinding() {
|
|
27
|
+
return {
|
|
28
|
+
accountId: DEFAULT_ACCOUNT_ID,
|
|
29
|
+
channel: "telegram",
|
|
30
|
+
createChannelDriverSmokeEnv: (env) => ({
|
|
31
|
+
...env,
|
|
32
|
+
TELEGRAM_BOT_TOKEN: telegram.botToken,
|
|
33
|
+
}),
|
|
34
|
+
createGatewayConfig: (openclawConfig = {}) => {
|
|
35
|
+
const channels = isRecord(openclawConfig.channels) ? openclawConfig.channels : {};
|
|
36
|
+
const telegramConfig = isRecord(channels.telegram) ? channels.telegram : {};
|
|
37
|
+
const groups = isRecord(telegramConfig.groups) ? telegramConfig.groups : {};
|
|
38
|
+
const defaultGroup = isRecord(groups["*"]) ? groups["*"] : {};
|
|
39
|
+
const messages = isRecord(openclawConfig.messages) ? openclawConfig.messages : {};
|
|
40
|
+
const groupChat = isRecord(messages.groupChat) ? messages.groupChat : {};
|
|
41
|
+
return {
|
|
42
|
+
...openclawConfig,
|
|
43
|
+
channels: {
|
|
44
|
+
...channels,
|
|
45
|
+
telegram: {
|
|
46
|
+
...telegramConfig,
|
|
47
|
+
enabled: true,
|
|
48
|
+
botToken: telegram.botToken,
|
|
49
|
+
apiRoot: telegram.endpoints.apiRoot,
|
|
50
|
+
dmPolicy: "open",
|
|
51
|
+
groupPolicy: "open",
|
|
52
|
+
allowFrom: ["*"],
|
|
53
|
+
groupAllowFrom: ["*"],
|
|
54
|
+
groups: {
|
|
55
|
+
...groups,
|
|
56
|
+
"*": {
|
|
57
|
+
...defaultGroup,
|
|
58
|
+
requireMention: false,
|
|
59
|
+
},
|
|
60
|
+
},
|
|
61
|
+
},
|
|
62
|
+
},
|
|
63
|
+
messages: {
|
|
64
|
+
...messages,
|
|
65
|
+
groupChat: {
|
|
66
|
+
...groupChat,
|
|
67
|
+
mentionPatterns: ["\\b@?openclaw\\b"],
|
|
68
|
+
visibleReplies: "automatic",
|
|
69
|
+
},
|
|
70
|
+
},
|
|
71
|
+
};
|
|
72
|
+
},
|
|
73
|
+
requiredPluginIds: ["telegram"],
|
|
74
|
+
};
|
|
75
|
+
},
|
|
76
|
+
createAgentDelivery(parsed) {
|
|
77
|
+
const chatId = normalizeTelegramChatId(parsed.kind, parsed.id);
|
|
78
|
+
const threadId = readInteger(parsed.threadId);
|
|
79
|
+
const to = telegramTargetKey(chatId, threadId);
|
|
80
|
+
return {
|
|
81
|
+
channel: "telegram",
|
|
82
|
+
to,
|
|
83
|
+
replyChannel: "telegram",
|
|
84
|
+
replyTo: to,
|
|
85
|
+
};
|
|
86
|
+
},
|
|
87
|
+
createInbound(input) {
|
|
88
|
+
const kind = input.conversation.kind === "direct" ? "direct" : "group";
|
|
89
|
+
const chatId = normalizeTelegramChatId(kind, input.conversation.id);
|
|
90
|
+
const threadId = readInteger(input.threadId);
|
|
91
|
+
return {
|
|
92
|
+
...createAdminInboundRequest(telegram),
|
|
93
|
+
providerBody: {
|
|
94
|
+
chatId,
|
|
95
|
+
fromId: readInteger(input.senderId) ?? TELEGRAM_DEFAULT_SENDER_ID,
|
|
96
|
+
fromName: input.senderName ?? input.senderId,
|
|
97
|
+
...(threadId !== undefined ? { messageThreadId: threadId } : {}),
|
|
98
|
+
text: input.text,
|
|
99
|
+
},
|
|
100
|
+
providerTargetKey: telegramTargetKey(chatId, threadId),
|
|
101
|
+
qaTarget: qaTargetForInbound(input),
|
|
102
|
+
stateConversation: {
|
|
103
|
+
id: chatId,
|
|
104
|
+
kind: kind === "group" ? "group" : "direct",
|
|
105
|
+
},
|
|
106
|
+
...(threadId !== undefined ? { threadId: String(threadId) } : {}),
|
|
107
|
+
};
|
|
108
|
+
},
|
|
109
|
+
createOutboundFromRecorderEvent({ event, targetByProviderTarget }) {
|
|
110
|
+
if (!isRecord(event) || event.type !== "api" || typeof event.path !== "string") {
|
|
111
|
+
return null;
|
|
112
|
+
}
|
|
113
|
+
if (!event.path.endsWith("/sendMessage") || !isRecord(event.body)) {
|
|
114
|
+
return null;
|
|
115
|
+
}
|
|
116
|
+
const chatId = readString(event.body.chat_id);
|
|
117
|
+
const text = typeof event.body.text === "string" && event.body.text.trim()
|
|
118
|
+
? event.body.text
|
|
119
|
+
: undefined;
|
|
120
|
+
if (!chatId || !text) {
|
|
121
|
+
return null;
|
|
122
|
+
}
|
|
123
|
+
const threadId = readInteger(event.body.message_thread_id);
|
|
124
|
+
const providerTargetKey = telegramTargetKey(chatId, threadId);
|
|
125
|
+
return {
|
|
126
|
+
accountId: DEFAULT_ACCOUNT_ID,
|
|
127
|
+
senderId: "openclaw",
|
|
128
|
+
senderName: "OpenClaw QA",
|
|
129
|
+
text,
|
|
130
|
+
to: targetByProviderTarget.get(providerTargetKey) ??
|
|
131
|
+
(threadId === undefined ? chatId : providerTargetKey),
|
|
132
|
+
};
|
|
133
|
+
},
|
|
134
|
+
};
|
|
135
|
+
},
|
|
136
|
+
});
|
|
137
|
+
//# sourceMappingURL=telegram.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"telegram.js","sourceRoot":"","sources":["../../../../src/openclaw/bridges/telegram.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare const WHATSAPP_OPENCLAW_CRABLINE_PROVIDER_BRIDGE: import("../shared.js").OpenClawCrablineProviderBridge<import("../../index.js").WhatsAppFakeServerManifest>;
|
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
import { createAdminInboundRequest, createOpenClawCrablineProviderBridge, DEFAULT_ACCOUNT_ID, isRecord, qaTargetForInbound, readString, } from "../shared.js";
|
|
2
|
+
const WHATSAPP_JID_RE = /^(?:\d{7,15}(?::\d+)?@s\.whatsapp\.net|\d{7,15}@c\.us|\d{5,}@g\.us|\d{7,15}@lid)$/iu;
|
|
3
|
+
function requireWhatsAppJid(value, label) {
|
|
4
|
+
const trimmed = value.trim();
|
|
5
|
+
if (!WHATSAPP_JID_RE.test(trimmed)) {
|
|
6
|
+
throw new Error(`${label} must be a native WhatsApp JID.`);
|
|
7
|
+
}
|
|
8
|
+
return trimmed;
|
|
9
|
+
}
|
|
10
|
+
export const WHATSAPP_OPENCLAW_CRABLINE_PROVIDER_BRIDGE = createOpenClawCrablineProviderBridge({
|
|
11
|
+
provider: "whatsapp",
|
|
12
|
+
createAdapter(whatsapp) {
|
|
13
|
+
return {
|
|
14
|
+
async probe() {
|
|
15
|
+
const response = await fetch(`${whatsapp.endpoints.apiRoot}/health`);
|
|
16
|
+
if (!response.ok) {
|
|
17
|
+
throw new Error(`Crabline WhatsApp health probe failed with HTTP ${response.status}.`);
|
|
18
|
+
}
|
|
19
|
+
return await response.json();
|
|
20
|
+
},
|
|
21
|
+
createBinding() {
|
|
22
|
+
return {
|
|
23
|
+
accountId: DEFAULT_ACCOUNT_ID,
|
|
24
|
+
channel: "whatsapp",
|
|
25
|
+
createChannelDriverSmokeEnv: (env) => ({
|
|
26
|
+
...env,
|
|
27
|
+
CRABLINE_WHATSAPP_ADMIN_TOKEN: whatsapp.adminToken,
|
|
28
|
+
CRABLINE_WHATSAPP_ACCESS_TOKEN: whatsapp.accessToken,
|
|
29
|
+
CRABLINE_WHATSAPP_API_ROOT: whatsapp.endpoints.apiRoot,
|
|
30
|
+
CRABLINE_WHATSAPP_RECORDER_PATH: whatsapp.recorderPath,
|
|
31
|
+
CRABLINE_WHATSAPP_SELF_JID: whatsapp.selfJid,
|
|
32
|
+
}),
|
|
33
|
+
createGatewayConfig: (openclawConfig = {}) => {
|
|
34
|
+
const channels = isRecord(openclawConfig.channels) ? openclawConfig.channels : {};
|
|
35
|
+
const whatsappConfig = isRecord(channels.whatsapp) ? channels.whatsapp : {};
|
|
36
|
+
const groups = isRecord(whatsappConfig.groups) ? whatsappConfig.groups : {};
|
|
37
|
+
const defaultGroup = isRecord(groups["*"]) ? groups["*"] : {};
|
|
38
|
+
return {
|
|
39
|
+
...openclawConfig,
|
|
40
|
+
channels: {
|
|
41
|
+
...channels,
|
|
42
|
+
whatsapp: {
|
|
43
|
+
...whatsappConfig,
|
|
44
|
+
enabled: true,
|
|
45
|
+
dmPolicy: "open",
|
|
46
|
+
groupPolicy: "open",
|
|
47
|
+
allowFrom: ["*"],
|
|
48
|
+
groupAllowFrom: ["*"],
|
|
49
|
+
groups: {
|
|
50
|
+
...groups,
|
|
51
|
+
"*": {
|
|
52
|
+
...defaultGroup,
|
|
53
|
+
requireMention: false,
|
|
54
|
+
},
|
|
55
|
+
},
|
|
56
|
+
},
|
|
57
|
+
},
|
|
58
|
+
};
|
|
59
|
+
},
|
|
60
|
+
requiredPluginIds: ["whatsapp"],
|
|
61
|
+
};
|
|
62
|
+
},
|
|
63
|
+
createAgentDelivery(parsed) {
|
|
64
|
+
const to = requireWhatsAppJid(parsed.id, "WhatsApp target");
|
|
65
|
+
return {
|
|
66
|
+
channel: "whatsapp",
|
|
67
|
+
to,
|
|
68
|
+
replyChannel: "whatsapp",
|
|
69
|
+
replyTo: to,
|
|
70
|
+
};
|
|
71
|
+
},
|
|
72
|
+
createInbound(input) {
|
|
73
|
+
const chatJid = requireWhatsAppJid(input.conversation.id, "WhatsApp conversation");
|
|
74
|
+
const senderJid = requireWhatsAppJid(input.senderId, "WhatsApp sender");
|
|
75
|
+
return {
|
|
76
|
+
...createAdminInboundRequest(whatsapp),
|
|
77
|
+
providerBody: {
|
|
78
|
+
chatJid,
|
|
79
|
+
senderJid,
|
|
80
|
+
...(input.senderName ? { pushName: input.senderName } : {}),
|
|
81
|
+
text: input.text,
|
|
82
|
+
},
|
|
83
|
+
providerTargetKey: chatJid,
|
|
84
|
+
qaTarget: qaTargetForInbound(input),
|
|
85
|
+
stateConversation: {
|
|
86
|
+
id: chatJid,
|
|
87
|
+
kind: chatJid.endsWith("@g.us") ? "group" : "direct",
|
|
88
|
+
},
|
|
89
|
+
};
|
|
90
|
+
},
|
|
91
|
+
createOutboundFromRecorderEvent({ event, targetByProviderTarget }) {
|
|
92
|
+
if (!isRecord(event) || event.type !== "api" || typeof event.path !== "string") {
|
|
93
|
+
return null;
|
|
94
|
+
}
|
|
95
|
+
if (!event.path.endsWith("/crabline/whatsapp/messages") || !isRecord(event.body)) {
|
|
96
|
+
return null;
|
|
97
|
+
}
|
|
98
|
+
const to = readString(event.body.to ?? event.body.jid);
|
|
99
|
+
const textPayload = event.body.text;
|
|
100
|
+
const text = isRecord(textPayload) ? readString(textPayload.body) : readString(textPayload);
|
|
101
|
+
if (!to || !text) {
|
|
102
|
+
return null;
|
|
103
|
+
}
|
|
104
|
+
return {
|
|
105
|
+
accountId: DEFAULT_ACCOUNT_ID,
|
|
106
|
+
senderId: "openclaw",
|
|
107
|
+
senderName: "OpenClaw QA",
|
|
108
|
+
text,
|
|
109
|
+
to: targetByProviderTarget.get(to) ?? to,
|
|
110
|
+
};
|
|
111
|
+
},
|
|
112
|
+
};
|
|
113
|
+
},
|
|
114
|
+
});
|
|
115
|
+
//# sourceMappingURL=whatsapp.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"whatsapp.js","sourceRoot":"","sources":["../../../../src/openclaw/bridges/whatsapp.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
import type { CrablineFakeProviderChannel, CrablineFakeProviderManifest } from "../fake-servers/index.js";
|
|
2
|
+
export declare const DEFAULT_ACCOUNT_ID = "default";
|
|
3
|
+
export declare const OPENCLAW_CRABLINE_CHANNEL_CAPABILITY_MATRIX_PATH = "crabline-fake-provider-capabilities.json";
|
|
4
|
+
export declare const OPENCLAW_CRABLINE_CHANNEL_SMOKE_PATH = "crabline-fake-provider-smoke.json";
|
|
5
|
+
export declare const OPENCLAW_CRABLINE_MANIFEST_PATH = "crabline-fake-provider-server.json";
|
|
6
|
+
export declare const OPENCLAW_CRABLINE_DEFAULT_CHANNEL = "telegram";
|
|
7
|
+
export type OpenClawCrablineChannelDriverSelection = {
|
|
8
|
+
channel: CrablineFakeProviderChannel;
|
|
9
|
+
channelDriver: "crabline";
|
|
10
|
+
capabilityMatrixPath: typeof OPENCLAW_CRABLINE_CHANNEL_CAPABILITY_MATRIX_PATH;
|
|
11
|
+
smokeArtifactPath: typeof OPENCLAW_CRABLINE_CHANNEL_SMOKE_PATH;
|
|
12
|
+
};
|
|
13
|
+
export type OpenClawCrablineChannelDriverSmokeResult = {
|
|
14
|
+
capabilityReport: unknown;
|
|
15
|
+
manifestPath: string;
|
|
16
|
+
smoke: unknown;
|
|
17
|
+
};
|
|
18
|
+
export type OpenClawCrablineConversation = {
|
|
19
|
+
id: string;
|
|
20
|
+
kind: "direct" | "group";
|
|
21
|
+
};
|
|
22
|
+
export type OpenClawCrablineGatewayBinding = {
|
|
23
|
+
accountId: string;
|
|
24
|
+
channel: string;
|
|
25
|
+
createChannelDriverSmokeEnv(env: NodeJS.ProcessEnv): NodeJS.ProcessEnv;
|
|
26
|
+
createGatewayConfig(openclawConfig?: Record<string, unknown>): Record<string, unknown>;
|
|
27
|
+
requiredPluginIds: string[];
|
|
28
|
+
};
|
|
29
|
+
export type OpenClawCrablineAgentDelivery = {
|
|
30
|
+
channel: string;
|
|
31
|
+
replyChannel: string;
|
|
32
|
+
replyTo: string;
|
|
33
|
+
to: string;
|
|
34
|
+
};
|
|
35
|
+
export type OpenClawCrablineInboundInput = {
|
|
36
|
+
conversation: {
|
|
37
|
+
id: string;
|
|
38
|
+
kind: string;
|
|
39
|
+
};
|
|
40
|
+
senderId: string;
|
|
41
|
+
senderName?: string | undefined;
|
|
42
|
+
text: string;
|
|
43
|
+
threadId?: string | undefined;
|
|
44
|
+
};
|
|
45
|
+
export type OpenClawCrablineInbound = {
|
|
46
|
+
providerBody: Record<string, unknown>;
|
|
47
|
+
providerHeaders: Record<string, string>;
|
|
48
|
+
providerTargetKey: string;
|
|
49
|
+
providerUrl: string;
|
|
50
|
+
qaTarget: string;
|
|
51
|
+
stateConversation: OpenClawCrablineConversation;
|
|
52
|
+
threadId?: string | undefined;
|
|
53
|
+
};
|
|
54
|
+
export type OpenClawCrablineOutboundMessage = {
|
|
55
|
+
accountId: string;
|
|
56
|
+
senderId: string;
|
|
57
|
+
senderName: string;
|
|
58
|
+
text: string;
|
|
59
|
+
to: string;
|
|
60
|
+
};
|
|
61
|
+
export type StartOpenClawCrablineAdapterParams = {
|
|
62
|
+
channel: CrablineFakeProviderChannel;
|
|
63
|
+
openclawConfig?: Record<string, unknown> | undefined;
|
|
64
|
+
recorderPath?: string | undefined;
|
|
65
|
+
};
|
|
66
|
+
export type StartedOpenClawCrablineAdapter = OpenClawCrablineGatewayBinding & {
|
|
67
|
+
close(): Promise<void>;
|
|
68
|
+
createAgentDelivery(params: {
|
|
69
|
+
target: string;
|
|
70
|
+
}): OpenClawCrablineAgentDelivery;
|
|
71
|
+
createInbound(params: {
|
|
72
|
+
input: OpenClawCrablineInboundInput;
|
|
73
|
+
}): OpenClawCrablineInbound;
|
|
74
|
+
createOutboundFromRecorderEvent(params: {
|
|
75
|
+
event: unknown;
|
|
76
|
+
targetByProviderTarget: ReadonlyMap<string, string>;
|
|
77
|
+
}): OpenClawCrablineOutboundMessage | null;
|
|
78
|
+
manifest: CrablineFakeProviderManifest;
|
|
79
|
+
probe(): Promise<unknown>;
|
|
80
|
+
};
|
|
81
|
+
export type ParsedQaTarget = {
|
|
82
|
+
kind: "direct" | "group";
|
|
83
|
+
id: string;
|
|
84
|
+
threadId?: string;
|
|
85
|
+
};
|
|
86
|
+
export type OpenClawCrablineProviderAdapter = {
|
|
87
|
+
createAgentDelivery(parsed: ParsedQaTarget): OpenClawCrablineAgentDelivery;
|
|
88
|
+
createBinding(): OpenClawCrablineGatewayBinding;
|
|
89
|
+
createInbound(input: OpenClawCrablineInboundInput): OpenClawCrablineInbound;
|
|
90
|
+
createOutboundFromRecorderEvent(params: {
|
|
91
|
+
event: unknown;
|
|
92
|
+
targetByProviderTarget: ReadonlyMap<string, string>;
|
|
93
|
+
}): OpenClawCrablineOutboundMessage | null;
|
|
94
|
+
probe(): Promise<unknown>;
|
|
95
|
+
};
|
|
96
|
+
export type OpenClawCrablineProviderBridge<TManifest extends CrablineFakeProviderManifest = CrablineFakeProviderManifest> = {
|
|
97
|
+
createAdapter(manifest: TManifest): OpenClawCrablineProviderAdapter;
|
|
98
|
+
createAdapterFromManifest(manifest: CrablineFakeProviderManifest): OpenClawCrablineProviderAdapter;
|
|
99
|
+
provider: TManifest["provider"];
|
|
100
|
+
};
|
|
101
|
+
export type OpenClawCrablineProviderBridgeRegistry = {
|
|
102
|
+
[Provider in CrablineFakeProviderManifest["provider"]]: OpenClawCrablineProviderBridge<Extract<CrablineFakeProviderManifest, {
|
|
103
|
+
provider: Provider;
|
|
104
|
+
}>>;
|
|
105
|
+
};
|
|
106
|
+
export declare function createOpenClawCrablineProviderBridge<TProvider extends CrablineFakeProviderManifest["provider"]>(params: {
|
|
107
|
+
createAdapter(manifest: Extract<CrablineFakeProviderManifest, {
|
|
108
|
+
provider: TProvider;
|
|
109
|
+
}>): OpenClawCrablineProviderAdapter;
|
|
110
|
+
provider: TProvider;
|
|
111
|
+
}): OpenClawCrablineProviderBridge<Extract<CrablineFakeProviderManifest, {
|
|
112
|
+
provider: TProvider;
|
|
113
|
+
}>>;
|
|
114
|
+
export declare function readString(value: unknown): string | undefined;
|
|
115
|
+
export declare function isRecord(value: unknown): value is Record<string, unknown>;
|
|
116
|
+
export declare function readInteger(value: unknown): number | undefined;
|
|
117
|
+
export declare function parseQaTarget(target: string): ParsedQaTarget;
|
|
118
|
+
export declare function qaTargetForInbound(input: OpenClawCrablineInboundInput): string;
|
|
119
|
+
export declare function createAdminInboundRequest(manifest: CrablineFakeProviderManifest): {
|
|
120
|
+
providerHeaders: {
|
|
121
|
+
"content-type": string;
|
|
122
|
+
"x-crabline-admin-token": string;
|
|
123
|
+
};
|
|
124
|
+
providerUrl: string;
|
|
125
|
+
};
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
import { ADMIN_TOKEN_HEADER } from "../fake-servers/http.js";
|
|
2
|
+
export const DEFAULT_ACCOUNT_ID = "default";
|
|
3
|
+
export const OPENCLAW_CRABLINE_CHANNEL_CAPABILITY_MATRIX_PATH = "crabline-fake-provider-capabilities.json";
|
|
4
|
+
export const OPENCLAW_CRABLINE_CHANNEL_SMOKE_PATH = "crabline-fake-provider-smoke.json";
|
|
5
|
+
export const OPENCLAW_CRABLINE_MANIFEST_PATH = "crabline-fake-provider-server.json";
|
|
6
|
+
export const OPENCLAW_CRABLINE_DEFAULT_CHANNEL = "telegram";
|
|
7
|
+
export function createOpenClawCrablineProviderBridge(params) {
|
|
8
|
+
const bridge = {
|
|
9
|
+
createAdapter: params.createAdapter,
|
|
10
|
+
createAdapterFromManifest(manifest) {
|
|
11
|
+
if (manifest.provider !== params.provider) {
|
|
12
|
+
throw new Error(`Unsupported OpenClaw fake provider binding: expected ${params.provider}, got ${manifest.provider}.`);
|
|
13
|
+
}
|
|
14
|
+
return params.createAdapter(manifest);
|
|
15
|
+
},
|
|
16
|
+
provider: params.provider,
|
|
17
|
+
};
|
|
18
|
+
return bridge;
|
|
19
|
+
}
|
|
20
|
+
export function readString(value) {
|
|
21
|
+
if (typeof value === "string" && value.trim()) {
|
|
22
|
+
return value.trim();
|
|
23
|
+
}
|
|
24
|
+
if (typeof value === "number" || typeof value === "bigint") {
|
|
25
|
+
return String(value);
|
|
26
|
+
}
|
|
27
|
+
return undefined;
|
|
28
|
+
}
|
|
29
|
+
export function isRecord(value) {
|
|
30
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
31
|
+
}
|
|
32
|
+
export function readInteger(value) {
|
|
33
|
+
const stringValue = readString(value);
|
|
34
|
+
if (!stringValue || !/^-?\d+$/u.test(stringValue)) {
|
|
35
|
+
return undefined;
|
|
36
|
+
}
|
|
37
|
+
return Number(stringValue);
|
|
38
|
+
}
|
|
39
|
+
export function parseQaTarget(target) {
|
|
40
|
+
const trimmed = target.trim();
|
|
41
|
+
if (trimmed.startsWith("thread:")) {
|
|
42
|
+
const rest = trimmed.slice("thread:".length);
|
|
43
|
+
const slash = rest.indexOf("/");
|
|
44
|
+
if (slash > 0) {
|
|
45
|
+
return { kind: "group", id: rest.slice(0, slash), threadId: rest.slice(slash + 1) };
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
if (trimmed.startsWith("channel:")) {
|
|
49
|
+
return { kind: "group", id: trimmed.slice("channel:".length) };
|
|
50
|
+
}
|
|
51
|
+
if (trimmed.startsWith("group:")) {
|
|
52
|
+
return { kind: "group", id: trimmed.slice("group:".length) };
|
|
53
|
+
}
|
|
54
|
+
if (trimmed.startsWith("dm:")) {
|
|
55
|
+
return { kind: "direct", id: trimmed.slice("dm:".length) };
|
|
56
|
+
}
|
|
57
|
+
return { kind: "direct", id: trimmed };
|
|
58
|
+
}
|
|
59
|
+
export function qaTargetForInbound(input) {
|
|
60
|
+
const prefix = input.conversation.kind === "direct"
|
|
61
|
+
? "dm"
|
|
62
|
+
: input.conversation.kind === "channel"
|
|
63
|
+
? "channel"
|
|
64
|
+
: "group";
|
|
65
|
+
return input.threadId
|
|
66
|
+
? `thread:${input.conversation.id}/${input.threadId}`
|
|
67
|
+
: `${prefix}:${input.conversation.id}`;
|
|
68
|
+
}
|
|
69
|
+
export function createAdminInboundRequest(manifest) {
|
|
70
|
+
return {
|
|
71
|
+
providerHeaders: {
|
|
72
|
+
"content-type": "application/json",
|
|
73
|
+
[ADMIN_TOKEN_HEADER]: manifest.adminToken,
|
|
74
|
+
},
|
|
75
|
+
providerUrl: manifest.endpoints.adminInboundUrl,
|
|
76
|
+
};
|
|
77
|
+
}
|
|
78
|
+
//# sourceMappingURL=shared.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"shared.js","sourceRoot":"","sources":["../../../src/openclaw/shared.ts"],"names":[],"mappings":"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"}
|