@automagik/omni 2.261006.2 → 2.261008.2
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/index.js +1 -1
- package/dist/server/index.js +351 -24
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -137462,7 +137462,7 @@ import { fileURLToPath } from "url";
|
|
|
137462
137462
|
// package.json
|
|
137463
137463
|
var package_default = {
|
|
137464
137464
|
name: "@automagik/omni",
|
|
137465
|
-
version: "2.
|
|
137465
|
+
version: "2.261008.2",
|
|
137466
137466
|
repository: {
|
|
137467
137467
|
type: "git",
|
|
137468
137468
|
url: "git+https://github.com/automagik-dev/omni.git",
|
package/dist/server/index.js
CHANGED
|
@@ -266444,7 +266444,7 @@ var init_sentry_scrub = __esm(() => {
|
|
|
266444
266444
|
var require_package7 = __commonJS((exports, module) => {
|
|
266445
266445
|
module.exports = {
|
|
266446
266446
|
name: "@omni/api",
|
|
266447
|
-
version: "2.
|
|
266447
|
+
version: "2.261008.2",
|
|
266448
266448
|
private: true,
|
|
266449
266449
|
type: "module",
|
|
266450
266450
|
exports: {
|
|
@@ -266504,6 +266504,7 @@ var require_package7 = __commonJS((exports, module) => {
|
|
|
266504
266504
|
"@asteasolutions/zod-to-openapi": "7.3.4",
|
|
266505
266505
|
"@types/qrcode-terminal": "^0.12.2",
|
|
266506
266506
|
"@types/bun": "1.3.14",
|
|
266507
|
+
baileys: "file:../channel-whatsapp/vendor/baileys-v7.0.0-rc14.tgz",
|
|
266507
266508
|
"openapi3-ts": "^4.5.0",
|
|
266508
266509
|
"qrcode-terminal": "^0.12.0",
|
|
266509
266510
|
typescript: "^5.7.3"
|
|
@@ -327263,7 +327264,7 @@ var init_worker_tenant_context = __esm(() => {
|
|
|
327263
327264
|
});
|
|
327264
327265
|
|
|
327265
327266
|
// ../api/src/middleware/config-audit.ts
|
|
327266
|
-
import { createHash as
|
|
327267
|
+
import { createHash as createHash13 } from "crypto";
|
|
327267
327268
|
function resolveTarget(method, path2) {
|
|
327268
327269
|
const rel = path2.replace(/^\/api\/v2/, "").replace(/\/$/, "");
|
|
327269
327270
|
for (const resource of RESOURCES) {
|
|
@@ -327277,7 +327278,7 @@ function resolveTarget(method, path2) {
|
|
|
327277
327278
|
return null;
|
|
327278
327279
|
}
|
|
327279
327280
|
function fingerprint(value) {
|
|
327280
|
-
return `sha256:${
|
|
327281
|
+
return `sha256:${createHash13("sha256").update(JSON.stringify(value)).digest("hex").slice(0, 12)}`;
|
|
327281
327282
|
}
|
|
327282
327283
|
function redactSecrets2(value, keyName = "") {
|
|
327283
327284
|
if (value === null || value === undefined)
|
|
@@ -327612,9 +327613,9 @@ var init_body_limit2 = __esm(() => {
|
|
|
327612
327613
|
});
|
|
327613
327614
|
|
|
327614
327615
|
// ../api/src/middleware/genie-signature.ts
|
|
327615
|
-
import { createHash as
|
|
327616
|
+
import { createHash as createHash14, createPublicKey, verify } from "crypto";
|
|
327616
327617
|
function canonicalSigningInput(timestamp3, method, path2, body) {
|
|
327617
|
-
const bodyHash =
|
|
327618
|
+
const bodyHash = createHash14("sha256").update(body, "utf-8").digest("hex");
|
|
327618
327619
|
return `${timestamp3}
|
|
327619
327620
|
${method.toUpperCase()}
|
|
327620
327621
|
${path2}
|
|
@@ -327882,12 +327883,12 @@ var init_profiles = __esm(() => {
|
|
|
327882
327883
|
});
|
|
327883
327884
|
|
|
327884
327885
|
// ../api/src/middleware/output-redactor.ts
|
|
327885
|
-
import { createHash as
|
|
327886
|
+
import { createHash as createHash15 } from "crypto";
|
|
327886
327887
|
function escapeRegex(literal2) {
|
|
327887
327888
|
return literal2.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
327888
327889
|
}
|
|
327889
327890
|
function hashPattern(source) {
|
|
327890
|
-
return
|
|
327891
|
+
return createHash15("sha256").update(source).digest("hex").slice(0, 12);
|
|
327891
327892
|
}
|
|
327892
327893
|
function compilePatterns(literals) {
|
|
327893
327894
|
const out = [];
|
|
@@ -328137,6 +328138,12 @@ var DEFAULT_TURN_SCOPES, SCOPE_MAP;
|
|
|
328137
328138
|
var init_scopes = __esm(() => {
|
|
328138
328139
|
DEFAULT_TURN_SCOPES = ["messages:send", "turns:close", "tts:synthesize", "context:read"];
|
|
328139
328140
|
SCOPE_MAP = {
|
|
328141
|
+
"GET /instances/:id/self": "instances:read",
|
|
328142
|
+
"GET /instances/:id/self/chats": "messages:selected:read",
|
|
328143
|
+
"POST /instances/:id/self/messages": "messages:self:read",
|
|
328144
|
+
"POST /instances/:id/self/receipt": "messages:self:read",
|
|
328145
|
+
"POST /instances/:id/self/history": "messages:selected:read",
|
|
328146
|
+
"POST /messages/send-self": "messages:self:send",
|
|
328140
328147
|
"GET /audit": "audit:read",
|
|
328141
328148
|
"GET /audit/:id": "audit:read",
|
|
328142
328149
|
"GET /a2a/agents": "agents:read",
|
|
@@ -329153,6 +329160,8 @@ var init_route_ownership = __esm(() => {
|
|
|
329153
329160
|
"GET /api/v2/instances/:id/passkey",
|
|
329154
329161
|
"GET /api/v2/instances/:id/privacy",
|
|
329155
329162
|
"GET /api/v2/instances/:id/qr",
|
|
329163
|
+
"GET /api/v2/instances/:id/self",
|
|
329164
|
+
"GET /api/v2/instances/:id/self/chats",
|
|
329156
329165
|
"GET /api/v2/instances/:id/status",
|
|
329157
329166
|
"GET /api/v2/instances/:id/sync",
|
|
329158
329167
|
"GET /api/v2/instances/:id/sync/:jobId",
|
|
@@ -329236,6 +329245,10 @@ var init_route_ownership = __esm(() => {
|
|
|
329236
329245
|
"POST /api/v2/:id/test",
|
|
329237
329246
|
"POST /api/v2/access/check",
|
|
329238
329247
|
"POST /api/v2/access/rules",
|
|
329248
|
+
"POST /api/v2/instances/:id/self/history",
|
|
329249
|
+
"POST /api/v2/instances/:id/self/messages",
|
|
329250
|
+
"POST /api/v2/instances/:id/self/receipt",
|
|
329251
|
+
"POST /api/v2/messages/send-self",
|
|
329239
329252
|
"POST /api/v2/agent-tasks",
|
|
329240
329253
|
"POST /api/v2/agents",
|
|
329241
329254
|
"POST /api/v2/agents/:id/identities/link",
|
|
@@ -329462,6 +329475,10 @@ var init_route_ownership = __esm(() => {
|
|
|
329462
329475
|
|
|
329463
329476
|
// ../api/src/tenancy/scope-projection.ts
|
|
329464
329477
|
function classifyLegacyScope(scope) {
|
|
329478
|
+
if (scope === "messages:self:read" || scope === "messages:selected:read")
|
|
329479
|
+
return "read";
|
|
329480
|
+
if (scope === "messages:self:send")
|
|
329481
|
+
return "write";
|
|
329465
329482
|
const verb = scope.split(":")[1];
|
|
329466
329483
|
if (verb === undefined)
|
|
329467
329484
|
return null;
|
|
@@ -330701,7 +330718,7 @@ var require_gaxios = __commonJS((exports) => {
|
|
|
330701
330718
|
var retry_js_1 = require_retry2();
|
|
330702
330719
|
var stream_1 = __require("stream");
|
|
330703
330720
|
var interceptor_js_1 = require_interceptor();
|
|
330704
|
-
var
|
|
330721
|
+
var randomUUID3 = async () => globalThis.crypto?.randomUUID() || (await import("crypto")).randomUUID();
|
|
330705
330722
|
var HTTP_STATUS_NO_CONTENT = 204;
|
|
330706
330723
|
|
|
330707
330724
|
class Gaxios {
|
|
@@ -330912,7 +330929,7 @@ var require_gaxios = __commonJS((exports) => {
|
|
|
330912
330929
|
}
|
|
330913
330930
|
const shouldDirectlyPassData = typeof opts.data === "string" || opts.data instanceof ArrayBuffer || opts.data instanceof Blob || globalThis.File && opts.data instanceof File || opts.data instanceof FormData || opts.data instanceof stream_1.Readable || opts.data instanceof ReadableStream || opts.data instanceof String || opts.data instanceof URLSearchParams || ArrayBuffer.isView(opts.data) || ["Blob", "File", "FormData"].includes(opts.data?.constructor?.name || "");
|
|
330914
330931
|
if (opts.multipart?.length) {
|
|
330915
|
-
const boundary = await
|
|
330932
|
+
const boundary = await randomUUID3();
|
|
330916
330933
|
preparedHeaders.set("content-type", `multipart/related; boundary=${boundary}`);
|
|
330917
330934
|
opts.body = stream_1.Readable.from(this.getMultipartRequest(opts.multipart, boundary));
|
|
330918
330935
|
} else if (shouldDirectlyPassData) {
|
|
@@ -378596,7 +378613,7 @@ var init_storage = __esm(() => {
|
|
|
378596
378613
|
});
|
|
378597
378614
|
|
|
378598
378615
|
// ../api/src/plugins/context.ts
|
|
378599
|
-
import { randomUUID as
|
|
378616
|
+
import { randomUUID as randomUUID3 } from "crypto";
|
|
378600
378617
|
function createPluginDatabase(db2) {
|
|
378601
378618
|
return {
|
|
378602
378619
|
async execute(_sql, _params) {
|
|
@@ -378611,7 +378628,7 @@ function createPluginDatabase(db2) {
|
|
|
378611
378628
|
function createIngressClaim(db2) {
|
|
378612
378629
|
return {
|
|
378613
378630
|
async claim({ idempotencyKey, instanceId, channelType, externalId, eventType = "message.received" }) {
|
|
378614
|
-
const id =
|
|
378631
|
+
const id = randomUUID3();
|
|
378615
378632
|
try {
|
|
378616
378633
|
const claimed = await db2.insert(omniEvents).values({
|
|
378617
378634
|
id,
|
|
@@ -379855,12 +379872,12 @@ var init_message_persistence = __esm(() => {
|
|
|
379855
379872
|
});
|
|
379856
379873
|
|
|
379857
379874
|
// ../api/src/plugins/agent-dispatcher.ts
|
|
379858
|
-
import { createHash as
|
|
379875
|
+
import { createHash as createHash16 } from "crypto";
|
|
379859
379876
|
import { unlink, writeFile as writeFile4 } from "fs/promises";
|
|
379860
379877
|
import { tmpdir as tmpdir11 } from "os";
|
|
379861
379878
|
import { join as join22, resolve as resolve3 } from "path";
|
|
379862
379879
|
function sha256Digest(value) {
|
|
379863
|
-
return `sha256:${
|
|
379880
|
+
return `sha256:${createHash16("sha256").update(value).digest("hex")}`;
|
|
379864
379881
|
}
|
|
379865
379882
|
function redactLifecycleText(value) {
|
|
379866
379883
|
return value.replace(/[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,}/gi, "[EMAIL]").replace(/\b\+?\d[\d\s().-]{5,}\d\b/g, "[PHONE]").replace(/\b\d{6,}\b/g, "[NUMBER]").replace(/\b[^\s@]+@(s\.whatsapp\.net|g\.us|lid|newsletter)\b/gi, "[JID]");
|
|
@@ -384102,7 +384119,7 @@ var init_batch_pricing = __esm(() => {
|
|
|
384102
384119
|
});
|
|
384103
384120
|
|
|
384104
384121
|
// ../api/src/services/media-storage.ts
|
|
384105
|
-
import { randomUUID as
|
|
384122
|
+
import { randomUUID as randomUUID4 } from "crypto";
|
|
384106
384123
|
import { existsSync as existsSync4, mkdirSync as mkdirSync2 } from "fs";
|
|
384107
384124
|
import { rm as rm3, writeFile as writeFile5 } from "fs/promises";
|
|
384108
384125
|
import { tmpdir as tmpdir12 } from "os";
|
|
@@ -384336,7 +384353,7 @@ class MediaStorageService {
|
|
|
384336
384353
|
}
|
|
384337
384354
|
const buffer3 = await this.backend.read(reference);
|
|
384338
384355
|
const ext = extname2(reference) || ".bin";
|
|
384339
|
-
const tempPath = join23(tmpdir12(), `omni-media-${
|
|
384356
|
+
const tempPath = join23(tmpdir12(), `omni-media-${randomUUID4()}${ext}`);
|
|
384340
384357
|
try {
|
|
384341
384358
|
await writeFile5(tempPath, buffer3);
|
|
384342
384359
|
} catch (error3) {
|
|
@@ -386223,7 +386240,7 @@ var init_events2 = __esm(() => {
|
|
|
386223
386240
|
});
|
|
386224
386241
|
|
|
386225
386242
|
// ../api/src/services/event-consumers.ts
|
|
386226
|
-
import { randomUUID as
|
|
386243
|
+
import { randomUUID as randomUUID5 } from "crypto";
|
|
386227
386244
|
function planSharedPull(state, now) {
|
|
386228
386245
|
const expired = state.leases.find((lease) => lease.expiresAt <= now);
|
|
386229
386246
|
return expired ? { reclaim: expired } : { after: state.claimed };
|
|
@@ -386408,7 +386425,7 @@ class EventConsumerService {
|
|
|
386408
386425
|
const last = scanned[scanned.length - 1];
|
|
386409
386426
|
if (!plan.reclaim && !last)
|
|
386410
386427
|
return { consumer, lease: null, scanned };
|
|
386411
|
-
const lease = plan.reclaim ? { ...plan.reclaim, id:
|
|
386428
|
+
const lease = plan.reclaim ? { ...plan.reclaim, id: randomUUID5(), expiresAt: now + leaseMs } : { id: randomUUID5(), from: plan.after, to: Number(last?.journalSeq), expiresAt: now + leaseMs };
|
|
386412
386429
|
if (await this.casLeaseState(consumer, claimLease(state, lease, plan.reclaim?.id))) {
|
|
386413
386430
|
return { consumer, lease, scanned };
|
|
386414
386431
|
}
|
|
@@ -387728,7 +387745,7 @@ var init_instances = __esm(() => {
|
|
|
387728
387745
|
});
|
|
387729
387746
|
|
|
387730
387747
|
// ../api/src/services/manifest-compiler.ts
|
|
387731
|
-
import { createHash as
|
|
387748
|
+
import { createHash as createHash17 } from "crypto";
|
|
387732
387749
|
function stableStringify(value) {
|
|
387733
387750
|
if (Array.isArray(value)) {
|
|
387734
387751
|
return `[${value.map((item) => stableStringify(item)).join(",")}]`;
|
|
@@ -387748,7 +387765,7 @@ function filterToConditions(filter) {
|
|
|
387748
387765
|
return fields.map((field) => ({ field, operator: "eq", value: filter[field] }));
|
|
387749
387766
|
}
|
|
387750
387767
|
function compiledAutomationName(agentId, entry) {
|
|
387751
|
-
const digest =
|
|
387768
|
+
const digest = createHash17("sha256").update(stableStringify({ event: entry.event, filter: entry.filter ?? null })).digest("hex").slice(0, 12);
|
|
387752
387769
|
const prefix = `manifest:${agentId}:`;
|
|
387753
387770
|
const suffix = `#${digest}`;
|
|
387754
387771
|
const room = MAX_AUTOMATION_NAME_LENGTH - prefix.length - suffix.length;
|
|
@@ -391419,9 +391436,9 @@ var init_turns = __esm(() => {
|
|
|
391419
391436
|
});
|
|
391420
391437
|
|
|
391421
391438
|
// ../api/src/lib/ingress-idempotency.ts
|
|
391422
|
-
import { createHash as
|
|
391439
|
+
import { createHash as createHash18 } from "crypto";
|
|
391423
391440
|
function sha256Hex(input) {
|
|
391424
|
-
return
|
|
391441
|
+
return createHash18("sha256").update(input).digest("hex");
|
|
391425
391442
|
}
|
|
391426
391443
|
function resolvePayloadPath(payload, path3) {
|
|
391427
391444
|
let current = payload;
|
|
@@ -396935,6 +396952,30 @@ var init_health3 = __esm(() => {
|
|
|
396935
396952
|
|
|
396936
396953
|
// ../api/src/schemas/openapi/instances.ts
|
|
396937
396954
|
function registerInstanceSchemas(registry4) {
|
|
396955
|
+
const pathId = exports_external.object({ id: exports_external.string().uuid() });
|
|
396956
|
+
for (const [method, path3, schema3] of [
|
|
396957
|
+
["get", "/instances/{id}/self", SelfIdentitySchema],
|
|
396958
|
+
["post", "/instances/{id}/self/messages", SelfMessagesSchema],
|
|
396959
|
+
["post", "/instances/{id}/self/history", SelfHistorySchema],
|
|
396960
|
+
["post", "/instances/{id}/self/receipt", SelfReceiptSchema],
|
|
396961
|
+
["get", "/instances/{id}/self/chats", SelfChatsSchema],
|
|
396962
|
+
["post", "/messages/send-self", SendSelfSchema]
|
|
396963
|
+
])
|
|
396964
|
+
registry4.registerPath({
|
|
396965
|
+
method,
|
|
396966
|
+
path: path3,
|
|
396967
|
+
tags: ["WhatsApp self"],
|
|
396968
|
+
request: {
|
|
396969
|
+
...path3.includes("{id}") ? { params: pathId } : {},
|
|
396970
|
+
...method === "get" && path3 === "/instances/{id}/self/chats" ? { query: SelfChatsSchema } : {},
|
|
396971
|
+
...method === "post" ? { body: { content: { "application/json": { schema: schema3 } } } } : {}
|
|
396972
|
+
},
|
|
396973
|
+
responses: {
|
|
396974
|
+
200: { description: "Verified bounded self capability" },
|
|
396975
|
+
201: { description: "Native self send accepted" },
|
|
396976
|
+
409: { description: "Identity changed or unverified" }
|
|
396977
|
+
}
|
|
396978
|
+
});
|
|
396938
396979
|
registry4.register("Instance", InstanceSchema2);
|
|
396939
396980
|
registry4.register("CreateInstanceRequest", CreateInstanceSchema2);
|
|
396940
396981
|
registry4.register("InstanceStatus", InstanceStatusSchema2);
|
|
@@ -397493,7 +397534,7 @@ function registerInstanceSchemas(registry4) {
|
|
|
397493
397534
|
}
|
|
397494
397535
|
});
|
|
397495
397536
|
}
|
|
397496
|
-
var gupshupHandoffFieldValue, gupshupHandoffFieldKey, gupshupHandoffFields, GupshupHandoffOptionsSchema, closeContactOutcomeOverride, CloseContactConfigSchema, InstanceSchema2, CreateInstanceSchema2, InstanceStatusSchema2, QrCodeSchema, PairingCodeRequestSchema, PairingCodeSchema, ConnectInstanceSchema, ConnectResponseSchema, UserProfileSchema, ContactSchema, GroupSchema, SupportedChannelSchema;
|
|
397537
|
+
var gupshupHandoffFieldValue, gupshupHandoffFieldKey, gupshupHandoffFields, GupshupHandoffOptionsSchema, closeContactOutcomeOverride, CloseContactConfigSchema, InstanceSchema2, CreateInstanceSchema2, InstanceStatusSchema2, QrCodeSchema, PairingCodeRequestSchema, PairingCodeSchema, ConnectInstanceSchema, ConnectResponseSchema, UserProfileSchema, ContactSchema, GroupSchema, SupportedChannelSchema, ownJid, SelfIdentitySchema, selfWindow, validWindow = (v2) => Date.parse(v2.before) >= Date.parse(v2.after) && Date.parse(v2.before) - Date.parse(v2.after) <= 7 * 86400000, SelfMessagesSchema, SelfHistorySchema, SelfChatsSchema, SelfReceiptSchema, SendSelfSchema;
|
|
397497
397538
|
var init_instances2 = __esm(() => {
|
|
397498
397539
|
init_src();
|
|
397499
397540
|
init_zod_openapi();
|
|
@@ -397677,6 +397718,34 @@ var init_instances2 = __esm(() => {
|
|
|
397677
397718
|
loaded: exports_external.boolean().openapi({ description: "Whether plugin is loaded" }),
|
|
397678
397719
|
capabilities: exports_external.record(exports_external.string(), exports_external.unknown()).optional().openapi({ description: "Plugin capabilities" })
|
|
397679
397720
|
});
|
|
397721
|
+
ownJid = exports_external.string().regex(/^\d{5,20}@s\.whatsapp\.net$/);
|
|
397722
|
+
SelfIdentitySchema = exports_external.object({
|
|
397723
|
+
ownerIdentifier: ownJid,
|
|
397724
|
+
generation: exports_external.string().uuid(),
|
|
397725
|
+
selfJid: ownJid,
|
|
397726
|
+
connectedAt: exports_external.string().datetime()
|
|
397727
|
+
}).strict();
|
|
397728
|
+
selfWindow = {
|
|
397729
|
+
expectedOwner: ownJid,
|
|
397730
|
+
expectedGeneration: exports_external.string().uuid(),
|
|
397731
|
+
after: exports_external.string().datetime(),
|
|
397732
|
+
before: exports_external.string().datetime()
|
|
397733
|
+
};
|
|
397734
|
+
SelfMessagesSchema = exports_external.object({
|
|
397735
|
+
...selfWindow,
|
|
397736
|
+
connectionStartedAt: exports_external.string().datetime(),
|
|
397737
|
+
excludeExternalIds: exports_external.array(exports_external.string().min(1).max(255)).max(1000).refine((v2) => new Set(v2).size === v2.length)
|
|
397738
|
+
}).strict().refine(validWindow, "At most seven days").refine((v2) => Date.parse(v2.connectionStartedAt) <= Date.parse(v2.after) && Date.parse(v2.after) === Math.max(Date.parse(v2.connectionStartedAt), Date.parse(v2.before) - 7 * 86400000), "Anchored self inbox window");
|
|
397739
|
+
SelfHistorySchema = exports_external.object({ ...selfWindow, chatId: exports_external.string().uuid() }).strict().refine(validWindow, "At most seven days");
|
|
397740
|
+
SelfChatsSchema = exports_external.object({ cursor: exports_external.string().uuid().optional() }).strict();
|
|
397741
|
+
SelfReceiptSchema = exports_external.object({ expectedOwner: ownJid, expectedGeneration: exports_external.string().uuid(), externalId: exports_external.string().min(1).max(255) }).strict();
|
|
397742
|
+
SendSelfSchema = exports_external.object({
|
|
397743
|
+
instanceId: exports_external.string().uuid(),
|
|
397744
|
+
expectedOwner: ownJid,
|
|
397745
|
+
expectedGeneration: exports_external.string().uuid(),
|
|
397746
|
+
operationKey: exports_external.string().regex(/^[A-Za-z0-9_-]{1,100}$/),
|
|
397747
|
+
text: exports_external.string().min(1).max(8000)
|
|
397748
|
+
}).strict();
|
|
397680
397749
|
});
|
|
397681
397750
|
|
|
397682
397751
|
// ../api/src/schemas/openapi/journeys.ts
|
|
@@ -405062,6 +405131,143 @@ var init_agent_replay = __esm(() => {
|
|
|
405062
405131
|
MAX_REPLAY_WINDOW_MS = 24 * 60 * 60 * 1000;
|
|
405063
405132
|
});
|
|
405064
405133
|
|
|
405134
|
+
// ../api/src/services/whatsapp-self.ts
|
|
405135
|
+
function selfPlugin(plugin13) {
|
|
405136
|
+
if (!plugin13 || plugin13.id !== "whatsapp-baileys" || !("getSelfIdentity" in plugin13) || typeof plugin13.getSelfIdentity !== "function" || !("sendSelf" in plugin13) || typeof plugin13.sendSelf !== "function")
|
|
405137
|
+
throw new Error("Self capability unavailable");
|
|
405138
|
+
return plugin13;
|
|
405139
|
+
}
|
|
405140
|
+
function verifySelf(plugin13, instanceId, expected) {
|
|
405141
|
+
const value = SelfIdentitySchema.parse(plugin13.getSelfIdentity(instanceId));
|
|
405142
|
+
if (value.selfJid !== value.ownerIdentifier || expected && (value.ownerIdentifier !== expected.expectedOwner || value.generation !== expected.expectedGeneration))
|
|
405143
|
+
throw new Error("Self identity changed");
|
|
405144
|
+
return value;
|
|
405145
|
+
}
|
|
405146
|
+
function freshInboxWindow(input) {
|
|
405147
|
+
const now = Date.now();
|
|
405148
|
+
const before = Date.parse(input.before);
|
|
405149
|
+
const after = Date.parse(input.after);
|
|
405150
|
+
const connectionStartedAt = Date.parse(input.connectionStartedAt);
|
|
405151
|
+
if (before < now - 60000 || before > now + 60000 || connectionStartedAt > after || after > before || before - after > 7 * 86400000 || after !== Math.max(connectionStartedAt, before - 7 * 86400000))
|
|
405152
|
+
throw new Error("Read window expired");
|
|
405153
|
+
}
|
|
405154
|
+
function platformTime(value) {
|
|
405155
|
+
let seconds;
|
|
405156
|
+
if (typeof value === "number")
|
|
405157
|
+
seconds = value;
|
|
405158
|
+
else {
|
|
405159
|
+
if (!value || typeof value !== "object" || Array.isArray(value))
|
|
405160
|
+
return null;
|
|
405161
|
+
const long = value;
|
|
405162
|
+
if (Object.keys(long).length !== 3 || Object.keys(long).some((key) => !["low", "high", "unsigned"].includes(key)) || typeof long.low !== "number" || !Number.isInteger(long.low) || long.low < -2147483648 || long.low > 2147483647 || typeof long.high !== "number" || !Number.isInteger(long.high) || long.high < -2147483648 || long.high > 2147483647 || typeof long.unsigned !== "boolean")
|
|
405163
|
+
return null;
|
|
405164
|
+
let integer3 = BigInt(long.high >>> 0) << 32n | BigInt(long.low >>> 0);
|
|
405165
|
+
if (!long.unsigned && long.high < 0)
|
|
405166
|
+
integer3 -= 1n << 64n;
|
|
405167
|
+
if (integer3 <= 0n || integer3 > 8640000000000n)
|
|
405168
|
+
return null;
|
|
405169
|
+
seconds = Number(integer3);
|
|
405170
|
+
}
|
|
405171
|
+
if (!Number.isSafeInteger(seconds) || seconds <= 0 || seconds > 8640000000000)
|
|
405172
|
+
return null;
|
|
405173
|
+
return new Date(seconds * 1000).toISOString();
|
|
405174
|
+
}
|
|
405175
|
+
function projectSelfEvent(row, owner, source = null) {
|
|
405176
|
+
const raw2 = row.rawPayload ?? {};
|
|
405177
|
+
const key = raw2.key;
|
|
405178
|
+
const message2 = raw2.message;
|
|
405179
|
+
const extended = message2?.extendedTextMessage;
|
|
405180
|
+
const context20 = extended?.contextInfo;
|
|
405181
|
+
const nativeText = message2?.conversation ?? extended?.text;
|
|
405182
|
+
const at = platformTime(raw2.messageTimestamp);
|
|
405183
|
+
const authority = source === "realtime" && row.eventType === "message.received" && row.contentType === "text" && key?.fromMe === true && raw2.isFromMe === true && key.remoteJid === owner && row.metadata?.from === owner.split("@")[0] && typeof nativeText === "string" && nativeText === row.textContent && at !== null && !row.replyToExternalId && !raw2.quotedMessage && !context20?.quotedMessage && !context20?.isForwarded && !context20?.forwardingScore && !message2?.protocolMessage && raw2.isHistorySync !== true;
|
|
405184
|
+
return {
|
|
405185
|
+
id: row.id,
|
|
405186
|
+
externalId: row.externalId,
|
|
405187
|
+
chatId: row.chatId,
|
|
405188
|
+
from: owner,
|
|
405189
|
+
text: row.textContent ?? "",
|
|
405190
|
+
at,
|
|
405191
|
+
receivedAt: row.receivedAt.toISOString(),
|
|
405192
|
+
isFromMe: raw2.isFromMe === true,
|
|
405193
|
+
authority
|
|
405194
|
+
};
|
|
405195
|
+
}
|
|
405196
|
+
async function readSelfMessages(db2, plugin13, instanceId, input) {
|
|
405197
|
+
const identity = verifySelf(plugin13, instanceId, input);
|
|
405198
|
+
freshInboxWindow(input);
|
|
405199
|
+
const rows = await db2.select({ event: omniEvents, source: messages2.source }).from(omniEvents).innerJoin(chats, and2(eq(chats.instanceId, omniEvents.instanceId), eq(chats.externalId, omniEvents.chatId))).innerJoin(messages2, and2(eq(messages2.chatId, chats.id), eq(messages2.externalId, omniEvents.externalId))).where(and2(eq(omniEvents.instanceId, instanceId), eq(omniEvents.chatId, identity.selfJid), eq(omniEvents.eventType, "message.received"), eq(omniEvents.contentType, "text"), eq(messages2.source, "realtime"), eq(messages2.isFromMe, true), isNull2(chats.deletedAt), isNull2(messages2.deletedAt), isNotNull(omniEvents.externalId), gte(omniEvents.receivedAt, new Date(input.after)), lte(omniEvents.receivedAt, new Date(input.before)), input.excludeExternalIds.length ? notInArray(omniEvents.externalId, input.excludeExternalIds) : undefined)).orderBy(asc(omniEvents.receivedAt), asc(omniEvents.id)).limit(51);
|
|
405200
|
+
const older = await db2.select({ id: omniEvents.id }).from(omniEvents).innerJoin(chats, and2(eq(chats.instanceId, omniEvents.instanceId), eq(chats.externalId, omniEvents.chatId))).innerJoin(messages2, and2(eq(messages2.chatId, chats.id), eq(messages2.externalId, omniEvents.externalId))).where(and2(eq(omniEvents.instanceId, instanceId), eq(omniEvents.chatId, identity.selfJid), eq(omniEvents.eventType, "message.received"), eq(omniEvents.contentType, "text"), eq(messages2.source, "realtime"), eq(messages2.isFromMe, true), isNull2(chats.deletedAt), isNull2(messages2.deletedAt), isNotNull(omniEvents.externalId), gte(omniEvents.receivedAt, new Date(input.connectionStartedAt)), lt(omniEvents.receivedAt, new Date(input.after)), input.excludeExternalIds.length ? notInArray(omniEvents.externalId, input.excludeExternalIds) : undefined)).limit(1);
|
|
405201
|
+
verifySelf(plugin13, instanceId, input);
|
|
405202
|
+
return {
|
|
405203
|
+
items: rows.slice(0, 50).map((row) => {
|
|
405204
|
+
const projected = projectSelfEvent(row.event, identity.selfJid, row.source);
|
|
405205
|
+
projected.authority = projected.authority && projected.at !== null && Date.parse(projected.at) >= Date.parse(input.connectionStartedAt) && Date.parse(projected.at) <= Date.parse(input.before);
|
|
405206
|
+
return projected;
|
|
405207
|
+
}),
|
|
405208
|
+
hasMore: rows.length > 50,
|
|
405209
|
+
hasOlder: older.length > 0
|
|
405210
|
+
};
|
|
405211
|
+
}
|
|
405212
|
+
async function readOwnedChats(db2, plugin13, instanceId, cursor) {
|
|
405213
|
+
const identity = verifySelf(plugin13, instanceId);
|
|
405214
|
+
const rows = await db2.select({ id: chats.id, name: chats.name }).from(chats).where(and2(eq(chats.instanceId, instanceId), isNull2(chats.deletedAt), cursor ? gt(chats.id, cursor) : undefined)).orderBy(asc(chats.id)).limit(26);
|
|
405215
|
+
verifySelf(plugin13, instanceId, { expectedOwner: identity.ownerIdentifier, expectedGeneration: identity.generation });
|
|
405216
|
+
const items = rows.slice(0, 25);
|
|
405217
|
+
return { items, meta: { hasMore: rows.length > 25, cursor: rows.length > 25 ? items.at(-1)?.id ?? null : null } };
|
|
405218
|
+
}
|
|
405219
|
+
function boundHistory(rows) {
|
|
405220
|
+
let characters = 0;
|
|
405221
|
+
let partial = rows.length > 50;
|
|
405222
|
+
const items = [];
|
|
405223
|
+
for (const row of rows.slice(0, 50)) {
|
|
405224
|
+
const text3 = row.text ?? "";
|
|
405225
|
+
if (characters + text3.length > 8000) {
|
|
405226
|
+
partial = true;
|
|
405227
|
+
break;
|
|
405228
|
+
}
|
|
405229
|
+
characters += text3.length;
|
|
405230
|
+
items.push({
|
|
405231
|
+
externalId: row.externalId,
|
|
405232
|
+
text: text3,
|
|
405233
|
+
at: row.at.toISOString(),
|
|
405234
|
+
direction: row.isFromMe ? "outbound" : "inbound"
|
|
405235
|
+
});
|
|
405236
|
+
}
|
|
405237
|
+
return { items, partial, limits: { days: 7, messages: 50, characters: 8000 } };
|
|
405238
|
+
}
|
|
405239
|
+
async function readOwnedHistory(db2, plugin13, instanceId, input) {
|
|
405240
|
+
verifySelf(plugin13, instanceId, input);
|
|
405241
|
+
const rows = await db2.select({
|
|
405242
|
+
externalId: messages2.externalId,
|
|
405243
|
+
text: messages2.textContent,
|
|
405244
|
+
at: messages2.platformTimestamp,
|
|
405245
|
+
isFromMe: messages2.isFromMe
|
|
405246
|
+
}).from(messages2).innerJoin(chats, eq(chats.id, messages2.chatId)).where(and2(eq(chats.id, input.chatId), eq(chats.instanceId, instanceId), isNull2(chats.deletedAt), isNull2(messages2.deletedAt), gte(messages2.platformTimestamp, new Date(input.after)), lte(messages2.platformTimestamp, new Date(input.before)))).orderBy(desc(messages2.platformTimestamp), desc(messages2.id)).limit(51);
|
|
405247
|
+
const [chat2] = await db2.select({ id: chats.id }).from(chats).where(and2(eq(chats.id, input.chatId), eq(chats.instanceId, instanceId), isNull2(chats.deletedAt))).limit(1);
|
|
405248
|
+
if (!chat2)
|
|
405249
|
+
throw new Error("Selected chat unavailable");
|
|
405250
|
+
verifySelf(plugin13, instanceId, input);
|
|
405251
|
+
return boundHistory(rows);
|
|
405252
|
+
}
|
|
405253
|
+
async function readSelfReceipt(db2, plugin13, instanceId, input) {
|
|
405254
|
+
const identity = verifySelf(plugin13, instanceId, input);
|
|
405255
|
+
const [row] = await db2.select({ externalId: messages2.externalId, text: messages2.textContent, at: messages2.platformTimestamp }).from(messages2).innerJoin(chats, eq(chats.id, messages2.chatId)).innerJoin(omniEvents, and2(eq(omniEvents.externalId, messages2.externalId), eq(omniEvents.instanceId, instanceId), eq(omniEvents.chatId, identity.selfJid))).where(and2(eq(chats.instanceId, instanceId), eq(chats.externalId, identity.selfJid), eq(messages2.externalId, input.externalId), eq(messages2.source, "realtime"), eq(omniEvents.eventType, "message.sent"), eq(omniEvents.direction, "outbound"), eq(omniEvents.status, "completed"), eq(omniEvents.contentType, "text"), eq(messages2.messageType, "text"), eq(messages2.textContent, omniEvents.textContent), eq(messages2.isFromMe, true), isNull2(messages2.deletedAt))).limit(1);
|
|
405256
|
+
verifySelf(plugin13, instanceId, input);
|
|
405257
|
+
return row ? {
|
|
405258
|
+
externalId: row.externalId,
|
|
405259
|
+
text: row.text ?? "",
|
|
405260
|
+
at: row.at.toISOString(),
|
|
405261
|
+
ownerIdentifier: identity.ownerIdentifier,
|
|
405262
|
+
generation: identity.generation
|
|
405263
|
+
} : null;
|
|
405264
|
+
}
|
|
405265
|
+
var init_whatsapp_self = __esm(() => {
|
|
405266
|
+
init_src6();
|
|
405267
|
+
init_drizzle_orm();
|
|
405268
|
+
init_instances2();
|
|
405269
|
+
});
|
|
405270
|
+
|
|
405065
405271
|
// ../api/src/routes/v2/instances.ts
|
|
405066
405272
|
function shouldApplyDefaultReplyFilter(args) {
|
|
405067
405273
|
if (!args.agentIdTouched)
|
|
@@ -405657,6 +405863,7 @@ var init_instances3 = __esm(() => {
|
|
|
405657
405863
|
init_instances2();
|
|
405658
405864
|
init_access();
|
|
405659
405865
|
init_agent_replay();
|
|
405866
|
+
init_whatsapp_self();
|
|
405660
405867
|
log123 = createLogger("api:instances");
|
|
405661
405868
|
instancesRoutes = new Hono2;
|
|
405662
405869
|
instanceAccess3 = requireInstanceAccess((c) => c.req.param("id") ?? "");
|
|
@@ -406018,6 +406225,51 @@ var init_instances3 = __esm(() => {
|
|
|
406018
406225
|
}
|
|
406019
406226
|
return c.json({ success: true });
|
|
406020
406227
|
});
|
|
406228
|
+
instancesRoutes.get("/:id/self", instanceAccess3, async (c) => {
|
|
406229
|
+
try {
|
|
406230
|
+
const instance4 = await c.get("services").instances.getById(c.req.param("id"));
|
|
406231
|
+
const plugin13 = selfPlugin(c.get("channelRegistry")?.get(instance4.channel));
|
|
406232
|
+
return c.json({ data: verifySelf(plugin13, instance4.id) });
|
|
406233
|
+
} catch {
|
|
406234
|
+
return c.json({ error: { code: "SELF_UNAVAILABLE" } }, 409);
|
|
406235
|
+
}
|
|
406236
|
+
});
|
|
406237
|
+
instancesRoutes.get("/:id/self/chats", instanceAccess3, zValidator("query", SelfChatsSchema), async (c) => {
|
|
406238
|
+
try {
|
|
406239
|
+
const instance4 = await c.get("services").instances.getById(c.req.param("id"));
|
|
406240
|
+
const plugin13 = selfPlugin(c.get("channelRegistry")?.get(instance4.channel));
|
|
406241
|
+
return c.json(await readOwnedChats(c.get("db"), plugin13, instance4.id, c.req.valid("query").cursor));
|
|
406242
|
+
} catch {
|
|
406243
|
+
return c.json({ error: { code: "SELF_READ_UNAVAILABLE" } }, 409);
|
|
406244
|
+
}
|
|
406245
|
+
});
|
|
406246
|
+
instancesRoutes.post("/:id/self/messages", instanceAccess3, zValidator("json", SelfMessagesSchema), async (c) => {
|
|
406247
|
+
try {
|
|
406248
|
+
const instance4 = await c.get("services").instances.getById(c.req.param("id"));
|
|
406249
|
+
const plugin13 = selfPlugin(c.get("channelRegistry")?.get(instance4.channel));
|
|
406250
|
+
return c.json(await readSelfMessages(c.get("db"), plugin13, instance4.id, c.req.valid("json")));
|
|
406251
|
+
} catch {
|
|
406252
|
+
return c.json({ error: { code: "SELF_READ_UNAVAILABLE" } }, 409);
|
|
406253
|
+
}
|
|
406254
|
+
});
|
|
406255
|
+
instancesRoutes.post("/:id/self/receipt", instanceAccess3, zValidator("json", SelfReceiptSchema), async (c) => {
|
|
406256
|
+
try {
|
|
406257
|
+
const instance4 = await c.get("services").instances.getById(c.req.param("id"));
|
|
406258
|
+
const plugin13 = selfPlugin(c.get("channelRegistry")?.get(instance4.channel));
|
|
406259
|
+
return c.json({ data: await readSelfReceipt(c.get("db"), plugin13, instance4.id, c.req.valid("json")) });
|
|
406260
|
+
} catch {
|
|
406261
|
+
return c.json({ error: { code: "SELF_READ_UNAVAILABLE" } }, 409);
|
|
406262
|
+
}
|
|
406263
|
+
});
|
|
406264
|
+
instancesRoutes.post("/:id/self/history", instanceAccess3, zValidator("json", SelfHistorySchema), async (c) => {
|
|
406265
|
+
try {
|
|
406266
|
+
const instance4 = await c.get("services").instances.getById(c.req.param("id"));
|
|
406267
|
+
const plugin13 = selfPlugin(c.get("channelRegistry")?.get(instance4.channel));
|
|
406268
|
+
return c.json(await readOwnedHistory(c.get("db"), plugin13, instance4.id, c.req.valid("json")));
|
|
406269
|
+
} catch {
|
|
406270
|
+
return c.json({ error: { code: "SELF_READ_UNAVAILABLE" } }, 409);
|
|
406271
|
+
}
|
|
406272
|
+
});
|
|
406021
406273
|
instancesRoutes.get("/:id/status", instanceAccess3, async (c) => {
|
|
406022
406274
|
const id = c.req.param("id");
|
|
406023
406275
|
const services = c.get("services");
|
|
@@ -409916,9 +410168,11 @@ var init_messages6 = __esm(() => {
|
|
|
409916
410168
|
init_sentry_scrub();
|
|
409917
410169
|
init_media_processor();
|
|
409918
410170
|
init_date_query();
|
|
410171
|
+
init_instances2();
|
|
409919
410172
|
init_messages5();
|
|
409920
410173
|
init_api_keys();
|
|
409921
410174
|
init_media_storage();
|
|
410175
|
+
init_whatsapp_self();
|
|
409922
410176
|
init_tenant_scope();
|
|
409923
410177
|
init__close_contact_config();
|
|
409924
410178
|
log126 = createLogger("routes:messages");
|
|
@@ -410348,6 +410602,21 @@ var init_messages6 = __esm(() => {
|
|
|
410348
410602
|
const message2 = await services.messages.updateDocumentExtraction(id, extraction);
|
|
410349
410603
|
return c.json({ data: message2 });
|
|
410350
410604
|
});
|
|
410605
|
+
messagesRoutes.post("/send-self", zValidator("json", SendSelfSchema), async (c) => {
|
|
410606
|
+
const { instanceId, ...input } = c.req.valid("json");
|
|
410607
|
+
checkInstanceAccess2(c.get("apiKey"), instanceId);
|
|
410608
|
+
try {
|
|
410609
|
+
const instance4 = await c.get("services").instances.getById(instanceId);
|
|
410610
|
+
const plugin13 = selfPlugin(c.get("channelRegistry")?.get(instance4.channel));
|
|
410611
|
+
verifySelf(plugin13, instanceId, input);
|
|
410612
|
+
const text3 = sanitizeOutboundText(input.text);
|
|
410613
|
+
if (!text3.trim())
|
|
410614
|
+
return c.json({ error: { code: "SELF_TEXT_REQUIRED" } }, 400);
|
|
410615
|
+
return c.json({ data: await plugin13.sendSelf(instanceId, { ...input, text: text3 }) }, 201);
|
|
410616
|
+
} catch {
|
|
410617
|
+
return c.json({ error: { code: "SELF_SEND_UNCONFIRMED" } }, 409);
|
|
410618
|
+
}
|
|
410619
|
+
});
|
|
410351
410620
|
messagesRoutes.post("/send", async (c) => {
|
|
410352
410621
|
let rawBody;
|
|
410353
410622
|
try {
|
|
@@ -412562,7 +412831,7 @@ var init_settings3 = __esm(() => {
|
|
|
412562
412831
|
});
|
|
412563
412832
|
|
|
412564
412833
|
// ../api/src/lib/single-use-store.ts
|
|
412565
|
-
import { randomUUID as
|
|
412834
|
+
import { randomUUID as randomUUID6 } from "crypto";
|
|
412566
412835
|
function createSingleUseStore(opts) {
|
|
412567
412836
|
const { ttlMs, maxEntries, prefix } = opts;
|
|
412568
412837
|
if (!(ttlMs > 0))
|
|
@@ -412601,7 +412870,7 @@ function createSingleUseStore(opts) {
|
|
|
412601
412870
|
}
|
|
412602
412871
|
return {
|
|
412603
412872
|
put(value, entryTtlMs = ttlMs) {
|
|
412604
|
-
const handle = `${prefix}${
|
|
412873
|
+
const handle = `${prefix}${randomUUID6()}`;
|
|
412605
412874
|
const expiresAt = Date.now() + entryTtlMs;
|
|
412606
412875
|
remember(handle, expiresAt);
|
|
412607
412876
|
store(handle, value, expiresAt);
|
|
@@ -430754,6 +431023,7 @@ var src_default8 = plugin9;
|
|
|
430754
431023
|
// ../channel-whatsapp/src/plugin.ts
|
|
430755
431024
|
init_src2();
|
|
430756
431025
|
init_src();
|
|
431026
|
+
import { createHash as createHash12, randomUUID as randomUUID2 } from "crypto";
|
|
430757
431027
|
|
|
430758
431028
|
// ../channel-whatsapp/src/auth.ts
|
|
430759
431029
|
init_src();
|
|
@@ -545092,6 +545362,15 @@ function createRateLimitManager(instanceId, logger5, config2) {
|
|
|
545092
545362
|
}
|
|
545093
545363
|
|
|
545094
545364
|
// ../channel-whatsapp/src/plugin.ts
|
|
545365
|
+
function selfPlatformMessageId(instanceId, owner, operationKey) {
|
|
545366
|
+
return `3EB0${createHash12("sha256").update(JSON.stringify([instanceId, owner, operationKey])).digest("hex").slice(0, 32).toUpperCase()}`;
|
|
545367
|
+
}
|
|
545368
|
+
function ownPhoneJid(value) {
|
|
545369
|
+
if (typeof value !== "string" || !/^\d{5,20}(?::\d+)?@s\.whatsapp\.net$/.test(value)) {
|
|
545370
|
+
throw new WhatsAppError(ErrorCode2.NOT_CONNECTED, "Verified own phone identity required");
|
|
545371
|
+
}
|
|
545372
|
+
return value.replace(/:\d+@/, "@");
|
|
545373
|
+
}
|
|
545095
545374
|
function isTransientConnectionClosedError(error) {
|
|
545096
545375
|
if (!error)
|
|
545097
545376
|
return false;
|
|
@@ -545124,6 +545403,8 @@ class WhatsAppPlugin extends BaseChannelPlugin {
|
|
|
545124
545403
|
version = "1.0.0";
|
|
545125
545404
|
capabilities = WHATSAPP_CAPABILITIES;
|
|
545126
545405
|
sockets = new Map;
|
|
545406
|
+
selfGenerations = new WeakMap;
|
|
545407
|
+
selfConnectedAt = new WeakMap;
|
|
545127
545408
|
passkeyStates = new Map;
|
|
545128
545409
|
pluginConfig = {};
|
|
545129
545410
|
historySyncCallbacks = new Map;
|
|
@@ -545916,6 +546197,45 @@ class WhatsAppPlugin extends BaseChannelPlugin {
|
|
|
545916
546197
|
systemNotice: originalMessage.metadata?.systemNotice
|
|
545917
546198
|
};
|
|
545918
546199
|
}
|
|
546200
|
+
getSelfIdentity(instanceId) {
|
|
546201
|
+
const sock = this.getSocket(instanceId);
|
|
546202
|
+
if (this.instances.getStatus(instanceId)?.state !== "connected") {
|
|
546203
|
+
throw new WhatsAppError(ErrorCode2.NOT_CONNECTED, "WhatsApp is disconnected");
|
|
546204
|
+
}
|
|
546205
|
+
const ownerIdentifier = ownPhoneJid(sock.user?.id);
|
|
546206
|
+
const generation = this.selfGenerations.get(sock);
|
|
546207
|
+
const connectedAt = this.selfConnectedAt.get(sock);
|
|
546208
|
+
if (!generation || !connectedAt)
|
|
546209
|
+
throw new Error("Authenticated connection epoch unavailable");
|
|
546210
|
+
return { ownerIdentifier, generation, selfJid: ownerIdentifier, connectedAt };
|
|
546211
|
+
}
|
|
546212
|
+
async sendSelf(instanceId, input) {
|
|
546213
|
+
if (Object.keys(input).some((key) => !["expectedOwner", "expectedGeneration", "operationKey", "text"].includes(key)) || !/^[A-Za-z0-9_-]{1,100}$/.test(input.operationKey) || typeof input.text !== "string" || !input.text.trim() || input.text.length > 8000)
|
|
546214
|
+
throw new Error("Invalid self message");
|
|
546215
|
+
const sock = this.getSocket(instanceId);
|
|
546216
|
+
const admitted = this.getSelfIdentity(instanceId);
|
|
546217
|
+
if (admitted.ownerIdentifier !== input.expectedOwner || admitted.generation !== input.expectedGeneration)
|
|
546218
|
+
throw new Error("Self identity changed");
|
|
546219
|
+
const externalId = selfPlatformMessageId(instanceId, admitted.ownerIdentifier, input.operationKey);
|
|
546220
|
+
const limiter = await this.waitForRateLimitBackoff(instanceId);
|
|
546221
|
+
const message2 = {
|
|
546222
|
+
to: admitted.selfJid,
|
|
546223
|
+
content: { type: "text", text: input.text },
|
|
546224
|
+
metadata: { correlationId: input.operationKey }
|
|
546225
|
+
};
|
|
546226
|
+
this.trackSentMessageId(instanceId, externalId);
|
|
546227
|
+
const current = this.getSelfIdentity(instanceId);
|
|
546228
|
+
if (this.sockets.get(instanceId) !== sock || current.ownerIdentifier !== admitted.ownerIdentifier || current.generation !== admitted.generation)
|
|
546229
|
+
throw new Error("Self identity changed");
|
|
546230
|
+
const result = await sock.sendMessage(admitted.selfJid, { text: input.text }, { messageId: externalId });
|
|
546231
|
+
if (result?.key?.id !== externalId)
|
|
546232
|
+
throw new Error("Self send outcome is uncertain");
|
|
546233
|
+
if (result.message)
|
|
546234
|
+
this.trackRecentSentMessage(instanceId, externalId, result.message);
|
|
546235
|
+
await this.emitMessageSent(this.buildSentEventPayload(instanceId, externalId, admitted.selfJid, message2, message2));
|
|
546236
|
+
limiter.reset();
|
|
546237
|
+
return { externalId, ownerIdentifier: admitted.ownerIdentifier, generation: admitted.generation };
|
|
546238
|
+
}
|
|
545919
546239
|
async sendMessage(instanceId, message2) {
|
|
545920
546240
|
const sock = this.getSocket(instanceId);
|
|
545921
546241
|
const jid = await this.resolveSendTarget(sock, instanceId, message2.to);
|
|
@@ -546657,6 +546977,13 @@ class WhatsAppPlugin extends BaseChannelPlugin {
|
|
|
546657
546977
|
}
|
|
546658
546978
|
}
|
|
546659
546979
|
async handleConnected(instanceId, sock, isNewLogin = false) {
|
|
546980
|
+
try {
|
|
546981
|
+
ownPhoneJid(sock.user?.id);
|
|
546982
|
+
if (!this.selfConnectedAt.has(sock))
|
|
546983
|
+
this.selfConnectedAt.set(sock, new Date().toISOString());
|
|
546984
|
+
if (!this.selfGenerations.has(sock))
|
|
546985
|
+
this.selfGenerations.set(sock, randomUUID2());
|
|
546986
|
+
} catch {}
|
|
546660
546987
|
this.passkeyStates.delete(instanceId);
|
|
546661
546988
|
let profileName;
|
|
546662
546989
|
let profilePicUrl;
|