@automagik/omni 2.260916.8 → 2.260916.9
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.
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
-- Per-instance close-contact cooldown/escalation overrides.
|
|
2
|
+
--
|
|
3
|
+
-- POST /messages/send/close-contact computes the chat's terminal state from
|
|
4
|
+
-- hardcoded per-outcome defaults (packages/api/src/routes/v2/_close-contact-config.ts).
|
|
5
|
+
-- The resolver already accepted overrides, but nothing persisted them, so an
|
|
6
|
+
-- operator could not tune an outcome (e.g. stop a repeated system-initiated
|
|
7
|
+
-- close from auto-promoting to terminal) without a code change.
|
|
8
|
+
--
|
|
9
|
+
-- instances.close_contact_config jsonb { [outcome]?: { cooldownMs?: number | null,
|
|
10
|
+
-- escalationThreshold?: number | null,
|
|
11
|
+
-- escalationWindowMs?: number | null } }
|
|
12
|
+
--
|
|
13
|
+
-- Nullable; NULL keeps the defaults. Validated by the instances API (Zod).
|
|
14
|
+
--
|
|
15
|
+
-- Hand-written following the 0043/0044/0052 precedent (additive, idempotent).
|
|
16
|
+
-- No explicit BEGIN/COMMIT — the boot migrator executes this file on a pooled
|
|
17
|
+
-- postgres-js connection, which rejects raw transaction control.
|
|
18
|
+
|
|
19
|
+
ALTER TABLE "instances" ADD COLUMN IF NOT EXISTS "close_contact_config" jsonb;
|
|
@@ -540,6 +540,13 @@
|
|
|
540
540
|
"when": 1787600000000,
|
|
541
541
|
"tag": "0076_instances_history_identity",
|
|
542
542
|
"breakpoints": true
|
|
543
|
+
},
|
|
544
|
+
{
|
|
545
|
+
"idx": 77,
|
|
546
|
+
"version": "7",
|
|
547
|
+
"when": 1787700000000,
|
|
548
|
+
"tag": "0077_instances_close_contact_config",
|
|
549
|
+
"breakpoints": true
|
|
543
550
|
}
|
|
544
551
|
]
|
|
545
552
|
}
|
package/dist/index.js
CHANGED
|
@@ -82431,6 +82431,7 @@ var init_schema2 = __esm(() => {
|
|
|
82431
82431
|
}),
|
|
82432
82432
|
chainMode: varchar("chain_mode", { length: 20 }).notNull().default("off"),
|
|
82433
82433
|
followUpConfig: jsonb("follow_up_config").$type(),
|
|
82434
|
+
closeContactConfig: jsonb("close_contact_config").$type(),
|
|
82434
82435
|
bridgeTmuxSession: text("bridge_tmux_session"),
|
|
82435
82436
|
requireGenieSignature: boolean2("require_genie_signature").notNull().default(false),
|
|
82436
82437
|
allowFirstParty: boolean2("allow_first_party").notNull().default(false),
|
|
@@ -115971,7 +115972,7 @@ var require_client2 = __commonJS((exports) => {
|
|
|
115971
115972
|
|
|
115972
115973
|
// ../../node_modules/.bun/@sentry+node-core@10.52.0+2c50d7e904f6cfd7/node_modules/@sentry/node-core/build/cjs/sdk/esmLoader.js
|
|
115973
115974
|
var require_esmLoader = __commonJS((exports) => {
|
|
115974
|
-
var __filename = "/home/runner/work/omni/omni
|
|
115975
|
+
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";
|
|
115975
115976
|
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
115976
115977
|
var core = require_cjs();
|
|
115977
115978
|
var importInTheMiddle = require_import_in_the_middle();
|
|
@@ -137422,7 +137423,7 @@ import { fileURLToPath } from "url";
|
|
|
137422
137423
|
// package.json
|
|
137423
137424
|
var package_default = {
|
|
137424
137425
|
name: "@automagik/omni",
|
|
137425
|
-
version: "2.260916.
|
|
137426
|
+
version: "2.260916.9",
|
|
137426
137427
|
repository: {
|
|
137427
137428
|
type: "git",
|
|
137428
137429
|
url: "git+https://github.com/automagik-dev/omni.git",
|
|
@@ -148286,7 +148287,7 @@ function createMessagesCommand() {
|
|
|
148286
148287
|
error(`Failed to edit message: ${message2}`);
|
|
148287
148288
|
}
|
|
148288
148289
|
});
|
|
148289
|
-
messages3.command("close-contact").description("Close a chat terminally (won/lost) or with a soft cooldown (redirected_sac/unqualified/no_response/other)").requiredOption("--instance <id>", "Instance ID").requiredOption("--chat <chatId>", "Chat DB UUID to close").requiredOption("--to <recipient>", "Recipient phone or platform ID").
|
|
148290
|
+
messages3.command("close-contact").description("Close a chat terminally (won/lost) or with a soft cooldown (redirected_sac/unqualified/no_response/other)").requiredOption("--instance <id>", "Instance ID").requiredOption("--chat <chatId>", "Chat DB UUID to close").requiredOption("--to <recipient>", "Recipient phone or platform ID").option("--text <text>", "Farewell message shown to the contact (omit to close without a farewell)").requiredOption("--outcome <outcome>", "Outcome: won | lost | redirected_sac | unqualified | no_response | other").option("--reason <reason>", "Free-text rationale persisted in close_contact_logs").option("--close-fields <jsonOrPath>", "Structured BI/CRM payload \u2014 inline JSON or path to a JSON file").action(handleCloseContact);
|
|
148290
148291
|
return messages3;
|
|
148291
148292
|
}
|
|
148292
148293
|
var VALID_CLOSE_OUTCOMES = ["won", "lost", "redirected_sac", "unqualified", "no_response", "other"];
|
|
@@ -148332,9 +148333,10 @@ async function buildCloseContactBody(options) {
|
|
|
148332
148333
|
instanceId,
|
|
148333
148334
|
chatId: resolvedChatId,
|
|
148334
148335
|
to: options.to,
|
|
148335
|
-
text: options.text,
|
|
148336
148336
|
outcome: options.outcome
|
|
148337
148337
|
};
|
|
148338
|
+
if (options.text)
|
|
148339
|
+
body.text = options.text;
|
|
148338
148340
|
if (options.reason)
|
|
148339
148341
|
body.reason = options.reason;
|
|
148340
148342
|
if (closeFields)
|
package/dist/server/index.js
CHANGED
|
@@ -77147,7 +77147,7 @@ var require_ClientVoiceManager = __commonJS((exports, module) => {
|
|
|
77147
77147
|
|
|
77148
77148
|
// ../../node_modules/.bun/@discordjs+ws@1.2.3/node_modules/@discordjs/ws/dist/index.js
|
|
77149
77149
|
var require_dist9 = __commonJS((exports, module) => {
|
|
77150
|
-
var __dirname = "/home/runner/work/omni/omni
|
|
77150
|
+
var __dirname = "/home/runner/work/omni/omni/node_modules/.bun/@discordjs+ws@1.2.3/node_modules/@discordjs/ws/dist";
|
|
77151
77151
|
var __create2 = Object.create;
|
|
77152
77152
|
var __defProp2 = Object.defineProperty;
|
|
77153
77153
|
var __getOwnPropDesc2 = Object.getOwnPropertyDescriptor;
|
|
@@ -161660,7 +161660,7 @@ var require_indexes = __commonJS((exports, module) => {
|
|
|
161660
161660
|
|
|
161661
161661
|
// ../../node_modules/.bun/thread-stream@3.1.0/node_modules/thread-stream/index.js
|
|
161662
161662
|
var require_thread_stream = __commonJS((exports, module) => {
|
|
161663
|
-
var __dirname = "/home/runner/work/omni/omni
|
|
161663
|
+
var __dirname = "/home/runner/work/omni/omni/node_modules/.bun/thread-stream@3.1.0/node_modules/thread-stream";
|
|
161664
161664
|
var { version } = require_package5();
|
|
161665
161665
|
var { EventEmitter: EventEmitter3 } = __require("events");
|
|
161666
161666
|
var { Worker } = __require("worker_threads");
|
|
@@ -162081,7 +162081,7 @@ var require_thread_stream = __commonJS((exports, module) => {
|
|
|
162081
162081
|
|
|
162082
162082
|
// ../../node_modules/.bun/pino@9.14.0/node_modules/pino/lib/transport.js
|
|
162083
162083
|
var require_transport2 = __commonJS((exports, module) => {
|
|
162084
|
-
var __dirname = "/home/runner/work/omni/omni
|
|
162084
|
+
var __dirname = "/home/runner/work/omni/omni/node_modules/.bun/pino@9.14.0/node_modules/pino/lib";
|
|
162085
162085
|
var { createRequire: createRequire2 } = __require("module");
|
|
162086
162086
|
var getCallers = require_caller();
|
|
162087
162087
|
var { join: join8, isAbsolute, sep: sep2 } = __require("path");
|
|
@@ -172916,6 +172916,7 @@ var init_schema2 = __esm(() => {
|
|
|
172916
172916
|
}),
|
|
172917
172917
|
chainMode: varchar("chain_mode", { length: 20 }).notNull().default("off"),
|
|
172918
172918
|
followUpConfig: jsonb("follow_up_config").$type(),
|
|
172919
|
+
closeContactConfig: jsonb("close_contact_config").$type(),
|
|
172919
172920
|
bridgeTmuxSession: text("bridge_tmux_session"),
|
|
172920
172921
|
requireGenieSignature: boolean2("require_genie_signature").notNull().default(false),
|
|
172921
172922
|
allowFirstParty: boolean2("allow_first_party").notNull().default(false),
|
|
@@ -243887,7 +243888,7 @@ var require_client3 = __commonJS((exports) => {
|
|
|
243887
243888
|
|
|
243888
243889
|
// ../../node_modules/.bun/@sentry+node-core@10.52.0+2c50d7e904f6cfd7/node_modules/@sentry/node-core/build/cjs/sdk/esmLoader.js
|
|
243889
243890
|
var require_esmLoader = __commonJS((exports) => {
|
|
243890
|
-
var __filename = "/home/runner/work/omni/omni
|
|
243891
|
+
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";
|
|
243891
243892
|
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
243892
243893
|
var core3 = require_cjs6();
|
|
243893
243894
|
var importInTheMiddle = require_import_in_the_middle();
|
|
@@ -251113,7 +251114,7 @@ var init_sentry_scrub = __esm(() => {
|
|
|
251113
251114
|
var require_package7 = __commonJS((exports, module) => {
|
|
251114
251115
|
module.exports = {
|
|
251115
251116
|
name: "@omni/api",
|
|
251116
|
-
version: "2.260916.
|
|
251117
|
+
version: "2.260916.9",
|
|
251117
251118
|
private: true,
|
|
251118
251119
|
type: "module",
|
|
251119
251120
|
exports: {
|
|
@@ -278215,7 +278216,7 @@ var require_src45 = __commonJS((exports) => {
|
|
|
278215
278216
|
|
|
278216
278217
|
// ../../node_modules/.bun/@grpc+grpc-js@1.14.3/node_modules/@grpc/grpc-js/build/src/channelz.js
|
|
278217
278218
|
var require_channelz = __commonJS((exports) => {
|
|
278218
|
-
var __dirname = "/home/runner/work/omni/omni
|
|
278219
|
+
var __dirname = "/home/runner/work/omni/omni/node_modules/.bun/@grpc+grpc-js@1.14.3/node_modules/@grpc/grpc-js/build/src";
|
|
278219
278220
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
278220
278221
|
exports.registerChannelzSocket = exports.registerChannelzServer = exports.registerChannelzSubchannel = exports.registerChannelzChannel = exports.ChannelzCallTrackerStub = exports.ChannelzCallTracker = exports.ChannelzChildrenTrackerStub = exports.ChannelzChildrenTracker = exports.ChannelzTrace = exports.ChannelzTraceStub = undefined;
|
|
278221
278222
|
exports.unregisterChannelzRef = unregisterChannelzRef;
|
|
@@ -283618,7 +283619,7 @@ var require_duration = __commonJS((exports) => {
|
|
|
283618
283619
|
|
|
283619
283620
|
// ../../node_modules/.bun/@grpc+grpc-js@1.14.3/node_modules/@grpc/grpc-js/build/src/orca.js
|
|
283620
283621
|
var require_orca = __commonJS((exports) => {
|
|
283621
|
-
var __dirname = "/home/runner/work/omni/omni
|
|
283622
|
+
var __dirname = "/home/runner/work/omni/omni/node_modules/.bun/@grpc+grpc-js@1.14.3/node_modules/@grpc/grpc-js/build/src";
|
|
283622
283623
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
283623
283624
|
exports.OrcaOobMetricsSubchannelWrapper = exports.GRPC_METRICS_HEADER = exports.ServerMetricRecorder = exports.PerRequestMetricRecorder = undefined;
|
|
283624
283625
|
exports.createOrcaClient = createOrcaClient;
|
|
@@ -381589,7 +381590,7 @@ function registerInstanceSchemas(registry4) {
|
|
|
381589
381590
|
}
|
|
381590
381591
|
});
|
|
381591
381592
|
}
|
|
381592
|
-
var InstanceSchema2, gupshupHandoffFieldValue, gupshupHandoffFieldKey, gupshupHandoffFields, GupshupHandoffOptionsSchema, CreateInstanceSchema2, InstanceStatusSchema2, QrCodeSchema, PairingCodeRequestSchema, PairingCodeSchema, ConnectInstanceSchema, ConnectResponseSchema, UserProfileSchema, ContactSchema, GroupSchema, SupportedChannelSchema;
|
|
381593
|
+
var InstanceSchema2, gupshupHandoffFieldValue, gupshupHandoffFieldKey, gupshupHandoffFields, GupshupHandoffOptionsSchema, closeContactOutcomeOverride, CloseContactConfigSchema, CreateInstanceSchema2, InstanceStatusSchema2, QrCodeSchema, PairingCodeRequestSchema, PairingCodeSchema, ConnectInstanceSchema, ConnectResponseSchema, UserProfileSchema, ContactSchema, GroupSchema, SupportedChannelSchema;
|
|
381593
381594
|
var init_instances2 = __esm(() => {
|
|
381594
381595
|
init_src();
|
|
381595
381596
|
init_zod_openapi();
|
|
@@ -381651,6 +381652,25 @@ var init_instances2 = __esm(() => {
|
|
|
381651
381652
|
]
|
|
381652
381653
|
})
|
|
381653
381654
|
}).strict();
|
|
381655
|
+
closeContactOutcomeOverride = exports_external.object({
|
|
381656
|
+
cooldownMs: exports_external.number().int().nonnegative().nullable().optional().openapi({
|
|
381657
|
+
description: "Soft-close cooldown in ms (null = no cooldown)"
|
|
381658
|
+
}),
|
|
381659
|
+
escalationThreshold: exports_external.number().int().positive().nullable().optional().openapi({
|
|
381660
|
+
description: "Closes with the same outcome within the window that promote to terminal (null = never)"
|
|
381661
|
+
}),
|
|
381662
|
+
escalationWindowMs: exports_external.number().int().positive().nullable().optional().openapi({
|
|
381663
|
+
description: "Window in ms in which repeated closes are counted"
|
|
381664
|
+
})
|
|
381665
|
+
}).strict();
|
|
381666
|
+
CloseContactConfigSchema = exports_external.object({
|
|
381667
|
+
won: closeContactOutcomeOverride.optional(),
|
|
381668
|
+
lost: closeContactOutcomeOverride.optional(),
|
|
381669
|
+
redirected_sac: closeContactOutcomeOverride.optional(),
|
|
381670
|
+
unqualified: closeContactOutcomeOverride.optional(),
|
|
381671
|
+
no_response: closeContactOutcomeOverride.optional(),
|
|
381672
|
+
other: closeContactOutcomeOverride.optional()
|
|
381673
|
+
}).strict();
|
|
381654
381674
|
CreateInstanceSchema2 = exports_external.object({
|
|
381655
381675
|
name: exports_external.string().min(1).max(255).openapi({ description: "Unique name for the instance" }),
|
|
381656
381676
|
channel: ChannelTypeSchema.openapi({ description: "Channel type" }),
|
|
@@ -381676,6 +381696,10 @@ var init_instances2 = __esm(() => {
|
|
|
381676
381696
|
{ apiKey: "Handled By", value: "assistant" }
|
|
381677
381697
|
]
|
|
381678
381698
|
}
|
|
381699
|
+
}),
|
|
381700
|
+
closeContactConfig: CloseContactConfigSchema.nullable().optional().openapi({
|
|
381701
|
+
description: "Per-outcome overrides for POST /messages/send/close-contact cooldown and escalation. Omitted outcomes/keys use the defaults; null clears it",
|
|
381702
|
+
example: { no_response: { escalationThreshold: null } }
|
|
381679
381703
|
})
|
|
381680
381704
|
});
|
|
381681
381705
|
InstanceStatusSchema2 = exports_external.object({
|
|
@@ -389572,6 +389596,7 @@ var init_instances3 = __esm(() => {
|
|
|
389572
389596
|
gupshupAuthToken: exports_external.string().optional().nullable().describe("Gupshup Custom Integration auth token"),
|
|
389573
389597
|
gupshupEventId: exports_external.string().optional().nullable().describe("Gupshup event ID (default: nx_omni_agent_reply)"),
|
|
389574
389598
|
gupshupHandoffOptions: GupshupHandoffOptionsSchema.optional().nullable().describe("Gupshup HANDOFF routing defaults and customerFields template"),
|
|
389599
|
+
closeContactConfig: CloseContactConfigSchema.optional().nullable().describe("Per-outcome close-contact cooldown/escalation overrides (null = defaults)"),
|
|
389575
389600
|
webhookVerifyToken: exports_external.string().optional().nullable().describe("Gupshup webhook verify token"),
|
|
389576
389601
|
twilioAccountSid: exports_external.string().optional().nullable().describe("Twilio Account SID"),
|
|
389577
389602
|
twilioAuthToken: exports_external.string().optional().nullable().describe("Twilio Auth Token"),
|
|
@@ -389624,6 +389649,7 @@ var init_instances3 = __esm(() => {
|
|
|
389624
389649
|
gupshupAuthToken: exports_external.string().nullable().optional(),
|
|
389625
389650
|
gupshupEventId: exports_external.string().nullable().optional(),
|
|
389626
389651
|
gupshupHandoffOptions: GupshupHandoffOptionsSchema.nullable().optional(),
|
|
389652
|
+
closeContactConfig: CloseContactConfigSchema.nullable().optional(),
|
|
389627
389653
|
webhookVerifyToken: exports_external.string().nullable().optional(),
|
|
389628
389654
|
twilioAccountSid: exports_external.string().nullable().optional(),
|
|
389629
389655
|
twilioAuthToken: exports_external.string().nullable().optional(),
|
|
@@ -393209,8 +393235,8 @@ function buildMediaDownloadFetchOptions(instance4) {
|
|
|
393209
393235
|
preserveAuthRedirectHostSuffixes: ["slack.com"]
|
|
393210
393236
|
};
|
|
393211
393237
|
}
|
|
393212
|
-
async function computeCloseContactTerminalState(db2, chatUuid, outcome, auditRowId) {
|
|
393213
|
-
const cfg = resolveCloseContactConfig(outcome,
|
|
393238
|
+
async function computeCloseContactTerminalState(db2, chatUuid, outcome, auditRowId, instanceOverrides) {
|
|
393239
|
+
const cfg = resolveCloseContactConfig(outcome, instanceOverrides);
|
|
393214
393240
|
if (isHardTerminalOutcome(outcome)) {
|
|
393215
393241
|
return { terminal: true, escalated: false, closeUntil: null };
|
|
393216
393242
|
}
|
|
@@ -393230,6 +393256,13 @@ async function computeCloseContactTerminalState(db2, chatUuid, outcome, auditRow
|
|
|
393230
393256
|
const closeUntil = cfg.cooldownMs !== null ? new Date(Date.now() + cfg.cooldownMs) : null;
|
|
393231
393257
|
return { terminal: false, escalated: false, closeUntil };
|
|
393232
393258
|
}
|
|
393259
|
+
function planCloseContactSend(text3, capabilities3) {
|
|
393260
|
+
const hasNativeClose = capabilities3?.canCloseContact === true;
|
|
393261
|
+
const farewellText = text3?.trim() ? text3 : "";
|
|
393262
|
+
const withoutFarewell = farewellText === "";
|
|
393263
|
+
const sendNativeClose = hasNativeClose && (!withoutFarewell || capabilities3?.canCloseContactWithoutText === true);
|
|
393264
|
+
return { hasNativeClose, sendNativeClose, farewellText, withoutFarewell };
|
|
393265
|
+
}
|
|
393233
393266
|
function hasPresenceStatusSender(plugin13) {
|
|
393234
393267
|
return typeof plugin13 === "object" && plugin13 !== null && typeof plugin13.sendPresenceStatus === "function";
|
|
393235
393268
|
}
|
|
@@ -393513,7 +393546,7 @@ var init_messages5 = __esm(() => {
|
|
|
393513
393546
|
instanceId: exports_external.string().uuid().describe("Instance ID \u2014 close-contact native send is Gupshup-only in v1"),
|
|
393514
393547
|
chatId: exports_external.string().min(1).describe("Chat DB UUID to mark as closed"),
|
|
393515
393548
|
to: exports_external.string().min(1).describe("Recipient phone or platform ID"),
|
|
393516
|
-
text: exports_external.string().
|
|
393549
|
+
text: exports_external.string().optional().describe("Farewell message shown to the contact. Omit (or send an empty string) to classify/close without a farewell: " + "channels declaring `canCloseContactWithoutText` still receive the native close event with an empty text " + "(the channel flow must not deliver an empty message); other channels skip the channel send."),
|
|
393517
393550
|
outcome: exports_external.enum(["won", "lost", "redirected_sac", "unqualified", "no_response", "other"]).describe("Drives terminal/cooldown/escalation logic and BI/audit trail"),
|
|
393518
393551
|
reason: exports_external.string().optional().describe("Free-text rationale persisted in close_contact_logs"),
|
|
393519
393552
|
closeFields: exports_external.record(exports_external.unknown()).optional().describe("Structured BI/CRM payload \u2014 forwarded to Gupshup native send when supported")
|
|
@@ -394260,13 +394293,13 @@ var init_messages5 = __esm(() => {
|
|
|
394260
394293
|
});
|
|
394261
394294
|
}
|
|
394262
394295
|
const resolvedTo = await resolveRecipient(data.to, instance4.channel, services);
|
|
394263
|
-
const hasNativeClose = plugin13.capabilities?.canCloseContact === true;
|
|
394264
394296
|
const outcome = data.outcome;
|
|
394297
|
+
const { hasNativeClose, sendNativeClose, farewellText, withoutFarewell } = planCloseContactSend(data.text, plugin13.capabilities);
|
|
394265
394298
|
let channelSendResult = null;
|
|
394266
|
-
if (
|
|
394299
|
+
if (sendNativeClose) {
|
|
394267
394300
|
const outgoingMessage = {
|
|
394268
394301
|
to: resolvedTo,
|
|
394269
|
-
content: { type: "text", text:
|
|
394302
|
+
content: { type: "text", text: farewellText },
|
|
394270
394303
|
metadata: {
|
|
394271
394304
|
isCloseContact: true,
|
|
394272
394305
|
closeReason: data.reason,
|
|
@@ -394286,7 +394319,7 @@ var init_messages5 = __esm(() => {
|
|
|
394286
394319
|
chatUuid: data.chatId,
|
|
394287
394320
|
chatId: resolvedTo,
|
|
394288
394321
|
toPhone: resolvedTo,
|
|
394289
|
-
text:
|
|
394322
|
+
text: farewellText,
|
|
394290
394323
|
outcome,
|
|
394291
394324
|
reason: data.reason ?? null,
|
|
394292
394325
|
closeFields: data.closeFields ?? null,
|
|
@@ -394296,10 +394329,12 @@ var init_messages5 = __esm(() => {
|
|
|
394296
394329
|
sentAt: new Date,
|
|
394297
394330
|
metadata: {
|
|
394298
394331
|
instanceChannel: instance4.channel,
|
|
394299
|
-
channelCloseSupported: hasNativeClose
|
|
394332
|
+
channelCloseSupported: hasNativeClose,
|
|
394333
|
+
channelCloseSent: sendNativeClose,
|
|
394334
|
+
withoutFarewell
|
|
394300
394335
|
}
|
|
394301
394336
|
}).returning();
|
|
394302
|
-
const { terminal, escalated, closeUntil } = await computeCloseContactTerminalState(db2, data.chatId, outcome, auditRow?.id ?? null);
|
|
394337
|
+
const { terminal, escalated, closeUntil } = await computeCloseContactTerminalState(db2, data.chatId, outcome, auditRow?.id ?? null, instance4);
|
|
394303
394338
|
const shouldPauseAgent = outcome === "lost";
|
|
394304
394339
|
const closedAt = new Date;
|
|
394305
394340
|
const closeChat = await services.chats.getById(data.chatId);
|
|
@@ -408661,6 +408696,7 @@ var GUPSHUP_CAPABILITIES = {
|
|
|
408661
408696
|
canForwardMessage: false,
|
|
408662
408697
|
canHandoff: true,
|
|
408663
408698
|
canCloseContact: true,
|
|
408699
|
+
canCloseContactWithoutText: true,
|
|
408664
408700
|
canSendContact: false,
|
|
408665
408701
|
canSendLocation: true,
|
|
408666
408702
|
canSendSticker: true,
|
|
@@ -408782,6 +408818,12 @@ class GupshupClient {
|
|
|
408782
408818
|
payload.handoff_fields = msg.handoff_fields;
|
|
408783
408819
|
if (msg.customer_fields && msg.customer_fields.length > 0)
|
|
408784
408820
|
payload.customerFields = msg.customer_fields;
|
|
408821
|
+
if (msg.close_reason)
|
|
408822
|
+
payload.close_reason = msg.close_reason;
|
|
408823
|
+
if (msg.close_outcome)
|
|
408824
|
+
payload.close_outcome = msg.close_outcome;
|
|
408825
|
+
if (msg.close_fields)
|
|
408826
|
+
payload.close_fields = msg.close_fields;
|
|
408785
408827
|
const res = await fetch(this.callbackUrl, {
|
|
408786
408828
|
method: "POST",
|
|
408787
408829
|
headers: { "Content-Type": "application/json", Authorization: this.authToken },
|
|
@@ -409435,6 +409477,9 @@ function toGupshupPhone(phone) {
|
|
|
409435
409477
|
}
|
|
409436
409478
|
|
|
409437
409479
|
// ../channel-gupshup/src/plugin.ts
|
|
409480
|
+
function isCloseWithoutText(message2) {
|
|
409481
|
+
return message2.metadata?.isCloseContact === true && !message2.content.text;
|
|
409482
|
+
}
|
|
409438
409483
|
async function dispatchContent(client, dest, message2, handoffOptions) {
|
|
409439
409484
|
const { content } = message2;
|
|
409440
409485
|
const meta = message2.metadata;
|
|
@@ -409585,6 +409630,9 @@ class GupshupPlugin extends BaseChannelPlugin {
|
|
|
409585
409630
|
const messageId = extractResponseString(response, "messageId") ?? crypto.randomUUID();
|
|
409586
409631
|
if (correlationId)
|
|
409587
409632
|
this.captureT11(correlationId);
|
|
409633
|
+
if (isCloseWithoutText(message2)) {
|
|
409634
|
+
return { success: true, messageId, timestamp: Date.now() };
|
|
409635
|
+
}
|
|
409588
409636
|
await this.emitMessageSent({
|
|
409589
409637
|
instanceId,
|
|
409590
409638
|
externalId: messageId,
|