@automagik/omni 2.260909.4 → 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.
- package/dist/commands/events.d.ts +45 -1
- package/dist/commands/events.d.ts.map +1 -1
- package/dist/index.js +101 -39
- package/dist/server/index.js +154 -45
- package/package.json +1 -1
|
@@ -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:
|
|
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":"AAAA;;;;;;;;GAQG;AAIH,OAAO,EAAE,KAAK,mBAAmB,EAAsB,MAAM,YAAY,CAAC;AAC1E,OAAO,KAAK,EAAE,KAAK,EAAE,UAAU,EAAE,MAAM,WAAW,CAAC;AACnD,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAuMpC,2DAA2D;AAC3D,UAAU,UAAU;IAClB,EAAE,EAAE,MAAM,CAAC;IACX,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,MAAM,CAAC;IACnB,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,QAAQ,CAAC,EAAE;QAAE,aAAa,CAAC,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI,CAAC;IAC7C,WAAW,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CAC7B;AA+BD,wEAAwE;AACxE,wBAAgB,eAAe,CAAC,KAAK,EAAE,UAAU,EAAE,MAAM,EAAE,MAAM,GAAG,MAAM,CAKzE;AAyCD,wDAAwD;AACxD,UAAU,eAAe;IACvB,EAAE,EAAE,MAAM,CAAC;IACX,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAChC,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,OAAO,EAAE,OAAO,CAAC;IACjB,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;CACnB;AAED;;;GAGG;AACH,iBAAe,gBAAgB,CAAC,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,GAAE;IAAE,MAAM,CAAC,EAAE,MAAM,CAAC;IAAC,IAAI,CAAC,EAAE,MAAM,CAAA;CAAO,GAAG,OAAO,CAAC,CAAC,CAAC,CAe1G;AAED,kFAAkF;AAClF,iBAAS,kBAAkB,CAAC,OAAO,EAAE;IAAE,IAAI,CAAC,EAAE,MAAM,CAAC;IAAC,MAAM,CAAC,EAAE,MAAM,CAAA;CAAE,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAUhG;AAED,iBAAS,kBAAkB,CAAC,GAAG,EAAE,eAAe,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAQzE;AAyED,eAAO,MAAM,WAAW;;;;CAA+D,CAAC;
|
|
1
|
+
{"version":3,"file":"events.d.ts","sourceRoot":"","sources":["../../src/commands/events.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAIH,OAAO,EAAE,KAAK,mBAAmB,EAAsB,MAAM,YAAY,CAAC;AAC1E,OAAO,KAAK,EAAE,KAAK,EAAE,UAAU,EAAE,MAAM,WAAW,CAAC;AACnD,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAuMpC,2DAA2D;AAC3D,UAAU,UAAU;IAClB,EAAE,EAAE,MAAM,CAAC;IACX,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,MAAM,CAAC;IACnB,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,QAAQ,CAAC,EAAE;QAAE,aAAa,CAAC,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI,CAAC;IAC7C,WAAW,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CAC7B;AA+BD,wEAAwE;AACxE,wBAAgB,eAAe,CAAC,KAAK,EAAE,UAAU,EAAE,MAAM,EAAE,MAAM,GAAG,MAAM,CAKzE;AAyCD,wDAAwD;AACxD,UAAU,eAAe;IACvB,EAAE,EAAE,MAAM,CAAC;IACX,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAChC,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,OAAO,EAAE,OAAO,CAAC;IACjB,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;CACnB;AAED;;;GAGG;AACH,iBAAe,gBAAgB,CAAC,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,GAAE;IAAE,MAAM,CAAC,EAAE,MAAM,CAAC;IAAC,IAAI,CAAC,EAAE,MAAM,CAAA;CAAO,GAAG,OAAO,CAAC,CAAC,CAAC,CAe1G;AAED,kFAAkF;AAClF,iBAAS,kBAAkB,CAAC,OAAO,EAAE;IAAE,IAAI,CAAC,EAAE,MAAM,CAAC;IAAC,MAAM,CAAC,EAAE,MAAM,CAAA;CAAE,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAUhG;AAED,iBAAS,kBAAkB,CAAC,GAAG,EAAE,eAAe,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAQzE;AAyED,eAAO,MAAM,WAAW;;;;CAA+D,CAAC;AAExF;;;;GAIG;AACH,wBAAgB,YAAY,CAAC,CAAC,EAAE,KAAK,GAAG;IACtC,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,UAAU,EAAE,MAAM,CAAC;IACnB,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,MAAM,CAAC;CACpB,CAEA;AAoBD,6EAA6E;AAC7E,wBAAgB,YAAY,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAEvD;AAED,yFAAyF;AACzF,wBAAgB,YAAY,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAEvD;AAED;;;;;GAKG;AACH,wBAAgB,sBAAsB,CAAC,SAAS,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAEjF;AAED,iFAAiF;AACjF,MAAM,WAAW,mBAAmB;IAClC,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,GAAG,CAAC,EAAE,OAAO,CAAC;CACf;AAED;;;;;GAKG;AACH,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,KAAK,EAAE,OAAO,EAAE,mBAAmB,GAAG,OAAO,CAQvF;AAED;;;;GAIG;AACH,MAAM,MAAM,cAAc,GAAG,KAAK,GAAG;IACnC,MAAM,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACvB,QAAQ,CAAC,EAAE;QAAE,IAAI,CAAC,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI,CAAC;IACpC,UAAU,CAAC,EAAE;QAAE,QAAQ,CAAC,EAAE,MAAM,CAAC;QAAC,GAAG,CAAC,EAAE;YAAE,MAAM,CAAC,EAAE,OAAO,CAAA;SAAE,CAAA;KAAE,GAAG,IAAI,CAAC;CACvE,CAAC;AAEF,gFAAgF;AAChF,MAAM,WAAW,WAAW;IAC1B,SAAS,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC,CAAC;IACtC,KAAK,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC,CAAC;IAClC,OAAO,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC,CAAC;CACrC;AAED,MAAM,WAAW,iBAAiB;IAChC,+DAA+D;IAC/D,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,4EAA4E;IAC5E,GAAG,CAAC,EAAE,OAAO,CAAC;IACd,KAAK,CAAC,EAAE,WAAW,CAAC;CACrB;AAQD,mFAAmF;AACnF,wBAAgB,WAAW,CAAC,KAAK,EAAE,cAAc,EAAE,KAAK,CAAC,EAAE,WAAW,GAAG,MAAM,CAG9E;AAED,uDAAuD;AACvD,wBAAgB,eAAe,CAAC,KAAK,EAAE,cAAc,EAAE,OAAO,GAAE,iBAAsB,GAAG,MAAM,CAc9F;AA6KD;;;;;;GAMG;AACH,KAAK,YAAY,GAAG,KAAK,GAAG;IAAE,UAAU,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAAA;CAAE,CAAC;AAc5E;;;;;GAKG;AACH,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,MAAM,EAAE,GAAG,mBAAmB,EAAE,CAYzE;AAED,UAAU,UAAU;IAClB,OAAO,EAAE,mBAAmB,CAAC;IAC7B,UAAU,EAAE,mBAAmB,EAAE,CAAC;IAClC,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,MAAM,CAAC;IACf,gEAAgE;IAChE,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,gFAAgF;AAChF,wBAAgB,gBAAgB,CAC9B,KAAK,EAAE,YAAY,EACnB,OAAO,EAAE,mBAAmB,EAC5B,UAAU,EAAE,mBAAmB,EAAE,GAChC,OAAO,CAGT;AAED;;;;;GAKG;AACH,wBAAsB,YAAY,CAAC,MAAM,EAAE,UAAU,EAAE,MAAM,EAAE,UAAU,GAAG,OAAO,CAAC,YAAY,GAAG,IAAI,CAAC,CA4BvG;AAMD,0EAA0E;AAC1E,UAAU,YAAY;IACpB,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,mBAAmB,EAAE,GAAG,IAAI,CAAC;IACtC,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,MAAM,CAAC;IACb,GAAG,EAAE,MAAM,CAAC;IACZ,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;CACnB;AAWD;;;;GAIG;AACH,wBAAsB,mBAAmB,CAAC,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,GAAE;IAAE,MAAM,CAAC,EAAE,MAAM,CAAC;IAAC,IAAI,CAAC,EAAE,MAAM,CAAA;CAAO,GAAG,OAAO,CAAC,CAAC,CAAC,CAepH;AAED,wBAAgB,oBAAoB,CAAC,GAAG,EAAE,YAAY,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAW/E;AAED,MAAM,WAAW,YAAY;IAC3B,QAAQ,EAAE,MAAM,CAAC;IACjB,sCAAsC;IACtC,KAAK,EAAE,MAAM,CAAC;IACd,sEAAsE;IACtE,MAAM,EAAE,MAAM,CAAC;IACf,sFAAsF;IACtF,GAAG,EAAE,OAAO,CAAC;IACb,8EAA8E;IAC9E,SAAS,EAAE,OAAO,CAAC;IACnB,qCAAqC;IACrC,SAAS,CAAC,EAAE,MAAM,OAAO,CAAC;IAC1B,sEAAsE;IACtE,IAAI,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;CAC/B;AAED;;;;;;;;GAQG;AACH,wBAAsB,cAAc,CAAC,MAAM,EAAE,YAAY,GAAG,OAAO,CAAC,IAAI,CAAC,CA+CxE;AAqFD,wBAAgB,mBAAmB,IAAI,OAAO,CA8W7C"}
|
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,
|
|
@@ -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.
|
|
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
|
|
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?.
|
|
144059
|
-
const chat = event.chatUuid?.
|
|
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
|
-
|
|
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
|
|
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
|
-
|
|
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
|
-
|
|
144430
|
-
|
|
144431
|
-
|
|
144432
|
-
|
|
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
|
-
|
|
144450
|
-
|
|
144451
|
-
|
|
144452
|
-
|
|
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
|
|
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:
|
|
144839
|
+
SENDER: senderLabel2(msg),
|
|
144778
144840
|
TYPE: msg.messageType,
|
|
144779
144841
|
CONTENT: contentPreview(msg, !!options.full)
|
|
144780
144842
|
}));
|
package/dist/server/index.js
CHANGED
|
@@ -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,
|
|
@@ -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.
|
|
251572
|
+
version: "2.260910.1",
|
|
251543
251573
|
private: true,
|
|
251544
251574
|
type: "module",
|
|
251545
251575
|
exports: {
|
|
@@ -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
|
-
|
|
372286
|
-
|
|
372287
|
-
if (
|
|
372288
|
-
|
|
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
|
|
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
|
|
531429
|
-
|
|
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
|
|
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) {
|