@automagik/omni 2.260909.5 → 2.260910.1

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.
@@ -53,6 +53,18 @@ export declare const __testables: {
53
53
  loadSchemaArtifact: typeof loadSchemaArtifact;
54
54
  summarizeSchemaRow: typeof summarizeSchemaRow;
55
55
  };
56
+ /**
57
+ * Table projection for list-shaped event commands. Human-readable output only:
58
+ * JSON mode emits the raw API rows via `rawData` so `eventType` (and every
59
+ * other field) survives intact (#1028).
60
+ */
61
+ export declare function eventListRow(e: Event): {
62
+ id: string;
63
+ type: string;
64
+ instanceId: string;
65
+ direction: string;
66
+ receivedAt: string;
67
+ };
56
68
  /** True when event_type denotes a failure/denial — used by --errors-only. */
57
69
  export declare function isErrorEvent(eventType: string): boolean;
58
70
  /** True when event_type is considered noisy and should be hidden unless --all is set. */
@@ -81,8 +93,40 @@ export interface StreamFilterOptions {
81
93
  * (chat-id, person-id, errors-only, noise suppression).
82
94
  */
83
95
  export declare function passesStreamFilters(event: Event, options: StreamFilterOptions): boolean;
96
+ /**
97
+ * The journal row as GET /events actually returns it (full omni_events row —
98
+ * the SDK `Event` type is a projection). `stream` reads the raw platform
99
+ * chat id (#1036 ask 3) and sender hints out of the extra columns.
100
+ */
101
+ export type StreamEventRow = Event & {
102
+ chatId?: string | null;
103
+ metadata?: {
104
+ from?: string;
105
+ } | null;
106
+ rawPayload?: {
107
+ pushName?: string;
108
+ key?: {
109
+ fromMe?: boolean;
110
+ };
111
+ } | null;
112
+ };
113
+ /** id → display name lookups for `stream` (null = looked up, nothing found). */
114
+ export interface StreamNames {
115
+ instances: Map<string, string | null>;
116
+ chats: Map<string, string | null>;
117
+ persons: Map<string, string | null>;
118
+ }
119
+ export interface FormatLineOptions {
120
+ /** Add sender / fromMe / contentType columns (#1036 ask 1). */
121
+ verbose?: boolean;
122
+ /** Print raw uuid8 ids even when a name is known (#1036 ask 2, `--ids`). */
123
+ ids?: boolean;
124
+ names?: StreamNames;
125
+ }
126
+ /** Sender label: resolved person name, then channel push name, then raw `from`. */
127
+ export declare function senderLabel(event: StreamEventRow, names?: StreamNames): string;
84
128
  /** Format an event as a single human-readable line. */
85
- export declare function formatEventLine(event: Event): string;
129
+ export declare function formatEventLine(event: StreamEventRow, options?: FormatLineOptions): string;
86
130
  /**
87
131
  * The journal row as the API actually returns it: the generated SDK `Event`
88
132
  * type is a projection, but GET /events returns full omni_events rows —
@@ -1 +1 @@
1
- {"version":3,"file":"events.d.ts","sourceRoot":"","sources":["../../src/commands/events.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"events.d.ts","sourceRoot":"","sources":["../../src/commands/events.ts"],"names":[],"mappings":"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"}
package/dist/index.js CHANGED
@@ -40094,6 +40094,14 @@ function evaluateConditionsWithDetails(conditions, payload, logic = "and") {
40094
40094
  conditions: results
40095
40095
  };
40096
40096
  }
40097
+ function describeUnmatchedConditions(result) {
40098
+ const failed = result.conditions.filter((c2) => !c2.matched).map((c2) => {
40099
+ const expected = c2.operator === "exists" || c2.operator === "not_exists" ? "" : ` ${JSON.stringify(c2.expectedValue)}`;
40100
+ const actual = c2.actualValue === undefined ? "condition_field_unresolved" : `actual: ${JSON.stringify(c2.actualValue)}`;
40101
+ return `${c2.field} ${c2.operator}${expected} (${actual})`;
40102
+ });
40103
+ return `conditions_not_matched: ${failed.join("; ")}`;
40104
+ }
40097
40105
  var logger, MAX_REGEX_INPUT_LENGTH = 1e4, MAX_REGEX_PATTERN_LENGTH = 500, DANGEROUS_REGEX_PATTERN;
40098
40106
  var init_conditions = __esm(() => {
40099
40107
  init_logger();
@@ -41503,6 +41511,7 @@ class AutomationEngine {
41503
41511
  releaseIdleTimeoutClaim: deps.releaseIdleTimeoutClaim,
41504
41512
  claimEmittedEvent: deps.claimEmittedEvent,
41505
41513
  releaseEmittedEventClaim: deps.releaseEmittedEventClaim,
41514
+ claimExecution: deps.claimExecution,
41506
41515
  validateEmitEvent: deps.validateEmitEvent
41507
41516
  };
41508
41517
  this.automations = automations.filter((a) => a.enabled);
@@ -41589,7 +41598,8 @@ class AutomationEngine {
41589
41598
  queue: "automation-engine",
41590
41599
  startFrom: "new",
41591
41600
  maxRetries: 3,
41592
- retryDelayMs: 1000
41601
+ retryDelayMs: 1000,
41602
+ ackWaitMs: 5 * 60 * 1000
41593
41603
  });
41594
41604
  logger4.info(`Subscribed to ${eventType}.*`, { durable });
41595
41605
  return subscription;
@@ -41876,6 +41886,25 @@ class AutomationEngine {
41876
41886
  status: "skipped",
41877
41887
  conditionsMatched: false,
41878
41888
  actionsExecuted: [],
41889
+ error: describeUnmatchedConditions(conditionResult),
41890
+ executionTimeMs: Date.now() - start
41891
+ };
41892
+ await this.logExecution(result2, trustedTenantId);
41893
+ return result2;
41894
+ }
41895
+ if (this.deps.claimExecution && !await this.deps.claimExecution(event.id, automation.id, trustedTenantId)) {
41896
+ logger4.info("Skipping redelivered event: execution already claimed", {
41897
+ automationId: automation.id,
41898
+ eventId: event.id
41899
+ });
41900
+ const result2 = {
41901
+ automationId: automation.id,
41902
+ automationName: automation.name,
41903
+ eventId: event.id,
41904
+ status: "skipped",
41905
+ conditionsMatched: true,
41906
+ actionsExecuted: [],
41907
+ error: "duplicate delivery: execution already claimed for this event",
41879
41908
  executionTimeMs: Date.now() - start
41880
41909
  };
41881
41910
  await this.logExecution(result2, trustedTenantId);
@@ -70700,6 +70729,7 @@ __export(exports_src, {
70700
70729
  enableDefaultMetrics: () => enableDefaultMetrics,
70701
70730
  disarmSequence: () => disarmSequence,
70702
70731
  detectContentFlags: () => detectContentFlags,
70732
+ describeUnmatchedConditions: () => describeUnmatchedConditions,
70703
70733
  deriveFollowUpFromPayload: () => deriveFollowUpFromPayload,
70704
70734
  decompressPayload: () => decompressPayload,
70705
70735
  deadLettersPending: () => deadLettersPending,
@@ -115685,7 +115715,7 @@ var require_client2 = __commonJS((exports) => {
115685
115715
 
115686
115716
  // ../../node_modules/.bun/@sentry+node-core@10.52.0+2c50d7e904f6cfd7/node_modules/@sentry/node-core/build/cjs/sdk/esmLoader.js
115687
115717
  var require_esmLoader = __commonJS((exports) => {
115688
- var __filename = "/home/runner/work/omni/omni/.stable-source/node_modules/.bun/@sentry+node-core@10.52.0+2c50d7e904f6cfd7/node_modules/@sentry/node-core/build/cjs/sdk/esmLoader.js";
115718
+ var __filename = "/home/runner/work/omni/omni/node_modules/.bun/@sentry+node-core@10.52.0+2c50d7e904f6cfd7/node_modules/@sentry/node-core/build/cjs/sdk/esmLoader.js";
115689
115719
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
115690
115720
  var core = require_cjs();
115691
115721
  var importInTheMiddle = require_import_in_the_middle();
@@ -137109,7 +137139,7 @@ import { fileURLToPath } from "url";
137109
137139
  // package.json
137110
137140
  var package_default = {
137111
137141
  name: "@automagik/omni",
137112
- version: "2.260909.5",
137142
+ version: "2.260910.1",
137113
137143
  repository: {
137114
137144
  type: "git",
137115
137145
  url: "git+https://github.com/automagik-dev/omni.git",
@@ -144020,6 +144050,9 @@ function createSchemaCommand() {
144020
144050
  });
144021
144051
  return schema;
144022
144052
  }
144053
+ function eventListRow(e10) {
144054
+ return { id: e10.id, type: e10.eventType, instanceId: e10.instanceId, direction: e10.direction, receivedAt: e10.receivedAt };
144055
+ }
144023
144056
  var NOISY_EVENT_TYPES = new Set([
144024
144057
  "presence.typing",
144025
144058
  "presence.online",
@@ -144053,19 +144086,55 @@ function passesStreamFilters(event, options) {
144053
144086
  return false;
144054
144087
  return true;
144055
144088
  }
144056
- function formatEventLine(event) {
144089
+ function labelFor(id, names, ids2) {
144090
+ if (!id)
144091
+ return "";
144092
+ const name = ids2 ? undefined : names?.get(id);
144093
+ return name ? name.slice(0, 16) : id.slice(0, 8);
144094
+ }
144095
+ function senderLabel(event, names) {
144096
+ const person2 = event.personId ? names?.persons.get(event.personId) : undefined;
144097
+ return person2 ?? event.rawPayload?.pushName ?? event.metadata?.from ?? "";
144098
+ }
144099
+ function formatEventLine(event, options = {}) {
144100
+ const ids2 = options.ids === true;
144057
144101
  const time = new Date(event.receivedAt).toISOString().slice(11, 19);
144058
- const instance3 = event.instanceId?.slice(0, 8) ?? "--------";
144059
- const chat = event.chatUuid?.slice(0, 8) ?? "--------";
144102
+ const instance3 = labelFor(event.instanceId, options.names?.instances, ids2) || "--------";
144103
+ const chat = labelFor(event.chatUuid, options.names?.chats, ids2) || event.chatId || "--------";
144060
144104
  const summary = event.textContent ?? event.transcription ?? event.imageDescription ?? "";
144061
144105
  const trimmed = summary.length > 80 ? `${summary.slice(0, 77)}...` : summary;
144062
- return `${time} ${event.eventType.padEnd(28)} ${instance3}/${chat} ${event.direction.padEnd(8)} ${trimmed}`.trimEnd();
144106
+ const cols = [time, event.eventType.padEnd(28), `${instance3}/${chat}`, event.direction.padEnd(8)];
144107
+ if (options.verbose) {
144108
+ const fromMe = event.rawPayload?.key?.fromMe === true || event.direction === "outbound";
144109
+ cols.push(fromMe ? "me" : " ", (event.contentType ?? "-").padEnd(8), senderLabel(event, options.names).padEnd(16));
144110
+ }
144111
+ return `${cols.join(" ")} ${trimmed}`.trimEnd();
144063
144112
  }
144064
- function emitStreamEvent(event, ndjson) {
144113
+ async function warmStreamNames(client, names, events2) {
144114
+ const lookup2 = async (map2, id, fetch2) => {
144115
+ if (map2.has(id))
144116
+ return;
144117
+ map2.set(id, await fetch2().catch(() => null));
144118
+ };
144119
+ if (names.instances.size === 0 && events2.length > 0) {
144120
+ const list2 = await client.instances.list({ limit: 100 }).catch(() => ({ items: [] }));
144121
+ for (const i6 of list2.items)
144122
+ names.instances.set(i6.id, i6.name);
144123
+ }
144124
+ for (const ev2 of events2) {
144125
+ if (ev2.chatUuid) {
144126
+ await lookup2(names.chats, ev2.chatUuid, async () => (await client.chats.get(ev2.chatUuid)).name ?? null);
144127
+ }
144128
+ if (ev2.personId) {
144129
+ await lookup2(names.persons, ev2.personId, async () => (await client.persons.get(ev2.personId)).displayName);
144130
+ }
144131
+ }
144132
+ }
144133
+ function emitStreamEvent(event, ndjson, format) {
144065
144134
  if (ndjson) {
144066
144135
  raw(JSON.stringify(event));
144067
144136
  } else {
144068
- raw(formatEventLine(event));
144137
+ raw(formatEventLine(event, format));
144069
144138
  }
144070
144139
  }
144071
144140
  async function fetchStreamBatch(client, filters, channel2, type, sinceIso) {
@@ -144084,15 +144153,18 @@ async function fetchStreamBatch(client, filters, channel2, type, sinceIso) {
144084
144153
  return [];
144085
144154
  }
144086
144155
  }
144087
- function processStreamBatch(items, filters, state, ndjson) {
144156
+ async function processStreamBatch(client, items, filters, state, ndjson, format) {
144088
144157
  const ascending = [...items].sort((a2, b8) => a2.receivedAt.localeCompare(b8.receivedAt));
144158
+ const fresh = ascending.filter((ev2) => !state.seen.has(ev2.id) && passesStreamFilters(ev2, filters));
144159
+ if (!ndjson && !format.ids && format.names)
144160
+ await warmStreamNames(client, format.names, fresh);
144089
144161
  for (const ev2 of ascending) {
144090
144162
  if (state.seen.has(ev2.id))
144091
144163
  continue;
144092
144164
  state.seen.add(ev2.id);
144093
144165
  if (!passesStreamFilters(ev2, filters))
144094
144166
  continue;
144095
- emitStreamEvent(ev2, ndjson);
144167
+ emitStreamEvent(ev2, ndjson, format);
144096
144168
  if (ev2.receivedAt > state.sinceIso)
144097
144169
  state.sinceIso = ev2.receivedAt;
144098
144170
  }
@@ -144118,6 +144190,11 @@ async function streamEvents(client, options) {
144118
144190
  errorsOnly: options.errorsOnly,
144119
144191
  all: options.all
144120
144192
  };
144193
+ const format = {
144194
+ verbose: options.verbose,
144195
+ ids: options.ids,
144196
+ names: { instances: new Map, chats: new Map, persons: new Map }
144197
+ };
144121
144198
  let stopped = false;
144122
144199
  const shutdown = () => {
144123
144200
  stopped = true;
@@ -144130,7 +144207,7 @@ async function streamEvents(client, options) {
144130
144207
  try {
144131
144208
  while (!stopped) {
144132
144209
  const items = await fetchStreamBatch(client, filters, options.channel, options.type, state.sinceIso);
144133
- processStreamBatch(items, filters, state, ndjson);
144210
+ await processStreamBatch(client, items, filters, state, ndjson, format);
144134
144211
  if (stopped)
144135
144212
  break;
144136
144213
  await new Promise((resolve2) => setTimeout(resolve2, pollMs));
@@ -144317,20 +144394,13 @@ function createEventsCommand() {
144317
144394
  until: options.until,
144318
144395
  limit: options.limit
144319
144396
  });
144320
- const items = result.items.map((e10) => ({
144321
- id: e10.id,
144322
- type: e10.eventType,
144323
- instanceId: e10.instanceId,
144324
- direction: e10.direction,
144325
- receivedAt: e10.receivedAt
144326
- }));
144327
- list(items, { emptyMessage: "No events found." });
144397
+ list(result.items.map(eventListRow), { emptyMessage: "No events found.", rawData: result.items });
144328
144398
  } catch (err2) {
144329
144399
  const message2 = err2 instanceof Error ? err2.message : "Unknown error";
144330
144400
  error(`Failed to list events: ${message2}`);
144331
144401
  }
144332
144402
  });
144333
- events2.command("stream").description("Stream events in real-time (tail -f style). Ctrl+C to stop.").option("--instance <id>", "Filter by instance ID").option("--channel <type>", "Filter by channel type").option("--type <type>", "Filter by event type (trailing * = prefix glob, e.g. custom.*)").option("--chat-id <id>", "Filter by chat ID").option("--person-id <id>", "Filter by person ID").option("--since <time>", "Start cursor (e.g., 5min, 24h, 7d, or ISO timestamp)").option("--errors-only", "Show only error/failure events").option("--all", "Include noisy event types (presence, delivered, read, progress)").option("--ndjson", "Emit JSON Lines (one event per line) \u2014 same as global --json in stream mode").option("--poll-ms <n>", "Polling interval in milliseconds", (v4) => Number.parseInt(v4, 10), 2000).action(async (options) => {
144403
+ events2.command("stream").description("Stream events in real-time (tail -f style). Ctrl+C to stop.").option("--instance <id>", "Filter by instance ID").option("--channel <type>", "Filter by channel type").option("--type <type>", "Filter by event type (trailing * = prefix glob, e.g. custom.*)").option("--chat-id <id>", "Filter by chat ID").option("--person-id <id>", "Filter by person ID").option("--since <time>", "Start cursor (e.g., 5min, 24h, 7d, or ISO timestamp)").option("--errors-only", "Show only error/failure events").option("--all", "Include noisy event types (presence, delivered, read, progress)").option("--ndjson", "Emit JSON Lines (one event per line) \u2014 same as global --json in stream mode").option("-v, --verbose", "Add sender, fromMe marker and contentType columns").option("--ids", "Print raw ids instead of resolved instance/chat names").option("--poll-ms <n>", "Polling interval in milliseconds", (v4) => Number.parseInt(v4, 10), 2000).action(async (options) => {
144334
144404
  const client = getClient();
144335
144405
  try {
144336
144406
  await streamEvents(client, options);
@@ -144374,7 +144444,7 @@ function createEventsCommand() {
144374
144444
  error(`Failed to wait for event: ${message2}`);
144375
144445
  }
144376
144446
  });
144377
- events2.command("follow").description("Tail the journal through a durable consumer: resumes from its stored cursor, prints JSON lines, acks as it goes.").requiredOption("--consumer <name>", "Durable consumer to follow (create with: omni events consumers create)").option("--limit <n>", "Max journal rows scanned per pull", (v4) => Number.parseInt(v4, 10), 100).option("--wait-ms <n>", "Server-side long-poll window per pull when idle (max 30000)", (v4) => Number.parseInt(v4, 10), 1e4).option("--no-ack", "Peek: print one page without advancing the cursor, then exit").option("--until-idle", "Exit 0 once caught up with the journal instead of tailing forever").action(async (options) => {
144447
+ events2.command("follow").description("Tail the journal through a durable consumer: resumes from its stored cursor, prints JSON lines, acks as it goes.").requiredOption("--consumer <name>", "Durable consumer to follow (create with: omni events consumers create)").option("--limit <n>", "Max journal rows scanned per pull", (v4) => Number.parseInt(v4, 10), 100).option("--wait-ms <n>", "Server-side long-poll window per pull when idle (max 30000)", (v4) => Number.parseInt(v4, 10), 1e4).option("--no-ack", "Peek: print one page without advancing the cursor, then exit").option("--until-idle", "Exit 0 once caught up with the journal instead of tailing forever").option("--ndjson", "Accepted for symmetry with `events stream` \u2014 follow always emits JSON Lines").action(async (options) => {
144378
144448
  let stopped = false;
144379
144449
  const shutdown = () => {
144380
144450
  stopped = true;
@@ -144426,14 +144496,10 @@ function createEventsCommand() {
144426
144496
  since: options.since ? parseSinceTime(options.since) : undefined,
144427
144497
  limit: options.limit
144428
144498
  });
144429
- const items = result.items.map((e10) => ({
144430
- id: e10.id,
144431
- type: e10.eventType,
144432
- instanceId: e10.instanceId,
144433
- direction: e10.direction,
144434
- receivedAt: e10.receivedAt
144435
- }));
144436
- list(items, { emptyMessage: "No matching events found." });
144499
+ list(result.items.map(eventListRow), {
144500
+ emptyMessage: "No matching events found.",
144501
+ rawData: result.items
144502
+ });
144437
144503
  } catch (err2) {
144438
144504
  const message2 = err2 instanceof Error ? err2.message : "Unknown error";
144439
144505
  error(`Failed to search events: ${message2}`);
@@ -144446,14 +144512,10 @@ function createEventsCommand() {
144446
144512
  search: personId,
144447
144513
  limit: options.limit
144448
144514
  });
144449
- const items = result.items.map((e10) => ({
144450
- id: e10.id,
144451
- type: e10.eventType,
144452
- instanceId: e10.instanceId,
144453
- direction: e10.direction,
144454
- receivedAt: e10.receivedAt
144455
- }));
144456
- list(items, { emptyMessage: `No events found for person: ${personId}` });
144515
+ list(result.items.map(eventListRow), {
144516
+ emptyMessage: `No events found for person: ${personId}`,
144517
+ rawData: result.items
144518
+ });
144457
144519
  } catch (err2) {
144458
144520
  const message2 = err2 instanceof Error ? err2.message : "Unknown error";
144459
144521
  error(`Failed to get timeline: ${message2}`);
@@ -144712,7 +144774,7 @@ function formatTime3(ts) {
144712
144774
  return ts;
144713
144775
  }
144714
144776
  }
144715
- function senderLabel(msg) {
144777
+ function senderLabel2(msg) {
144716
144778
  if (msg.senderDisplayName)
144717
144779
  return msg.senderDisplayName;
144718
144780
  if (msg.isFromMe)
@@ -144774,7 +144836,7 @@ function createHistoryCommand() {
144774
144836
  const rows = messages2.map((msg) => ({
144775
144837
  ID: msg.externalId,
144776
144838
  TIME: formatTime3(msg.platformTimestamp),
144777
- SENDER: senderLabel(msg),
144839
+ SENDER: senderLabel2(msg),
144778
144840
  TYPE: msg.messageType,
144779
144841
  CONTENT: contentPreview(msg, !!options.full)
144780
144842
  }));
@@ -36998,6 +36998,14 @@ function evaluateConditionsWithDetails(conditions, payload, logic = "and") {
36998
36998
  conditions: results
36999
36999
  };
37000
37000
  }
37001
+ function describeUnmatchedConditions(result) {
37002
+ const failed = result.conditions.filter((c) => !c.matched).map((c) => {
37003
+ const expected = c.operator === "exists" || c.operator === "not_exists" ? "" : ` ${JSON.stringify(c.expectedValue)}`;
37004
+ const actual = c.actualValue === undefined ? "condition_field_unresolved" : `actual: ${JSON.stringify(c.actualValue)}`;
37005
+ return `${c.field} ${c.operator}${expected} (${actual})`;
37006
+ });
37007
+ return `conditions_not_matched: ${failed.join("; ")}`;
37008
+ }
37001
37009
  var logger, MAX_REGEX_INPUT_LENGTH = 1e4, MAX_REGEX_PATTERN_LENGTH = 500, DANGEROUS_REGEX_PATTERN;
37002
37010
  var init_conditions = __esm(() => {
37003
37011
  init_logger();
@@ -38407,6 +38415,7 @@ class AutomationEngine {
38407
38415
  releaseIdleTimeoutClaim: deps.releaseIdleTimeoutClaim,
38408
38416
  claimEmittedEvent: deps.claimEmittedEvent,
38409
38417
  releaseEmittedEventClaim: deps.releaseEmittedEventClaim,
38418
+ claimExecution: deps.claimExecution,
38410
38419
  validateEmitEvent: deps.validateEmitEvent
38411
38420
  };
38412
38421
  this.automations = automations.filter((a) => a.enabled);
@@ -38493,7 +38502,8 @@ class AutomationEngine {
38493
38502
  queue: "automation-engine",
38494
38503
  startFrom: "new",
38495
38504
  maxRetries: 3,
38496
- retryDelayMs: 1000
38505
+ retryDelayMs: 1000,
38506
+ ackWaitMs: 5 * 60 * 1000
38497
38507
  });
38498
38508
  logger4.info(`Subscribed to ${eventType}.*`, { durable });
38499
38509
  return subscription;
@@ -38780,6 +38790,25 @@ class AutomationEngine {
38780
38790
  status: "skipped",
38781
38791
  conditionsMatched: false,
38782
38792
  actionsExecuted: [],
38793
+ error: describeUnmatchedConditions(conditionResult),
38794
+ executionTimeMs: Date.now() - start
38795
+ };
38796
+ await this.logExecution(result2, trustedTenantId);
38797
+ return result2;
38798
+ }
38799
+ if (this.deps.claimExecution && !await this.deps.claimExecution(event.id, automation.id, trustedTenantId)) {
38800
+ logger4.info("Skipping redelivered event: execution already claimed", {
38801
+ automationId: automation.id,
38802
+ eventId: event.id
38803
+ });
38804
+ const result2 = {
38805
+ automationId: automation.id,
38806
+ automationName: automation.name,
38807
+ eventId: event.id,
38808
+ status: "skipped",
38809
+ conditionsMatched: true,
38810
+ actionsExecuted: [],
38811
+ error: "duplicate delivery: execution already claimed for this event",
38783
38812
  executionTimeMs: Date.now() - start
38784
38813
  };
38785
38814
  await this.logExecution(result2, trustedTenantId);
@@ -44234,6 +44263,7 @@ __export(exports_src, {
44234
44263
  enableDefaultMetrics: () => enableDefaultMetrics,
44235
44264
  disarmSequence: () => disarmSequence,
44236
44265
  detectContentFlags: () => detectContentFlags,
44266
+ describeUnmatchedConditions: () => describeUnmatchedConditions,
44237
44267
  deriveFollowUpFromPayload: () => deriveFollowUpFromPayload,
44238
44268
  decompressPayload: () => decompressPayload,
44239
44269
  deadLettersPending: () => deadLettersPending,
@@ -76868,7 +76898,7 @@ var require_ClientVoiceManager = __commonJS((exports, module) => {
76868
76898
 
76869
76899
  // ../../node_modules/.bun/@discordjs+ws@1.2.3/node_modules/@discordjs/ws/dist/index.js
76870
76900
  var require_dist9 = __commonJS((exports, module) => {
76871
- var __dirname = "/home/runner/work/omni/omni/.stable-source/node_modules/.bun/@discordjs+ws@1.2.3/node_modules/@discordjs/ws/dist";
76901
+ var __dirname = "/home/runner/work/omni/omni/node_modules/.bun/@discordjs+ws@1.2.3/node_modules/@discordjs/ws/dist";
76872
76902
  var __create2 = Object.create;
76873
76903
  var __defProp2 = Object.defineProperty;
76874
76904
  var __getOwnPropDesc2 = Object.getOwnPropertyDescriptor;
@@ -162148,7 +162178,7 @@ var require_indexes = __commonJS((exports, module) => {
162148
162178
 
162149
162179
  // ../../node_modules/.bun/thread-stream@3.1.0/node_modules/thread-stream/index.js
162150
162180
  var require_thread_stream = __commonJS((exports, module) => {
162151
- var __dirname = "/home/runner/work/omni/omni/.stable-source/node_modules/.bun/thread-stream@3.1.0/node_modules/thread-stream";
162181
+ var __dirname = "/home/runner/work/omni/omni/node_modules/.bun/thread-stream@3.1.0/node_modules/thread-stream";
162152
162182
  var { version } = require_package5();
162153
162183
  var { EventEmitter: EventEmitter3 } = __require("events");
162154
162184
  var { Worker } = __require("worker_threads");
@@ -162569,7 +162599,7 @@ var require_thread_stream = __commonJS((exports, module) => {
162569
162599
 
162570
162600
  // ../../node_modules/.bun/pino@9.14.0/node_modules/pino/lib/transport.js
162571
162601
  var require_transport2 = __commonJS((exports, module) => {
162572
- var __dirname = "/home/runner/work/omni/omni/.stable-source/node_modules/.bun/pino@9.14.0/node_modules/pino/lib";
162602
+ var __dirname = "/home/runner/work/omni/omni/node_modules/.bun/pino@9.14.0/node_modules/pino/lib";
162573
162603
  var { createRequire: createRequire2 } = __require("module");
162574
162604
  var getCallers = require_caller();
162575
162605
  var { join: join8, isAbsolute, sep: sep2 } = __require("path");
@@ -244313,7 +244343,7 @@ var require_client3 = __commonJS((exports) => {
244313
244343
 
244314
244344
  // ../../node_modules/.bun/@sentry+node-core@10.52.0+2c50d7e904f6cfd7/node_modules/@sentry/node-core/build/cjs/sdk/esmLoader.js
244315
244345
  var require_esmLoader = __commonJS((exports) => {
244316
- var __filename = "/home/runner/work/omni/omni/.stable-source/node_modules/.bun/@sentry+node-core@10.52.0+2c50d7e904f6cfd7/node_modules/@sentry/node-core/build/cjs/sdk/esmLoader.js";
244346
+ var __filename = "/home/runner/work/omni/omni/node_modules/.bun/@sentry+node-core@10.52.0+2c50d7e904f6cfd7/node_modules/@sentry/node-core/build/cjs/sdk/esmLoader.js";
244317
244347
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
244318
244348
  var core3 = require_cjs6();
244319
244349
  var importInTheMiddle = require_import_in_the_middle();
@@ -251539,7 +251569,7 @@ var init_sentry_scrub = __esm(() => {
251539
251569
  var require_package7 = __commonJS((exports, module) => {
251540
251570
  module.exports = {
251541
251571
  name: "@omni/api",
251542
- version: "2.260909.5",
251572
+ version: "2.260910.1",
251543
251573
  private: true,
251544
251574
  type: "module",
251545
251575
  exports: {
@@ -278641,7 +278671,7 @@ var require_src45 = __commonJS((exports) => {
278641
278671
 
278642
278672
  // ../../node_modules/.bun/@grpc+grpc-js@1.14.3/node_modules/@grpc/grpc-js/build/src/channelz.js
278643
278673
  var require_channelz = __commonJS((exports) => {
278644
- var __dirname = "/home/runner/work/omni/omni/.stable-source/node_modules/.bun/@grpc+grpc-js@1.14.3/node_modules/@grpc/grpc-js/build/src";
278674
+ var __dirname = "/home/runner/work/omni/omni/node_modules/.bun/@grpc+grpc-js@1.14.3/node_modules/@grpc/grpc-js/build/src";
278645
278675
  Object.defineProperty(exports, "__esModule", { value: true });
278646
278676
  exports.registerChannelzSocket = exports.registerChannelzServer = exports.registerChannelzSubchannel = exports.registerChannelzChannel = exports.ChannelzCallTrackerStub = exports.ChannelzCallTracker = exports.ChannelzChildrenTrackerStub = exports.ChannelzChildrenTracker = exports.ChannelzTrace = exports.ChannelzTraceStub = undefined;
278647
278677
  exports.unregisterChannelzRef = unregisterChannelzRef;
@@ -284044,7 +284074,7 @@ var require_duration = __commonJS((exports) => {
284044
284074
 
284045
284075
  // ../../node_modules/.bun/@grpc+grpc-js@1.14.3/node_modules/@grpc/grpc-js/build/src/orca.js
284046
284076
  var require_orca = __commonJS((exports) => {
284047
- var __dirname = "/home/runner/work/omni/omni/.stable-source/node_modules/.bun/@grpc+grpc-js@1.14.3/node_modules/@grpc/grpc-js/build/src";
284077
+ var __dirname = "/home/runner/work/omni/omni/node_modules/.bun/@grpc+grpc-js@1.14.3/node_modules/@grpc/grpc-js/build/src";
284048
284078
  Object.defineProperty(exports, "__esModule", { value: true });
284049
284079
  exports.OrcaOobMetricsSubchannelWrapper = exports.GRPC_METRICS_HEADER = exports.ServerMetricRecorder = exports.PerRequestMetricRecorder = undefined;
284050
284080
  exports.createOrcaClient = createOrcaClient;
@@ -313067,6 +313097,7 @@ var init_scopes = __esm(() => {
313067
313097
  "PATCH /access/rules/:id": "access:write",
313068
313098
  "DELETE /access/rules/:id": "access:write",
313069
313099
  "POST /access/check": "access:read",
313100
+ "GET /access": "access:read",
313070
313101
  "GET /instances/:instanceId/routes": "routes:read",
313071
313102
  "GET /instances/:instanceId/routes/:id": "routes:read",
313072
313103
  "POST /instances/:instanceId/routes": "routes:write",
@@ -313087,7 +313118,7 @@ var init_scopes = __esm(() => {
313087
313118
  "PATCH /agents/:id": "agents:write",
313088
313119
  "DELETE /agents/:id": "agents:write",
313089
313120
  "GET /agents/:id/identities": "agents:read",
313090
- "POST /agents/:id/identities": "agents:write",
313121
+ "POST /agents/:id/identities/link": "agents:write",
313091
313122
  "GET /agents/:id/manifest": "agents:read",
313092
313123
  "PUT /agents/:id/manifest": "agents:write",
313093
313124
  "GET /agents/:id/tasks": "agents:read",
@@ -313113,6 +313144,9 @@ var init_scopes = __esm(() => {
313113
313144
  "GET /chats": "chats:read",
313114
313145
  "POST /chats": "chats:write",
313115
313146
  "GET /chats/:id": "chats:read",
313147
+ "PATCH /chats/:id/participants/:platformUserId/role": "chats:write",
313148
+ "POST /chats/:id/reopen-contact": "chats:write",
313149
+ "POST /chats/clear-session": "chats:write",
313116
313150
  "PATCH /chats/:id": "chats:write",
313117
313151
  "DELETE /chats/:id": "chats:write",
313118
313152
  "POST /chats/:id/archive": "chats:write",
@@ -313128,7 +313162,6 @@ var init_scopes = __esm(() => {
313128
313162
  "GET /chats/:id/participants": "chats:read",
313129
313163
  "POST /chats/:id/participants": "chats:write",
313130
313164
  "DELETE /chats/:id/participants/:platformUserId": "chats:write",
313131
- "PATCH /chats/:id/participants/:platformUserId": "chats:write",
313132
313165
  "GET /chats/:id/messages": "chats:read",
313133
313166
  "GET /chats/by-external": "chats:read",
313134
313167
  "POST /chats/:id/read": "chats:write",
@@ -313163,6 +313196,11 @@ var init_scopes = __esm(() => {
313163
313196
  "GET /events/schemas": "events:read",
313164
313197
  "GET /events/schemas/:eventType": "events:read",
313165
313198
  "POST /events/schemas": "events:write",
313199
+ "GET /events/consumers/:name": "events:read",
313200
+ "POST /events/consumers": "events:write",
313201
+ "DELETE /events/consumers/:name": "events:write",
313202
+ "POST /events/consumers/:name/pull": "events:write",
313203
+ "POST /events/consumers/:name/ack": "events:write",
313166
313204
  "GET /events": "events:read",
313167
313205
  "GET /events/analytics": "events:read",
313168
313206
  "GET /events/timeline/:personId": "events:read",
@@ -313219,6 +313257,16 @@ var init_scopes = __esm(() => {
313219
313257
  "POST /instances/:id/groups/:groupJid/invite/revoke": "instances:write",
313220
313258
  "POST /instances/:id/groups/join": "instances:write",
313221
313259
  "PUT /instances/:id/groups/:groupJid/picture": "instances:write",
313260
+ "PUT /instances/:id/groups/:groupJid/subject": "instances:write",
313261
+ "POST /instances/:id/groups/:groupJid/subject": "instances:write",
313262
+ "PUT /instances/:id/groups/:groupJid/description": "instances:write",
313263
+ "POST /instances/:id/groups/:groupJid/description": "instances:write",
313264
+ "POST /instances/:id/groups/:groupJid/settings": "instances:write",
313265
+ "PATCH /instances/:id/groups/:groupJid": "instances:write",
313266
+ "POST /instances/:id/groups/:groupJid/participants": "instances:write",
313267
+ "PATCH /instances/:id/groups/:groupJid/participants": "instances:write",
313268
+ "POST /instances/:id/groups/:groupJid/participants/:action": "instances:write",
313269
+ "POST /instances/:id/groups/:groupJid/leave": "instances:write",
313222
313270
  "GET /instances/:id/privacy": "instances:read",
313223
313271
  "POST /instances/:id/calls/reject": "instances:write",
313224
313272
  "POST /instances/:id/resync": "instances:write",
@@ -313247,12 +313295,14 @@ var init_scopes = __esm(() => {
313247
313295
  "POST /media/imagine": "media:write",
313248
313296
  "POST /media/vision": "media:read",
313249
313297
  "POST /media/film": "media:write",
313298
+ "POST /media/music": "media:write",
313250
313299
  "GET /media/:instanceId/*": "media:read",
313251
313300
  "GET /messages": "messages:read",
313252
313301
  "GET /messages/by-external": "messages:read",
313253
313302
  "POST /messages/media/download": "messages:read",
313254
313303
  "POST /messages": "messages:write",
313255
313304
  "GET /messages/:id": "messages:read",
313305
+ "GET /messages/:id/permalink": "messages:read",
313256
313306
  "PATCH /messages/:id": "messages:write",
313257
313307
  "DELETE /messages/:id": "messages:write",
313258
313308
  "POST /messages/:id/edit": "messages:write",
@@ -313269,6 +313319,8 @@ var init_scopes = __esm(() => {
313269
313319
  "POST /messages/send/sticker": "messages:send",
313270
313320
  "POST /messages/send/contact": "messages:send",
313271
313321
  "POST /messages/send/location": "messages:send",
313322
+ "POST /messages/send/handoff": "messages:send",
313323
+ "POST /messages/send/close-contact": "messages:send",
313272
313324
  "GET /messages/tts/voices": "messages:read",
313273
313325
  "POST /messages/send/tts": "messages:send",
313274
313326
  "POST /messages/send/forward": "messages:send",
@@ -313281,6 +313333,12 @@ var init_scopes = __esm(() => {
313281
313333
  "POST /messages/delete-channel": "messages:send",
313282
313334
  "POST /messages/:id/star": "messages:write",
313283
313335
  "DELETE /messages/:id/star": "messages:write",
313336
+ "GET /scheduled-messages": "messages:read",
313337
+ "GET /scheduled-messages/:id": "messages:read",
313338
+ "POST /scheduled-messages": "messages:send",
313339
+ "DELETE /scheduled-messages/:id": "messages:send",
313340
+ "GET /slack/search": "messages:read",
313341
+ "POST /slack/dm/open": "messages:send",
313284
313342
  "GET /metrics": "metrics:read",
313285
313343
  "GET /events/:eventId/payloads": "payloads:read",
313286
313344
  "GET /events/:eventId/payloads/:stage": "payloads:read",
@@ -313361,6 +313419,7 @@ var init_scopes = __esm(() => {
313361
313419
  "PATCH /webhook-sources/:id": "webhooks:write",
313362
313420
  "DELETE /webhook-sources/:id": "webhooks:write",
313363
313421
  "POST /webhooks/:source": "webhooks:write",
313422
+ "POST /webhooks/:source/heartbeat": "webhooks:write",
313364
313423
  "POST /events/trigger": "events:write"
313365
313424
  };
313366
313425
  });
@@ -363791,6 +363850,39 @@ async function handleMessagePinState(services, event, pinned) {
363791
363850
  });
363792
363851
  }
363793
363852
  }
363853
+ async function handleReactionState(services, event, added) {
363854
+ const payload = event.payload;
363855
+ const metadata = event.metadata;
363856
+ if (!metadata.instanceId)
363857
+ return;
363858
+ const instanceId = metadata.instanceId;
363859
+ try {
363860
+ await runConsumerInTenantContext(services.db, event, async () => {
363861
+ const chat2 = await services.chats.findByExternalIdSmart(instanceId, payload.chatId);
363862
+ const message2 = chat2 ? await services.messages.getByExternalId(chat2.id, payload.messageId) : null;
363863
+ if (!message2) {
363864
+ log90.debug("Target message not found for reaction", { chatId: payload.chatId, messageId: payload.messageId });
363865
+ return;
363866
+ }
363867
+ if (added) {
363868
+ await services.messages.addReaction(message2.id, {
363869
+ emoji: payload.emoji,
363870
+ platformUserId: payload.from,
363871
+ isCustomEmoji: payload.isCustomEmoji,
363872
+ customEmojiId: payload.isCustomEmoji ? payload.emoji : undefined
363873
+ }, event.id);
363874
+ } else {
363875
+ await services.messages.removeReaction(message2.id, payload.from, payload.emoji, event.id);
363876
+ }
363877
+ log90.debug("Updated message reactions", { messageId: message2.id, emoji: payload.emoji, added });
363878
+ });
363879
+ } catch (error3) {
363880
+ log90.error("Failed to update message reactions", {
363881
+ messageId: payload.messageId,
363882
+ error: String(error3)
363883
+ });
363884
+ }
363885
+ }
363794
363886
  async function setupMessagePersistence(eventBus, services) {
363795
363887
  try {
363796
363888
  await eventBus.subscribe("message.received", async (event) => {
@@ -363988,6 +364080,22 @@ async function setupMessagePersistence(eventBus, services) {
363988
364080
  startFrom: "first",
363989
364081
  concurrency: 10
363990
364082
  });
364083
+ await eventBus.subscribe("reaction.received", (event) => handleReactionState(services, event, true), {
364084
+ durable: "message-persistence-reaction-received",
364085
+ queue: "message-persistence",
364086
+ maxRetries: 2,
364087
+ retryDelayMs: 500,
364088
+ startFrom: "first",
364089
+ concurrency: 10
364090
+ });
364091
+ await eventBus.subscribe("reaction.removed", (event) => handleReactionState(services, event, false), {
364092
+ durable: "message-persistence-reaction-removed",
364093
+ queue: "message-persistence",
364094
+ maxRetries: 2,
364095
+ retryDelayMs: 500,
364096
+ startFrom: "first",
364097
+ concurrency: 10
364098
+ });
363991
364099
  await eventBus.subscribe("instance.connected", async (event) => {
363992
364100
  const payload = event.payload;
363993
364101
  const instanceId = payload.instanceId;
@@ -372279,13 +372387,15 @@ class MessageService {
372279
372387
  async removeReaction(id, platformUserId, emoji, latestEventId) {
372280
372388
  const message2 = await this.getById(id);
372281
372389
  const currentReactions = message2.reactions ?? [];
372282
- const newReactions = currentReactions.filter((r) => !(r.platformUserId === platformUserId && r.emoji === emoji));
372390
+ const newReactions = currentReactions.filter((r) => !(r.platformUserId === platformUserId && (emoji === "" || r.emoji === emoji)));
372283
372391
  const currentCounts = message2.reactionCounts ?? {};
372284
372392
  const newCounts = { ...currentCounts };
372285
- if (newCounts[emoji]) {
372286
- newCounts[emoji] = Math.max(0, newCounts[emoji] - 1);
372287
- if (newCounts[emoji] === 0) {
372288
- delete newCounts[emoji];
372393
+ for (const removed of currentReactions.filter((r) => !newReactions.includes(r))) {
372394
+ const count3 = (newCounts[removed.emoji] ?? 0) - 1;
372395
+ if (count3 > 0) {
372396
+ newCounts[removed.emoji] = count3;
372397
+ } else {
372398
+ delete newCounts[removed.emoji];
372289
372399
  }
372290
372400
  }
372291
372401
  const [updated] = await this.db.update(messages2).set({
@@ -384599,7 +384709,7 @@ var init_automations4 = __esm(() => {
384599
384709
  init_zod();
384600
384710
  automationsRoutes = new Hono2;
384601
384711
  conditionSchema = exports_external.object({
384602
- field: exports_external.string().min(1).describe("Dot notation field path (e.g., payload.content.type)"),
384712
+ field: exports_external.string().min(1).describe("Dot notation path into the event payload (e.g., content.type, pull_request.merged)"),
384603
384713
  operator: exports_external.enum(["eq", "neq", "gt", "lt", "gte", "lte", "contains", "not_contains", "exists", "not_exists", "regex"]).describe("Comparison operator"),
384604
384714
  value: exports_external.unknown().optional().describe("Value to compare against")
384605
384715
  });
@@ -397577,7 +397687,7 @@ async function setupEventPersistence(eventBus, db2) {
397577
397687
  personId: metadata.personId,
397578
397688
  platformIdentityId: metadata.platformIdentityId,
397579
397689
  eventType: "message.received",
397580
- direction: "inbound",
397690
+ direction: payload.rawPayload?.isFromMe === true ? "outbound" : "inbound",
397581
397691
  contentType: mapContentType2(payload.content.type),
397582
397692
  textContent: sanitizeText(payload.content.text),
397583
397693
  mediaUrl: payload.content.mediaUrl,
@@ -399948,6 +400058,10 @@ function buildAutomationEngineDeps(services, db3, options = {}) {
399948
400058
  return services.followUpLifecycle.evaluateIdleTimeoutFreshness(chatId, instanceId, eventSequenceIndex, trustedTenantId);
399949
400059
  },
399950
400060
  releaseIdleTimeoutClaim: (claimToken) => releaseIdleTimeoutClaim(claimToken),
400061
+ claimExecution: async (eventId, automationId) => {
400062
+ const claim = await db3.insert(processedEvents).values({ eventId, handler: `automation:${automationId}` }).onConflictDoNothing().returning({ eventId: processedEvents.eventId });
400063
+ return claim.length > 0;
400064
+ },
399951
400065
  claimEmittedEvent: async (claim, trustedTenantId = null) => {
399952
400066
  const claimed = await runTenantWorkDb(db3, trustedTenantId, () => scopedHandle(db3).insert(omniEvents).values({
399953
400067
  id: claim.eventId,
@@ -407298,23 +407412,6 @@ class DiscordPlugin extends BaseChannelPlugin {
407298
407412
  isCustomEmoji: false
407299
407413
  });
407300
407414
  }
407301
- if (process.env.OMNI_DUAL_EMIT_REACTIONS !== "false") {
407302
- await this.emitMessageReceived({
407303
- instanceId,
407304
- externalId: `${messageId}-reaction-${Date.now()}`,
407305
- chatId,
407306
- from: userId,
407307
- content: {
407308
- type: "reaction",
407309
- text: emoji
407310
- },
407311
- rawPayload: {
407312
- targetMessageId: messageId,
407313
- action,
407314
- emoji
407315
- }
407316
- });
407317
- }
407318
407415
  }
407319
407416
  async handleMessageEdited(instanceId, messageId, chatId, newText) {
407320
407417
  await this.emitMessageReceived({
@@ -529352,6 +529449,14 @@ function summarizeContent(content) {
529352
529449
  }
529353
529450
  return summary;
529354
529451
  }
529452
+ function getOrCreate(outer, key) {
529453
+ let inner = outer.get(key);
529454
+ if (!inner) {
529455
+ inner = new Map;
529456
+ outer.set(key, inner);
529457
+ }
529458
+ return inner;
529459
+ }
529355
529460
 
529356
529461
  class WhatsAppPlugin extends BaseChannelPlugin {
529357
529462
  id = "whatsapp-baileys";
@@ -529455,6 +529560,8 @@ class WhatsAppPlugin extends BaseChannelPlugin {
529455
529560
  }
529456
529561
  lidFirstEnabledMap = new Map;
529457
529562
  lidMappingCache = new Map;
529563
+ publishedLidMappings = new Map;
529564
+ publishedContactNames = new Map;
529458
529565
  recentMessageKeys = new Map;
529459
529566
  static MESSAGE_KEY_CACHE_TTL_MS = 60000;
529460
529567
  storeLidMapping(instanceId, lidJid, phoneJid) {
@@ -529831,6 +529938,8 @@ class WhatsAppPlugin extends BaseChannelPlugin {
529831
529938
  this.decryptTrackers.delete(instanceId);
529832
529939
  this.lidFirstEnabledMap.delete(instanceId);
529833
529940
  this.lidMappingCache.delete(instanceId);
529941
+ this.publishedLidMappings.delete(instanceId);
529942
+ this.publishedContactNames.delete(instanceId);
529834
529943
  this.lastActionTime.delete(instanceId);
529835
529944
  this.historyPushFetchCount.delete(instanceId);
529836
529945
  this.dedupeCaches.get(instanceId)?.dispose();
@@ -531176,19 +531285,6 @@ class WhatsAppPlugin extends BaseChannelPlugin {
531176
531285
  emoji: ""
531177
531286
  });
531178
531287
  }
531179
- if (process.env.OMNI_DUAL_EMIT_REACTIONS !== "false" && !isFromMe2) {
531180
- await this.emitMessageReceived({
531181
- instanceId,
531182
- externalId,
531183
- chatId,
531184
- from,
531185
- content: {
531186
- type: "reaction",
531187
- text: emoji
531188
- },
531189
- rawPayload: { targetMessageId, isFromMe: isFromMe2 }
531190
- });
531191
- }
531192
531288
  }
531193
531289
  async handleMessageDelivered(instanceId, externalId, chatId) {
531194
531290
  await this.emitMessageDelivered({
@@ -531423,11 +531519,15 @@ class WhatsAppPlugin extends BaseChannelPlugin {
531423
531519
  const contactCache = this.contactsCache.get(instanceId);
531424
531520
  if (!contactCache || contactCache.size === 0)
531425
531521
  return;
531522
+ const published = getOrCreate(this.publishedContactNames, instanceId);
531426
531523
  const names = [];
531427
531524
  for (const [jid, contact] of contactCache) {
531428
- if (contact.name && !jid.includes("@g.us") && !jid.includes("@broadcast")) {
531429
- names.push({ jid, name: contact.name });
531430
- }
531525
+ if (!contact.name || jid.includes("@g.us") || jid.includes("@broadcast"))
531526
+ continue;
531527
+ if (published.get(jid) === contact.name)
531528
+ continue;
531529
+ published.set(jid, contact.name);
531530
+ names.push({ jid, name: contact.name });
531431
531531
  }
531432
531532
  if (names.length === 0)
531433
531533
  return;
@@ -531442,7 +531542,16 @@ class WhatsAppPlugin extends BaseChannelPlugin {
531442
531542
  const lidCache = this.lidMappingCache.get(instanceId);
531443
531543
  if (!lidCache || lidCache.size === 0)
531444
531544
  return;
531445
- const mappings = Array.from(lidCache.entries()).filter(([key]) => isLidJid(key)).map(([lidJid, phoneJid]) => ({ lidJid, phoneJid }));
531545
+ const published = getOrCreate(this.publishedLidMappings, instanceId);
531546
+ const mappings = [];
531547
+ for (const [lidJid, phoneJid] of lidCache) {
531548
+ if (!isLidJid(lidJid) || published.get(lidJid) === phoneJid)
531549
+ continue;
531550
+ published.set(lidJid, phoneJid);
531551
+ mappings.push({ lidJid, phoneJid });
531552
+ }
531553
+ if (mappings.length === 0)
531554
+ return;
531446
531555
  this.eventBus.publishGeneric("custom.lid-mapping.batch", { mappings }, { instanceId, channelType: this.id, source: `channel:${this.id}`, correlationId: `lid-batch-${instanceId}` }).catch((err2) => this.logger.warn("Failed to publish LID mappings", { error: String(err2) }));
531447
531556
  }
531448
531557
  handleContactsUpdate(instanceId, updates) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@automagik/omni",
3
- "version": "2.260909.5",
3
+ "version": "2.260910.1",
4
4
  "repository": {
5
5
  "type": "git",
6
6
  "url": "git+https://github.com/automagik-dev/omni.git",