@atom8n/n8n-nodes-langchain 2.5.7 → 2.5.8
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/dist/known/nodes.json +24 -0
- package/dist/methods/defined.json +3 -0
- package/dist/methods/referenced.json +3 -0
- package/dist/nodes/agents/OpenClawAgent/OpenClawAgent.node.js +62 -0
- package/dist/nodes/agents/OpenClawAgent/OpenClawAgent.node.js.map +1 -0
- package/dist/nodes/agents/OpenClawAgent/V1/OpenClawAgentV1.node.js +821 -0
- package/dist/nodes/agents/OpenClawAgent/V1/OpenClawAgentV1.node.js.map +1 -0
- package/dist/nodes/agents/OpenClawAgent/V2/OpenClawAgentV2.node.js +2059 -0
- package/dist/nodes/agents/OpenClawAgent/V2/OpenClawAgentV2.node.js.map +1 -0
- package/dist/nodes/agents/OpenClawAgent/channels/TelegramChannel/TelegramChannel.node.js +329 -0
- package/dist/nodes/agents/OpenClawAgent/channels/TelegramChannel/TelegramChannel.node.js.map +1 -0
- package/dist/nodes/agents/OpenClawAgent/channels/TelegramChannel/telegram-channel.svg +4 -0
- package/dist/nodes/agents/OpenClawAgent/channels/WhatsAppChannel/WhatsAppChannel.node.js +108 -0
- package/dist/nodes/agents/OpenClawAgent/channels/WhatsAppChannel/WhatsAppChannel.node.js.map +1 -0
- package/dist/nodes/agents/OpenClawAgent/channels/WhatsAppChannel/whatsapp-channel.svg +3 -0
- package/dist/nodes/agents/OpenClawAgent/mcpServers/OpenClawMcpServer/OpenClawMcpServer.node.js +228 -0
- package/dist/nodes/agents/OpenClawAgent/mcpServers/OpenClawMcpServer/OpenClawMcpServer.node.js.map +1 -0
- package/dist/nodes/agents/OpenClawAgent/mcpServers/OpenClawMcpServer/openclaw-mcp-server.svg +9 -0
- package/dist/nodes/agents/OpenClawAgent/models/OpenCodeFreeModel/OpenCodeFreeModel.node.js +97 -0
- package/dist/nodes/agents/OpenClawAgent/models/OpenCodeFreeModel/OpenCodeFreeModel.node.js.map +1 -0
- package/dist/nodes/agents/OpenClawAgent/models/OpenCodeFreeModel/opencode-free-model.svg +1 -0
- package/dist/nodes/agents/OpenClawAgent/openclaw.svg +8 -0
- package/dist/nodes/agents/OpenClawAgent/plugins/OpenClawPlugin/OpenClawPlugin.node.js +261 -0
- package/dist/nodes/agents/OpenClawAgent/plugins/OpenClawPlugin/OpenClawPlugin.node.js.map +1 -0
- package/dist/nodes/agents/OpenClawAgent/plugins/OpenClawPlugin/openclaw-plugin.svg +3 -0
- package/dist/nodes/llms/LmChat9Router/LmChat9Router.node.js +40 -3
- package/dist/nodes/llms/LmChat9Router/LmChat9Router.node.js.map +1 -1
- package/dist/types/nodes.json +8 -1
- package/package.json +17 -11
|
@@ -0,0 +1,329 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
+
var __export = (target, all) => {
|
|
7
|
+
for (var name in all)
|
|
8
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
9
|
+
};
|
|
10
|
+
var __copyProps = (to, from, except, desc) => {
|
|
11
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
12
|
+
for (let key of __getOwnPropNames(from))
|
|
13
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
14
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
15
|
+
}
|
|
16
|
+
return to;
|
|
17
|
+
};
|
|
18
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
|
+
var TelegramChannel_node_exports = {};
|
|
20
|
+
__export(TelegramChannel_node_exports, {
|
|
21
|
+
TelegramChannel: () => TelegramChannel
|
|
22
|
+
});
|
|
23
|
+
module.exports = __toCommonJS(TelegramChannel_node_exports);
|
|
24
|
+
var import_fs = require("fs");
|
|
25
|
+
var import_path = require("path");
|
|
26
|
+
var import_n8n_workflow = require("n8n-workflow");
|
|
27
|
+
const TELEGRAM_CREDENTIAL_TYPE = "telegramApi";
|
|
28
|
+
const OPENCLAW_STATE_DIR_ENV = "OPENCLAW_STATE_DIR";
|
|
29
|
+
const OPENCLAW_OAUTH_DIR_ENV = "OPENCLAW_OAUTH_DIR";
|
|
30
|
+
const OPENCLAW_DEFAULT_ACCOUNT_ID = "default";
|
|
31
|
+
function isObject(value) {
|
|
32
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
33
|
+
}
|
|
34
|
+
function normalizeOptionalString(value) {
|
|
35
|
+
if (typeof value === "number" && Number.isFinite(value)) {
|
|
36
|
+
return String(value);
|
|
37
|
+
}
|
|
38
|
+
if (typeof value !== "string") {
|
|
39
|
+
return void 0;
|
|
40
|
+
}
|
|
41
|
+
const trimmed = value.trim();
|
|
42
|
+
return trimmed || void 0;
|
|
43
|
+
}
|
|
44
|
+
function normalizeTelegramAllowFromEntry(value) {
|
|
45
|
+
const raw = normalizeOptionalString(value);
|
|
46
|
+
if (!raw) {
|
|
47
|
+
return void 0;
|
|
48
|
+
}
|
|
49
|
+
const normalized = raw.replace(/^(telegram|tg):/i, "").trim();
|
|
50
|
+
return normalized || void 0;
|
|
51
|
+
}
|
|
52
|
+
function normalizeAllowFromEntries(value) {
|
|
53
|
+
const rawEntries = Array.isArray(value) ? value : typeof value === "string" ? value.split(/[\n,]/) : [];
|
|
54
|
+
const seen = /* @__PURE__ */ new Set();
|
|
55
|
+
const entries = [];
|
|
56
|
+
for (const rawEntry of rawEntries) {
|
|
57
|
+
const entry = normalizeTelegramAllowFromEntry(rawEntry);
|
|
58
|
+
if (!entry || seen.has(entry)) {
|
|
59
|
+
continue;
|
|
60
|
+
}
|
|
61
|
+
seen.add(entry);
|
|
62
|
+
entries.push(entry);
|
|
63
|
+
}
|
|
64
|
+
return entries;
|
|
65
|
+
}
|
|
66
|
+
function getHomeDirectory() {
|
|
67
|
+
return normalizeOptionalString(process.env.HOME) ?? normalizeOptionalString(process.env.USERPROFILE);
|
|
68
|
+
}
|
|
69
|
+
function resolveOpenClawStateDir() {
|
|
70
|
+
const stateDir = normalizeOptionalString(process.env[OPENCLAW_STATE_DIR_ENV]);
|
|
71
|
+
if (stateDir) {
|
|
72
|
+
return stateDir;
|
|
73
|
+
}
|
|
74
|
+
const home = getHomeDirectory();
|
|
75
|
+
return home ? (0, import_path.join)(home, ".openclaw") : void 0;
|
|
76
|
+
}
|
|
77
|
+
function resolveOpenClawCredentialsDir() {
|
|
78
|
+
const oauthDir = normalizeOptionalString(process.env[OPENCLAW_OAUTH_DIR_ENV]);
|
|
79
|
+
if (oauthDir) {
|
|
80
|
+
return oauthDir;
|
|
81
|
+
}
|
|
82
|
+
const stateDir = resolveOpenClawStateDir();
|
|
83
|
+
return stateDir ? (0, import_path.join)(stateDir, "credentials") : void 0;
|
|
84
|
+
}
|
|
85
|
+
function normalizeOpenClawAccountId(value) {
|
|
86
|
+
const accountId = normalizeOptionalString(value)?.toLowerCase();
|
|
87
|
+
return accountId || OPENCLAW_DEFAULT_ACCOUNT_ID;
|
|
88
|
+
}
|
|
89
|
+
function safeFilenameKey(value) {
|
|
90
|
+
return value.trim().toLowerCase().replace(/[\\/:*?"<>|]/g, "_").replace(/\.\./g, "_");
|
|
91
|
+
}
|
|
92
|
+
function getTelegramPairingPath(credentialsDir) {
|
|
93
|
+
return (0, import_path.join)(credentialsDir, "telegram-pairing.json");
|
|
94
|
+
}
|
|
95
|
+
function getTelegramAllowFromPaths(credentialsDir, accountId) {
|
|
96
|
+
const accountPath = (0, import_path.join)(credentialsDir, `telegram-${safeFilenameKey(accountId)}-allowFrom.json`);
|
|
97
|
+
if (accountId === OPENCLAW_DEFAULT_ACCOUNT_ID) {
|
|
98
|
+
return [accountPath, (0, import_path.join)(credentialsDir, "telegram-allowFrom.json")];
|
|
99
|
+
}
|
|
100
|
+
return [accountPath];
|
|
101
|
+
}
|
|
102
|
+
function readJsonFile(filePath) {
|
|
103
|
+
try {
|
|
104
|
+
if (!(0, import_fs.existsSync)(filePath) || !(0, import_fs.statSync)(filePath).isFile()) {
|
|
105
|
+
return void 0;
|
|
106
|
+
}
|
|
107
|
+
return JSON.parse((0, import_fs.readFileSync)(filePath, "utf8"));
|
|
108
|
+
} catch (error) {
|
|
109
|
+
console.log("[TelegramChannel] Failed to read Allow From source file", {
|
|
110
|
+
filePath,
|
|
111
|
+
error: error instanceof Error ? error.message : String(error)
|
|
112
|
+
});
|
|
113
|
+
return void 0;
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
function getMetaString(meta, key) {
|
|
117
|
+
return isObject(meta) ? normalizeOptionalString(meta[key]) : void 0;
|
|
118
|
+
}
|
|
119
|
+
function formatPairingOptionName(request) {
|
|
120
|
+
const id = normalizeTelegramAllowFromEntry(request.id) ?? "Unknown sender";
|
|
121
|
+
const meta = request.meta;
|
|
122
|
+
const username = getMetaString(meta, "username");
|
|
123
|
+
const firstName = getMetaString(meta, "firstName");
|
|
124
|
+
const lastName = getMetaString(meta, "lastName");
|
|
125
|
+
const fullName = [firstName, lastName].filter(Boolean).join(" ");
|
|
126
|
+
const labelParts = [username ? `@${username}` : void 0, fullName || void 0].filter(Boolean);
|
|
127
|
+
return labelParts.length > 0 ? `${id} (${labelParts.join(", ")})` : id;
|
|
128
|
+
}
|
|
129
|
+
function addOption(options, seen, option) {
|
|
130
|
+
const value = String(option.value);
|
|
131
|
+
if (seen.has(value)) {
|
|
132
|
+
return;
|
|
133
|
+
}
|
|
134
|
+
seen.add(value);
|
|
135
|
+
options.push(option);
|
|
136
|
+
}
|
|
137
|
+
function getTelegramAllowFromOptions(accountId) {
|
|
138
|
+
const credentialsDir = resolveOpenClawCredentialsDir();
|
|
139
|
+
if (!credentialsDir) {
|
|
140
|
+
console.log("[TelegramChannel] Allow From options skipped: OpenClaw credentials dir unknown", {
|
|
141
|
+
accountId
|
|
142
|
+
});
|
|
143
|
+
return [];
|
|
144
|
+
}
|
|
145
|
+
const pairingPath = getTelegramPairingPath(credentialsDir);
|
|
146
|
+
const allowFromPaths = getTelegramAllowFromPaths(credentialsDir, accountId);
|
|
147
|
+
console.log("[TelegramChannel] Loading Allow From options", {
|
|
148
|
+
accountId,
|
|
149
|
+
credentialsDir,
|
|
150
|
+
pairingPath,
|
|
151
|
+
allowFromPaths
|
|
152
|
+
});
|
|
153
|
+
const options = [];
|
|
154
|
+
const seen = /* @__PURE__ */ new Set();
|
|
155
|
+
const pairingStore = readJsonFile(pairingPath);
|
|
156
|
+
const requests = isObject(pairingStore) && Array.isArray(pairingStore.requests) ? pairingStore.requests : [];
|
|
157
|
+
let pairingOptionCount = 0;
|
|
158
|
+
for (const request of requests) {
|
|
159
|
+
if (!isObject(request)) {
|
|
160
|
+
continue;
|
|
161
|
+
}
|
|
162
|
+
const id = normalizeTelegramAllowFromEntry(request.id);
|
|
163
|
+
if (!id) {
|
|
164
|
+
continue;
|
|
165
|
+
}
|
|
166
|
+
const requestAccountId = normalizeOpenClawAccountId(getMetaString(request.meta, "accountId"));
|
|
167
|
+
if (requestAccountId !== accountId) {
|
|
168
|
+
continue;
|
|
169
|
+
}
|
|
170
|
+
addOption(options, seen, {
|
|
171
|
+
name: formatPairingOptionName(request),
|
|
172
|
+
value: id,
|
|
173
|
+
description: `Pending Telegram pairing request from ${pairingPath}`
|
|
174
|
+
});
|
|
175
|
+
pairingOptionCount++;
|
|
176
|
+
}
|
|
177
|
+
let allowFromOptionCount = 0;
|
|
178
|
+
for (const allowFromPath of allowFromPaths) {
|
|
179
|
+
const allowFromStore = readJsonFile(allowFromPath);
|
|
180
|
+
const entries = isObject(allowFromStore) && Array.isArray(allowFromStore.allowFrom) ? normalizeAllowFromEntries(allowFromStore.allowFrom) : [];
|
|
181
|
+
for (const entry of entries) {
|
|
182
|
+
addOption(options, seen, {
|
|
183
|
+
name: `${entry} (Configured)`,
|
|
184
|
+
value: entry,
|
|
185
|
+
description: `Existing Telegram allowFrom entry from ${allowFromPath}`
|
|
186
|
+
});
|
|
187
|
+
allowFromOptionCount++;
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
console.log("[TelegramChannel] Loaded Allow From options", {
|
|
191
|
+
accountId,
|
|
192
|
+
optionCount: options.length,
|
|
193
|
+
pairingOptionCount,
|
|
194
|
+
allowFromOptionCount
|
|
195
|
+
});
|
|
196
|
+
return options;
|
|
197
|
+
}
|
|
198
|
+
class TelegramChannel {
|
|
199
|
+
constructor() {
|
|
200
|
+
this.description = {
|
|
201
|
+
displayName: "Telegram Channel",
|
|
202
|
+
name: "openClawTelegramChannel",
|
|
203
|
+
icon: "file:telegram-channel.svg",
|
|
204
|
+
iconColor: "blue",
|
|
205
|
+
group: ["transform"],
|
|
206
|
+
version: 1,
|
|
207
|
+
description: "Provides Telegram channel configuration to an OpenClaw AI Agent",
|
|
208
|
+
defaults: {
|
|
209
|
+
name: "Telegram Channel"
|
|
210
|
+
},
|
|
211
|
+
codex: {
|
|
212
|
+
alias: ["Telegram", "Channel", "Bot", "OpenClaw"],
|
|
213
|
+
categories: ["AI"],
|
|
214
|
+
subcategories: {
|
|
215
|
+
AI: ["Other"]
|
|
216
|
+
},
|
|
217
|
+
resources: {
|
|
218
|
+
primaryDocumentation: [
|
|
219
|
+
{
|
|
220
|
+
url: "https://docs.openclaw.ai/channels/telegram"
|
|
221
|
+
}
|
|
222
|
+
]
|
|
223
|
+
}
|
|
224
|
+
},
|
|
225
|
+
inputs: [],
|
|
226
|
+
outputs: [import_n8n_workflow.NodeConnectionTypes.AiChannel],
|
|
227
|
+
outputNames: ["Channel"],
|
|
228
|
+
credentials: [
|
|
229
|
+
{
|
|
230
|
+
name: TELEGRAM_CREDENTIAL_TYPE,
|
|
231
|
+
required: true
|
|
232
|
+
}
|
|
233
|
+
],
|
|
234
|
+
properties: [
|
|
235
|
+
{
|
|
236
|
+
displayName: "Connect this node to an OpenClaw AI Agent to provide Telegram channel configuration. The bot token is read from the Telegram credential.",
|
|
237
|
+
name: "telegramNotice",
|
|
238
|
+
type: "notice",
|
|
239
|
+
default: ""
|
|
240
|
+
},
|
|
241
|
+
{
|
|
242
|
+
displayName: "Account ID",
|
|
243
|
+
name: "accountId",
|
|
244
|
+
type: "string",
|
|
245
|
+
default: "",
|
|
246
|
+
description: "Optional OpenClaw account ID for multi-account setups. Leave empty for the default account."
|
|
247
|
+
},
|
|
248
|
+
{
|
|
249
|
+
displayName: "DM Policy",
|
|
250
|
+
name: "dmPolicy",
|
|
251
|
+
type: "options",
|
|
252
|
+
default: "pairing",
|
|
253
|
+
description: "Direct message policy for this Telegram channel",
|
|
254
|
+
options: [
|
|
255
|
+
{ name: "Pairing", value: "pairing" },
|
|
256
|
+
{ name: "Open", value: "open" },
|
|
257
|
+
{ name: "Allowlist", value: "allowlist" },
|
|
258
|
+
{ name: "Disabled", value: "disabled" }
|
|
259
|
+
]
|
|
260
|
+
},
|
|
261
|
+
{
|
|
262
|
+
displayName: "Allow From Names or IDs",
|
|
263
|
+
name: "allowFrom",
|
|
264
|
+
type: "multiOptions",
|
|
265
|
+
typeOptions: {
|
|
266
|
+
loadOptionsMethod: "getAllowFromOptions",
|
|
267
|
+
loadOptionsDependsOn: ["accountId"]
|
|
268
|
+
},
|
|
269
|
+
default: [],
|
|
270
|
+
allowArbitraryValues: true,
|
|
271
|
+
description: 'Choose from the list, or specify IDs using an <a href="https://docs.n8n.io/code/expressions/">expression</a>'
|
|
272
|
+
},
|
|
273
|
+
{
|
|
274
|
+
displayName: "Group Policy",
|
|
275
|
+
name: "groupPolicy",
|
|
276
|
+
type: "options",
|
|
277
|
+
default: "allowlist",
|
|
278
|
+
description: "Group message policy for this Telegram channel",
|
|
279
|
+
options: [
|
|
280
|
+
{ name: "Allowlist", value: "allowlist" },
|
|
281
|
+
{ name: "Open", value: "open" },
|
|
282
|
+
{ name: "Disabled", value: "disabled" }
|
|
283
|
+
]
|
|
284
|
+
}
|
|
285
|
+
]
|
|
286
|
+
};
|
|
287
|
+
this.methods = {
|
|
288
|
+
loadOptions: {
|
|
289
|
+
async getAllowFromOptions() {
|
|
290
|
+
const accountId = normalizeOpenClawAccountId(this.getCurrentNodeParameter("accountId"));
|
|
291
|
+
return getTelegramAllowFromOptions(accountId);
|
|
292
|
+
}
|
|
293
|
+
}
|
|
294
|
+
};
|
|
295
|
+
}
|
|
296
|
+
async supplyData(itemIndex) {
|
|
297
|
+
const credentials = await this.getCredentials(
|
|
298
|
+
TELEGRAM_CREDENTIAL_TYPE,
|
|
299
|
+
itemIndex
|
|
300
|
+
);
|
|
301
|
+
const botToken = credentials.accessToken?.trim();
|
|
302
|
+
const accountId = this.getNodeParameter("accountId", itemIndex, "").trim() || void 0;
|
|
303
|
+
const dmPolicy = this.getNodeParameter("dmPolicy", itemIndex, "pairing");
|
|
304
|
+
const allowFrom = normalizeAllowFromEntries(this.getNodeParameter("allowFrom", itemIndex, []));
|
|
305
|
+
const groupPolicy = this.getNodeParameter("groupPolicy", itemIndex, "allowlist");
|
|
306
|
+
console.log("[TelegramChannel] supplyData resolved channel config", {
|
|
307
|
+
itemIndex,
|
|
308
|
+
hasBotToken: !!botToken,
|
|
309
|
+
accountId: accountId ?? OPENCLAW_DEFAULT_ACCOUNT_ID,
|
|
310
|
+
dmPolicy,
|
|
311
|
+
groupPolicy,
|
|
312
|
+
allowFromCount: allowFrom.length
|
|
313
|
+
});
|
|
314
|
+
const channelConfig = {
|
|
315
|
+
channelType: "telegram",
|
|
316
|
+
botToken,
|
|
317
|
+
accountId,
|
|
318
|
+
dmPolicy,
|
|
319
|
+
allowFrom,
|
|
320
|
+
groupPolicy
|
|
321
|
+
};
|
|
322
|
+
return { response: channelConfig };
|
|
323
|
+
}
|
|
324
|
+
}
|
|
325
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
326
|
+
0 && (module.exports = {
|
|
327
|
+
TelegramChannel
|
|
328
|
+
});
|
|
329
|
+
//# sourceMappingURL=TelegramChannel.node.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../../../../nodes/agents/OpenClawAgent/channels/TelegramChannel/TelegramChannel.node.ts"],"sourcesContent":["import { existsSync, readFileSync, statSync } from 'fs';\nimport { join } from 'path';\n\nimport {\n\tNodeConnectionTypes,\n\ttype ILoadOptionsFunctions,\n\ttype INodeType,\n\ttype INodeTypeDescription,\n\ttype INodePropertyOptions,\n\ttype ISupplyDataFunctions,\n\ttype SupplyData,\n} from 'n8n-workflow';\n\nimport type { ChannelConfig } from '../../V2/OpenClawAgentV2.node';\n\nconst TELEGRAM_CREDENTIAL_TYPE = 'telegramApi';\nconst OPENCLAW_STATE_DIR_ENV = 'OPENCLAW_STATE_DIR';\nconst OPENCLAW_OAUTH_DIR_ENV = 'OPENCLAW_OAUTH_DIR';\nconst OPENCLAW_DEFAULT_ACCOUNT_ID = 'default';\n\nfunction isObject(value: unknown): value is Record<string, unknown> {\n\treturn typeof value === 'object' && value !== null && !Array.isArray(value);\n}\n\nfunction normalizeOptionalString(value: unknown): string | undefined {\n\tif (typeof value === 'number' && Number.isFinite(value)) {\n\t\treturn String(value);\n\t}\n\tif (typeof value !== 'string') {\n\t\treturn undefined;\n\t}\n\tconst trimmed = value.trim();\n\treturn trimmed || undefined;\n}\n\nfunction normalizeTelegramAllowFromEntry(value: unknown): string | undefined {\n\tconst raw = normalizeOptionalString(value);\n\tif (!raw) {\n\t\treturn undefined;\n\t}\n\tconst normalized = raw.replace(/^(telegram|tg):/i, '').trim();\n\treturn normalized || undefined;\n}\n\nfunction normalizeAllowFromEntries(value: unknown): string[] {\n\tconst rawEntries = Array.isArray(value)\n\t\t? value\n\t\t: typeof value === 'string'\n\t\t\t? value.split(/[\\n,]/)\n\t\t\t: [];\n\tconst seen = new Set<string>();\n\tconst entries: string[] = [];\n\tfor (const rawEntry of rawEntries) {\n\t\tconst entry = normalizeTelegramAllowFromEntry(rawEntry);\n\t\tif (!entry || seen.has(entry)) {\n\t\t\tcontinue;\n\t\t}\n\t\tseen.add(entry);\n\t\tentries.push(entry);\n\t}\n\treturn entries;\n}\n\nfunction getHomeDirectory(): string | undefined {\n\treturn (\n\t\tnormalizeOptionalString(process.env.HOME) ?? normalizeOptionalString(process.env.USERPROFILE)\n\t);\n}\n\nfunction resolveOpenClawStateDir(): string | undefined {\n\tconst stateDir = normalizeOptionalString(process.env[OPENCLAW_STATE_DIR_ENV]);\n\tif (stateDir) {\n\t\treturn stateDir;\n\t}\n\tconst home = getHomeDirectory();\n\treturn home ? join(home, '.openclaw') : undefined;\n}\n\nfunction resolveOpenClawCredentialsDir(): string | undefined {\n\tconst oauthDir = normalizeOptionalString(process.env[OPENCLAW_OAUTH_DIR_ENV]);\n\tif (oauthDir) {\n\t\treturn oauthDir;\n\t}\n\tconst stateDir = resolveOpenClawStateDir();\n\treturn stateDir ? join(stateDir, 'credentials') : undefined;\n}\n\nfunction normalizeOpenClawAccountId(value: unknown): string {\n\tconst accountId = normalizeOptionalString(value)?.toLowerCase();\n\treturn accountId || OPENCLAW_DEFAULT_ACCOUNT_ID;\n}\n\nfunction safeFilenameKey(value: string): string {\n\treturn value\n\t\t.trim()\n\t\t.toLowerCase()\n\t\t.replace(/[\\\\/:*?\"<>|]/g, '_')\n\t\t.replace(/\\.\\./g, '_');\n}\n\nfunction getTelegramPairingPath(credentialsDir: string): string {\n\treturn join(credentialsDir, 'telegram-pairing.json');\n}\n\nfunction getTelegramAllowFromPaths(credentialsDir: string, accountId: string): string[] {\n\tconst accountPath = join(credentialsDir, `telegram-${safeFilenameKey(accountId)}-allowFrom.json`);\n\tif (accountId === OPENCLAW_DEFAULT_ACCOUNT_ID) {\n\t\treturn [accountPath, join(credentialsDir, 'telegram-allowFrom.json')];\n\t}\n\treturn [accountPath];\n}\n\nfunction readJsonFile(filePath: string): unknown | undefined {\n\ttry {\n\t\tif (!existsSync(filePath) || !statSync(filePath).isFile()) {\n\t\t\treturn undefined;\n\t\t}\n\t\treturn JSON.parse(readFileSync(filePath, 'utf8'));\n\t} catch (error) {\n\t\tconsole.log('[TelegramChannel] Failed to read Allow From source file', {\n\t\t\tfilePath,\n\t\t\terror: error instanceof Error ? error.message : String(error),\n\t\t});\n\t\treturn undefined;\n\t}\n}\n\nfunction getMetaString(meta: unknown, key: string): string | undefined {\n\treturn isObject(meta) ? normalizeOptionalString(meta[key]) : undefined;\n}\n\nfunction formatPairingOptionName(request: Record<string, unknown>): string {\n\tconst id = normalizeTelegramAllowFromEntry(request.id) ?? 'Unknown sender';\n\tconst meta = request.meta;\n\tconst username = getMetaString(meta, 'username');\n\tconst firstName = getMetaString(meta, 'firstName');\n\tconst lastName = getMetaString(meta, 'lastName');\n\tconst fullName = [firstName, lastName].filter(Boolean).join(' ');\n\tconst labelParts = [username ? `@${username}` : undefined, fullName || undefined].filter(Boolean);\n\treturn labelParts.length > 0 ? `${id} (${labelParts.join(', ')})` : id;\n}\n\nfunction addOption(\n\toptions: INodePropertyOptions[],\n\tseen: Set<string>,\n\toption: INodePropertyOptions,\n): void {\n\tconst value = String(option.value);\n\tif (seen.has(value)) {\n\t\treturn;\n\t}\n\tseen.add(value);\n\toptions.push(option);\n}\n\nfunction getTelegramAllowFromOptions(accountId: string): INodePropertyOptions[] {\n\tconst credentialsDir = resolveOpenClawCredentialsDir();\n\tif (!credentialsDir) {\n\t\tconsole.log('[TelegramChannel] Allow From options skipped: OpenClaw credentials dir unknown', {\n\t\t\taccountId,\n\t\t});\n\t\treturn [];\n\t}\n\n\tconst pairingPath = getTelegramPairingPath(credentialsDir);\n\tconst allowFromPaths = getTelegramAllowFromPaths(credentialsDir, accountId);\n\tconsole.log('[TelegramChannel] Loading Allow From options', {\n\t\taccountId,\n\t\tcredentialsDir,\n\t\tpairingPath,\n\t\tallowFromPaths,\n\t});\n\n\tconst options: INodePropertyOptions[] = [];\n\tconst seen = new Set<string>();\n\tconst pairingStore = readJsonFile(pairingPath);\n\tconst requests =\n\t\tisObject(pairingStore) && Array.isArray(pairingStore.requests) ? pairingStore.requests : [];\n\tlet pairingOptionCount = 0;\n\n\tfor (const request of requests) {\n\t\tif (!isObject(request)) {\n\t\t\tcontinue;\n\t\t}\n\t\tconst id = normalizeTelegramAllowFromEntry(request.id);\n\t\tif (!id) {\n\t\t\tcontinue;\n\t\t}\n\t\tconst requestAccountId = normalizeOpenClawAccountId(getMetaString(request.meta, 'accountId'));\n\t\tif (requestAccountId !== accountId) {\n\t\t\tcontinue;\n\t\t}\n\t\taddOption(options, seen, {\n\t\t\tname: formatPairingOptionName(request),\n\t\t\tvalue: id,\n\t\t\tdescription: `Pending Telegram pairing request from ${pairingPath}`,\n\t\t});\n\t\tpairingOptionCount++;\n\t}\n\n\tlet allowFromOptionCount = 0;\n\tfor (const allowFromPath of allowFromPaths) {\n\t\tconst allowFromStore = readJsonFile(allowFromPath);\n\t\tconst entries =\n\t\t\tisObject(allowFromStore) && Array.isArray(allowFromStore.allowFrom)\n\t\t\t\t? normalizeAllowFromEntries(allowFromStore.allowFrom)\n\t\t\t\t: [];\n\t\tfor (const entry of entries) {\n\t\t\taddOption(options, seen, {\n\t\t\t\tname: `${entry} (Configured)`,\n\t\t\t\tvalue: entry,\n\t\t\t\tdescription: `Existing Telegram allowFrom entry from ${allowFromPath}`,\n\t\t\t});\n\t\t\tallowFromOptionCount++;\n\t\t}\n\t}\n\n\tconsole.log('[TelegramChannel] Loaded Allow From options', {\n\t\taccountId,\n\t\toptionCount: options.length,\n\t\tpairingOptionCount,\n\t\tallowFromOptionCount,\n\t});\n\treturn options;\n}\n\nexport class TelegramChannel implements INodeType {\n\tdescription: INodeTypeDescription = {\n\t\tdisplayName: 'Telegram Channel',\n\t\tname: 'openClawTelegramChannel',\n\t\ticon: 'file:telegram-channel.svg',\n\t\ticonColor: 'blue',\n\t\tgroup: ['transform'],\n\t\tversion: 1,\n\t\tdescription: 'Provides Telegram channel configuration to an OpenClaw AI Agent',\n\t\tdefaults: {\n\t\t\tname: 'Telegram Channel',\n\t\t},\n\t\tcodex: {\n\t\t\talias: ['Telegram', 'Channel', 'Bot', 'OpenClaw'],\n\t\t\tcategories: ['AI'],\n\t\t\tsubcategories: {\n\t\t\t\tAI: ['Other'],\n\t\t\t},\n\t\t\tresources: {\n\t\t\t\tprimaryDocumentation: [\n\t\t\t\t\t{\n\t\t\t\t\t\turl: 'https://docs.openclaw.ai/channels/telegram',\n\t\t\t\t\t},\n\t\t\t\t],\n\t\t\t},\n\t\t},\n\t\tinputs: [],\n\t\toutputs: [NodeConnectionTypes.AiChannel],\n\t\toutputNames: ['Channel'],\n\t\tcredentials: [\n\t\t\t{\n\t\t\t\tname: TELEGRAM_CREDENTIAL_TYPE,\n\t\t\t\trequired: true,\n\t\t\t},\n\t\t],\n\t\tproperties: [\n\t\t\t{\n\t\t\t\tdisplayName:\n\t\t\t\t\t'Connect this node to an OpenClaw AI Agent to provide Telegram channel configuration. The bot token is read from the Telegram credential.',\n\t\t\t\tname: 'telegramNotice',\n\t\t\t\ttype: 'notice',\n\t\t\t\tdefault: '',\n\t\t\t},\n\t\t\t{\n\t\t\t\tdisplayName: 'Account ID',\n\t\t\t\tname: 'accountId',\n\t\t\t\ttype: 'string',\n\t\t\t\tdefault: '',\n\t\t\t\tdescription:\n\t\t\t\t\t'Optional OpenClaw account ID for multi-account setups. Leave empty for the default account.',\n\t\t\t},\n\t\t\t{\n\t\t\t\tdisplayName: 'DM Policy',\n\t\t\t\tname: 'dmPolicy',\n\t\t\t\ttype: 'options',\n\t\t\t\tdefault: 'pairing',\n\t\t\t\tdescription: 'Direct message policy for this Telegram channel',\n\t\t\t\toptions: [\n\t\t\t\t\t{ name: 'Pairing', value: 'pairing' },\n\t\t\t\t\t{ name: 'Open', value: 'open' },\n\t\t\t\t\t{ name: 'Allowlist', value: 'allowlist' },\n\t\t\t\t\t{ name: 'Disabled', value: 'disabled' },\n\t\t\t\t],\n\t\t\t},\n\t\t\t{\n\t\t\t\tdisplayName: 'Allow From Names or IDs',\n\t\t\t\tname: 'allowFrom',\n\t\t\t\ttype: 'multiOptions',\n\t\t\t\ttypeOptions: {\n\t\t\t\t\tloadOptionsMethod: 'getAllowFromOptions',\n\t\t\t\t\tloadOptionsDependsOn: ['accountId'],\n\t\t\t\t},\n\t\t\t\tdefault: [],\n\t\t\t\tallowArbitraryValues: true,\n\t\t\t\tdescription:\n\t\t\t\t\t'Choose from the list, or specify IDs using an <a href=\"https://docs.n8n.io/code/expressions/\">expression</a>',\n\t\t\t},\n\t\t\t{\n\t\t\t\tdisplayName: 'Group Policy',\n\t\t\t\tname: 'groupPolicy',\n\t\t\t\ttype: 'options',\n\t\t\t\tdefault: 'allowlist',\n\t\t\t\tdescription: 'Group message policy for this Telegram channel',\n\t\t\t\toptions: [\n\t\t\t\t\t{ name: 'Allowlist', value: 'allowlist' },\n\t\t\t\t\t{ name: 'Open', value: 'open' },\n\t\t\t\t\t{ name: 'Disabled', value: 'disabled' },\n\t\t\t\t],\n\t\t\t},\n\t\t],\n\t};\n\n\tasync supplyData(this: ISupplyDataFunctions, itemIndex: number): Promise<SupplyData> {\n\t\tconst credentials = await this.getCredentials<{ accessToken?: string }>(\n\t\t\tTELEGRAM_CREDENTIAL_TYPE,\n\t\t\titemIndex,\n\t\t);\n\n\t\tconst botToken = credentials.accessToken?.trim();\n\t\tconst accountId =\n\t\t\t(this.getNodeParameter('accountId', itemIndex, '') as string).trim() || undefined;\n\t\tconst dmPolicy = this.getNodeParameter('dmPolicy', itemIndex, 'pairing') as string;\n\t\tconst allowFrom = normalizeAllowFromEntries(this.getNodeParameter('allowFrom', itemIndex, []));\n\t\tconst groupPolicy = this.getNodeParameter('groupPolicy', itemIndex, 'allowlist') as string;\n\n\t\tconsole.log('[TelegramChannel] supplyData resolved channel config', {\n\t\t\titemIndex,\n\t\t\thasBotToken: !!botToken,\n\t\t\taccountId: accountId ?? OPENCLAW_DEFAULT_ACCOUNT_ID,\n\t\t\tdmPolicy,\n\t\t\tgroupPolicy,\n\t\t\tallowFromCount: allowFrom.length,\n\t\t});\n\n\t\tconst channelConfig: ChannelConfig = {\n\t\t\tchannelType: 'telegram',\n\t\t\tbotToken,\n\t\t\taccountId,\n\t\t\tdmPolicy,\n\t\t\tallowFrom,\n\t\t\tgroupPolicy,\n\t\t};\n\n\t\treturn { response: channelConfig };\n\t}\n\n\tmethods = {\n\t\tloadOptions: {\n\t\t\tasync getAllowFromOptions(this: ILoadOptionsFunctions): Promise<INodePropertyOptions[]> {\n\t\t\t\tconst accountId = normalizeOpenClawAccountId(this.getCurrentNodeParameter('accountId'));\n\t\t\t\treturn getTelegramAllowFromOptions(accountId);\n\t\t\t},\n\t\t},\n\t};\n}\n"],"mappings":"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","names":[]}
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
+
var __export = (target, all) => {
|
|
7
|
+
for (var name in all)
|
|
8
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
9
|
+
};
|
|
10
|
+
var __copyProps = (to, from, except, desc) => {
|
|
11
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
12
|
+
for (let key of __getOwnPropNames(from))
|
|
13
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
14
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
15
|
+
}
|
|
16
|
+
return to;
|
|
17
|
+
};
|
|
18
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
|
+
var WhatsAppChannel_node_exports = {};
|
|
20
|
+
__export(WhatsAppChannel_node_exports, {
|
|
21
|
+
WhatsAppChannel: () => WhatsAppChannel
|
|
22
|
+
});
|
|
23
|
+
module.exports = __toCommonJS(WhatsAppChannel_node_exports);
|
|
24
|
+
var import_n8n_workflow = require("n8n-workflow");
|
|
25
|
+
const WHATSAPP_CREDENTIAL_TYPE = "whatsAppBusinessApi";
|
|
26
|
+
class WhatsAppChannel {
|
|
27
|
+
constructor() {
|
|
28
|
+
this.description = {
|
|
29
|
+
displayName: "WhatsApp Channel",
|
|
30
|
+
name: "openClawWhatsAppChannel",
|
|
31
|
+
icon: "file:whatsapp-channel.svg",
|
|
32
|
+
iconColor: "green",
|
|
33
|
+
group: ["transform"],
|
|
34
|
+
version: 1,
|
|
35
|
+
description: "Provides WhatsApp channel configuration to an OpenClaw AI Agent",
|
|
36
|
+
defaults: {
|
|
37
|
+
name: "WhatsApp Channel"
|
|
38
|
+
},
|
|
39
|
+
codex: {
|
|
40
|
+
alias: ["WhatsApp", "Channel", "OpenClaw"],
|
|
41
|
+
categories: ["AI"],
|
|
42
|
+
subcategories: {
|
|
43
|
+
AI: ["Other"]
|
|
44
|
+
},
|
|
45
|
+
resources: {
|
|
46
|
+
primaryDocumentation: [
|
|
47
|
+
{
|
|
48
|
+
url: "https://docs.openclaw.ai/channels/whatsapp"
|
|
49
|
+
}
|
|
50
|
+
]
|
|
51
|
+
}
|
|
52
|
+
},
|
|
53
|
+
inputs: [],
|
|
54
|
+
outputs: [import_n8n_workflow.NodeConnectionTypes.AiChannel],
|
|
55
|
+
outputNames: ["Channel"],
|
|
56
|
+
credentials: [
|
|
57
|
+
{
|
|
58
|
+
name: WHATSAPP_CREDENTIAL_TYPE,
|
|
59
|
+
required: true
|
|
60
|
+
}
|
|
61
|
+
],
|
|
62
|
+
properties: [
|
|
63
|
+
{
|
|
64
|
+
displayName: "Connect this node to an OpenClaw AI Agent to provide WhatsApp channel configuration.",
|
|
65
|
+
name: "whatsappNotice",
|
|
66
|
+
type: "notice",
|
|
67
|
+
default: ""
|
|
68
|
+
},
|
|
69
|
+
{
|
|
70
|
+
displayName: "Phone Number ID",
|
|
71
|
+
name: "phoneNumberId",
|
|
72
|
+
type: "string",
|
|
73
|
+
default: "",
|
|
74
|
+
required: true,
|
|
75
|
+
description: "WhatsApp Business phone number ID"
|
|
76
|
+
},
|
|
77
|
+
{
|
|
78
|
+
displayName: "Account ID",
|
|
79
|
+
name: "accountId",
|
|
80
|
+
type: "string",
|
|
81
|
+
default: "",
|
|
82
|
+
description: "Optional OpenClaw account ID for multi-account setups. Leave empty for the default account."
|
|
83
|
+
}
|
|
84
|
+
]
|
|
85
|
+
};
|
|
86
|
+
}
|
|
87
|
+
async supplyData(itemIndex) {
|
|
88
|
+
const credentials = await this.getCredentials(
|
|
89
|
+
WHATSAPP_CREDENTIAL_TYPE,
|
|
90
|
+
itemIndex
|
|
91
|
+
);
|
|
92
|
+
const accessToken = credentials.accessToken?.trim();
|
|
93
|
+
const phoneNumberId = this.getNodeParameter("phoneNumberId", itemIndex, "").trim();
|
|
94
|
+
const accountId = this.getNodeParameter("accountId", itemIndex, "").trim() || void 0;
|
|
95
|
+
const channelConfig = {
|
|
96
|
+
channelType: "whatsapp",
|
|
97
|
+
accessToken,
|
|
98
|
+
phoneNumberId,
|
|
99
|
+
accountId
|
|
100
|
+
};
|
|
101
|
+
return { response: channelConfig };
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
105
|
+
0 && (module.exports = {
|
|
106
|
+
WhatsAppChannel
|
|
107
|
+
});
|
|
108
|
+
//# sourceMappingURL=WhatsAppChannel.node.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../../../../nodes/agents/OpenClawAgent/channels/WhatsAppChannel/WhatsAppChannel.node.ts"],"sourcesContent":["import {\n\tNodeConnectionTypes,\n\ttype INodeType,\n\ttype INodeTypeDescription,\n\ttype ISupplyDataFunctions,\n\ttype SupplyData,\n} from 'n8n-workflow';\n\nimport type { ChannelConfig } from '../../V2/OpenClawAgentV2.node';\n\nconst WHATSAPP_CREDENTIAL_TYPE = 'whatsAppBusinessApi';\n\nexport class WhatsAppChannel implements INodeType {\n\tdescription: INodeTypeDescription = {\n\t\tdisplayName: 'WhatsApp Channel',\n\t\tname: 'openClawWhatsAppChannel',\n\t\ticon: 'file:whatsapp-channel.svg',\n\t\ticonColor: 'green',\n\t\tgroup: ['transform'],\n\t\tversion: 1,\n\t\tdescription: 'Provides WhatsApp channel configuration to an OpenClaw AI Agent',\n\t\tdefaults: {\n\t\t\tname: 'WhatsApp Channel',\n\t\t},\n\t\tcodex: {\n\t\t\talias: ['WhatsApp', 'Channel', 'OpenClaw'],\n\t\t\tcategories: ['AI'],\n\t\t\tsubcategories: {\n\t\t\t\tAI: ['Other'],\n\t\t\t},\n\t\t\tresources: {\n\t\t\t\tprimaryDocumentation: [\n\t\t\t\t\t{\n\t\t\t\t\t\turl: 'https://docs.openclaw.ai/channels/whatsapp',\n\t\t\t\t\t},\n\t\t\t\t],\n\t\t\t},\n\t\t},\n\t\tinputs: [],\n\t\toutputs: [NodeConnectionTypes.AiChannel],\n\t\toutputNames: ['Channel'],\n\t\tcredentials: [\n\t\t\t{\n\t\t\t\tname: WHATSAPP_CREDENTIAL_TYPE,\n\t\t\t\trequired: true,\n\t\t\t},\n\t\t],\n\t\tproperties: [\n\t\t\t{\n\t\t\t\tdisplayName:\n\t\t\t\t\t'Connect this node to an OpenClaw AI Agent to provide WhatsApp channel configuration.',\n\t\t\t\tname: 'whatsappNotice',\n\t\t\t\ttype: 'notice',\n\t\t\t\tdefault: '',\n\t\t\t},\n\t\t\t{\n\t\t\t\tdisplayName: 'Phone Number ID',\n\t\t\t\tname: 'phoneNumberId',\n\t\t\t\ttype: 'string',\n\t\t\t\tdefault: '',\n\t\t\t\trequired: true,\n\t\t\t\tdescription: 'WhatsApp Business phone number ID',\n\t\t\t},\n\t\t\t{\n\t\t\t\tdisplayName: 'Account ID',\n\t\t\t\tname: 'accountId',\n\t\t\t\ttype: 'string',\n\t\t\t\tdefault: '',\n\t\t\t\tdescription:\n\t\t\t\t\t'Optional OpenClaw account ID for multi-account setups. Leave empty for the default account.',\n\t\t\t},\n\t\t],\n\t};\n\n\tasync supplyData(this: ISupplyDataFunctions, itemIndex: number): Promise<SupplyData> {\n\t\tconst credentials = await this.getCredentials<{ accessToken?: string }>(\n\t\t\tWHATSAPP_CREDENTIAL_TYPE,\n\t\t\titemIndex,\n\t\t);\n\n\t\tconst accessToken = credentials.accessToken?.trim();\n\t\tconst phoneNumberId = (this.getNodeParameter('phoneNumberId', itemIndex, '') as string).trim();\n\t\tconst accountId =\n\t\t\t(this.getNodeParameter('accountId', itemIndex, '') as string).trim() || undefined;\n\n\t\tconst channelConfig: ChannelConfig = {\n\t\t\tchannelType: 'whatsapp',\n\t\t\taccessToken,\n\t\t\tphoneNumberId,\n\t\t\taccountId,\n\t\t};\n\n\t\treturn { response: channelConfig };\n\t}\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,0BAMO;AAIP,MAAM,2BAA2B;AAE1B,MAAM,gBAAqC;AAAA,EAA3C;AACN,uBAAoC;AAAA,MACnC,aAAa;AAAA,MACb,MAAM;AAAA,MACN,MAAM;AAAA,MACN,WAAW;AAAA,MACX,OAAO,CAAC,WAAW;AAAA,MACnB,SAAS;AAAA,MACT,aAAa;AAAA,MACb,UAAU;AAAA,QACT,MAAM;AAAA,MACP;AAAA,MACA,OAAO;AAAA,QACN,OAAO,CAAC,YAAY,WAAW,UAAU;AAAA,QACzC,YAAY,CAAC,IAAI;AAAA,QACjB,eAAe;AAAA,UACd,IAAI,CAAC,OAAO;AAAA,QACb;AAAA,QACA,WAAW;AAAA,UACV,sBAAsB;AAAA,YACrB;AAAA,cACC,KAAK;AAAA,YACN;AAAA,UACD;AAAA,QACD;AAAA,MACD;AAAA,MACA,QAAQ,CAAC;AAAA,MACT,SAAS,CAAC,wCAAoB,SAAS;AAAA,MACvC,aAAa,CAAC,SAAS;AAAA,MACvB,aAAa;AAAA,QACZ;AAAA,UACC,MAAM;AAAA,UACN,UAAU;AAAA,QACX;AAAA,MACD;AAAA,MACA,YAAY;AAAA,QACX;AAAA,UACC,aACC;AAAA,UACD,MAAM;AAAA,UACN,MAAM;AAAA,UACN,SAAS;AAAA,QACV;AAAA,QACA;AAAA,UACC,aAAa;AAAA,UACb,MAAM;AAAA,UACN,MAAM;AAAA,UACN,SAAS;AAAA,UACT,UAAU;AAAA,UACV,aAAa;AAAA,QACd;AAAA,QACA;AAAA,UACC,aAAa;AAAA,UACb,MAAM;AAAA,UACN,MAAM;AAAA,UACN,SAAS;AAAA,UACT,aACC;AAAA,QACF;AAAA,MACD;AAAA,IACD;AAAA;AAAA,EAEA,MAAM,WAAuC,WAAwC;AACpF,UAAM,cAAc,MAAM,KAAK;AAAA,MAC9B;AAAA,MACA;AAAA,IACD;AAEA,UAAM,cAAc,YAAY,aAAa,KAAK;AAClD,UAAM,gBAAiB,KAAK,iBAAiB,iBAAiB,WAAW,EAAE,EAAa,KAAK;AAC7F,UAAM,YACJ,KAAK,iBAAiB,aAAa,WAAW,EAAE,EAAa,KAAK,KAAK;AAEzE,UAAM,gBAA+B;AAAA,MACpC,aAAa;AAAA,MACb;AAAA,MACA;AAAA,MACA;AAAA,IACD;AAEA,WAAO,EAAE,UAAU,cAAc;AAAA,EAClC;AACD;","names":[]}
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
|
|
2
|
+
<path d="M21 11.5a8.38 8.38 0 0 1-.9 3.8 8.5 8.5 0 0 1-7.6 4.7 8.38 8.38 0 0 1-3.8-.9L3 21l1.9-5.7a8.38 8.38 0 0 1-.9-3.8 8.5 8.5 0 0 1 4.7-7.6 8.38 8.38 0 0 1 3.8-.9h.5a8.48 8.48 0 0 1 8 8v.5z"/>
|
|
3
|
+
</svg>
|