@automagik/omni 2.260331.1 → 2.260404.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/db/drizzle/0013_curious_leo.sql +4 -0
- package/db/drizzle/meta/0013_snapshot.json +6754 -0
- package/db/drizzle/meta/_journal.json +7 -0
- package/dist/commands/connect.d.ts +1 -1
- package/dist/commands/instances.d.ts.map +1 -1
- package/dist/index.js +8 -4
- package/dist/server/index.js +115 -11
- package/package.json +9 -9
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
* Connect Command — omni connect <instance-id> <agent-name>
|
|
3
3
|
*
|
|
4
4
|
* One-command setup for Omni ↔ Genie NATS integration:
|
|
5
|
-
* 1. Discovers agent via `genie dir
|
|
5
|
+
* 1. Discovers agent via `genie dir ls <agent-name> --json`
|
|
6
6
|
* 2. Creates/updates Omni provider with schema `nats-genie`
|
|
7
7
|
* 3. Creates Omni agent record linked to provider
|
|
8
8
|
* 4. Updates instance to use the new agent
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"instances.d.ts","sourceRoot":"","sources":["../../src/commands/instances.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAGH,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;
|
|
1
|
+
{"version":3,"file":"instances.d.ts","sourceRoot":"","sources":["../../src/commands/instances.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAGH,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAwJpC,wBAAgB,sBAAsB,IAAI,OAAO,CAsnChD"}
|
package/dist/index.js
CHANGED
|
@@ -76650,7 +76650,7 @@ import { fileURLToPath } from "url";
|
|
|
76650
76650
|
// package.json
|
|
76651
76651
|
var package_default = {
|
|
76652
76652
|
name: "@automagik/omni",
|
|
76653
|
-
version: "2.
|
|
76653
|
+
version: "2.260404.1",
|
|
76654
76654
|
description: "LLM-optimized CLI for Omni",
|
|
76655
76655
|
type: "module",
|
|
76656
76656
|
bin: {
|
|
@@ -79673,7 +79673,7 @@ function createConnectCommand() {
|
|
|
79673
79673
|
info(`Discovering agent "${agentName}" from genie directory...`);
|
|
79674
79674
|
let agentEntry;
|
|
79675
79675
|
try {
|
|
79676
|
-
const stdout = execFileSync("genie", ["dir", "
|
|
79676
|
+
const stdout = execFileSync("genie", ["dir", "ls", agentName, "--json"], {
|
|
79677
79677
|
encoding: "utf-8",
|
|
79678
79678
|
env: process.env,
|
|
79679
79679
|
timeout: 1e4
|
|
@@ -81401,7 +81401,7 @@ function createInstallCommand() {
|
|
|
81401
81401
|
|
|
81402
81402
|
// src/commands/instances.ts
|
|
81403
81403
|
var import_qrcode_terminal = __toESM(require_main(), 1);
|
|
81404
|
-
var VALID_CHANNELS2 = ["whatsapp-baileys", "whatsapp-cloud", "discord", "slack", "telegram"];
|
|
81404
|
+
var VALID_CHANNELS2 = ["whatsapp-baileys", "whatsapp-cloud", "discord", "slack", "telegram", "gupshup"];
|
|
81405
81405
|
var VALID_SYNC_TYPES = ["profile", "messages", "contacts", "groups", "all"];
|
|
81406
81406
|
function setVal(body, key, val) {
|
|
81407
81407
|
if (val === "null")
|
|
@@ -81474,6 +81474,10 @@ function applyMiscFields(body, opts) {
|
|
|
81474
81474
|
setVal(body, "discordBotToken", opts.discordToken);
|
|
81475
81475
|
setVal(body, "slackBotToken", opts.slackBotToken);
|
|
81476
81476
|
setVal(body, "slackAppToken", opts.slackAppToken);
|
|
81477
|
+
setVal(body, "gupshupApiKey", opts.gupshupApiKey);
|
|
81478
|
+
setVal(body, "gupshupAppName", opts.gupshupAppName);
|
|
81479
|
+
setVal(body, "gupshupSourcePhone", opts.gupshupSourcePhone);
|
|
81480
|
+
setVal(body, "webhookVerifyToken", opts.gupshupWebhookVerifyToken);
|
|
81477
81481
|
if (opts.triggerEvents !== undefined) {
|
|
81478
81482
|
const raw2 = opts.triggerEvents;
|
|
81479
81483
|
body.triggerEvents = raw2 === "null" ? null : raw2.split(",").map((s) => s.trim());
|
|
@@ -81577,7 +81581,7 @@ function createInstancesCommand() {
|
|
|
81577
81581
|
error(`Failed to get instance: ${message}`, undefined, 3);
|
|
81578
81582
|
}
|
|
81579
81583
|
});
|
|
81580
|
-
instances.command("create").description("Create a new instance (supports all API fields)").requiredOption("--name <name>", "Instance name").requiredOption("--channel <type>", `Channel type (${VALID_CHANNELS2.join(", ")})`).option("--agent-fk-id <uuid>", 'Agent FK UUID (references agents table, use "null" to clear)').option("--agent-provider <id>", "Agent provider ID").option("--agent <id>", "Agent ID").option("--agent-type <type>", "Agent type: agent, team, or workflow").option("--agent-timeout <seconds>", "Agent timeout in seconds", (v) => Number.parseInt(v, 10)).option("--agent-stream-mode", "Enable streaming responses").option("--agent-session-strategy <strategy>", "Session strategy: per_user, per_chat, per_user_per_chat").option("--agent-prefix-sender-name", "Prefix messages with sender name").option("--no-agent-prefix-sender-name", "Disable sender name prefix").option("--agent-wait-for-media", "Wait for media processing before dispatch").option("--no-agent-wait-for-media", "Dispatch immediately without waiting for media").option("--agent-send-media-path", "Include file path in formatted media text").option("--no-agent-send-media-path", "Exclude file path from formatted media text").option("--agent-send-media-path-types <types>", "Content types that receive file path (comma-separated: image,video,document)").option("--reply-filter-mode <mode>", "Reply filter: all or filtered").option("--reply-on-dm", "Reply to DMs").option("--no-reply-on-dm", "Ignore DMs").option("--reply-on-mention", "Reply when @mentioned").option("--no-reply-on-mention", "Ignore @mentions").option("--reply-on-reply", "Reply when message is reply to bot").option("--no-reply-on-reply", "Ignore replies").option("--reply-on-name", "Reply when bot name appears in text").option("--no-reply-on-name", "Ignore name matches").option("--reply-name-patterns <patterns>", "Custom name patterns (comma-separated)").option("--enable-auto-split", "Split responses on double newlines").option("--no-enable-auto-split", "Disable auto-split").option("--message-format-mode <mode>", "Format mode: convert or passthrough").option("--debounce-mode <mode>", "Debounce mode: disabled, fixed, or randomized").option("--debounce-min <ms>", "Minimum debounce delay in ms", (v) => Number.parseInt(v, 10)).option("--debounce-max <ms>", "Maximum debounce delay in ms", (v) => Number.parseInt(v, 10)).option("--debounce-restart-on-typing", "Restart debounce timer on typing").option("--debounce-group <ms>", "Group chat debounce in ms", (v) => Number.parseInt(v, 10)).option("--agent-gate", "Enable LLM response gate").option("--agent-gate-model <model>", "Model for response gate").option("--agent-gate-prompt <prompt>", "Custom gate prompt").option("--tts-voice <id>", "ElevenLabs voice ID").option("--tts-model <id>", "ElevenLabs model ID").option("--access-mode <mode>", "Access mode: disabled, blocklist, or allowlist").option("--reaction-ack <mode>", "Reaction ack mode (on|off)").option("--reaction-ack-emoji <json>", "Per-channel emoji map as JSON").option("--ack-timeout <ms>", "Ack timeout in milliseconds", (v) => Number.parseInt(v, 10)).option("--token <token>", "Generic bot token (auto-resolves to channel-specific field)").option("--telegram-token <token>", "Telegram bot token").option("--discord-token <token>", "Discord bot token").option("--slack-bot-token <token>", "Slack bot token").option("--slack-app-token <token>", "Slack app token").option("--is-default", "Set as default instance for channel").action(async (options) => {
|
|
81584
|
+
instances.command("create").description("Create a new instance (supports all API fields)").requiredOption("--name <name>", "Instance name").requiredOption("--channel <type>", `Channel type (${VALID_CHANNELS2.join(", ")})`).option("--agent-fk-id <uuid>", 'Agent FK UUID (references agents table, use "null" to clear)').option("--agent-provider <id>", "Agent provider ID").option("--agent <id>", "Agent ID").option("--agent-type <type>", "Agent type: agent, team, or workflow").option("--agent-timeout <seconds>", "Agent timeout in seconds", (v) => Number.parseInt(v, 10)).option("--agent-stream-mode", "Enable streaming responses").option("--agent-session-strategy <strategy>", "Session strategy: per_user, per_chat, per_user_per_chat").option("--agent-prefix-sender-name", "Prefix messages with sender name").option("--no-agent-prefix-sender-name", "Disable sender name prefix").option("--agent-wait-for-media", "Wait for media processing before dispatch").option("--no-agent-wait-for-media", "Dispatch immediately without waiting for media").option("--agent-send-media-path", "Include file path in formatted media text").option("--no-agent-send-media-path", "Exclude file path from formatted media text").option("--agent-send-media-path-types <types>", "Content types that receive file path (comma-separated: image,video,document)").option("--reply-filter-mode <mode>", "Reply filter: all or filtered").option("--reply-on-dm", "Reply to DMs").option("--no-reply-on-dm", "Ignore DMs").option("--reply-on-mention", "Reply when @mentioned").option("--no-reply-on-mention", "Ignore @mentions").option("--reply-on-reply", "Reply when message is reply to bot").option("--no-reply-on-reply", "Ignore replies").option("--reply-on-name", "Reply when bot name appears in text").option("--no-reply-on-name", "Ignore name matches").option("--reply-name-patterns <patterns>", "Custom name patterns (comma-separated)").option("--enable-auto-split", "Split responses on double newlines").option("--no-enable-auto-split", "Disable auto-split").option("--message-format-mode <mode>", "Format mode: convert or passthrough").option("--debounce-mode <mode>", "Debounce mode: disabled, fixed, or randomized").option("--debounce-min <ms>", "Minimum debounce delay in ms", (v) => Number.parseInt(v, 10)).option("--debounce-max <ms>", "Maximum debounce delay in ms", (v) => Number.parseInt(v, 10)).option("--debounce-restart-on-typing", "Restart debounce timer on typing").option("--debounce-group <ms>", "Group chat debounce in ms", (v) => Number.parseInt(v, 10)).option("--agent-gate", "Enable LLM response gate").option("--agent-gate-model <model>", "Model for response gate").option("--agent-gate-prompt <prompt>", "Custom gate prompt").option("--tts-voice <id>", "ElevenLabs voice ID").option("--tts-model <id>", "ElevenLabs model ID").option("--access-mode <mode>", "Access mode: disabled, blocklist, or allowlist").option("--reaction-ack <mode>", "Reaction ack mode (on|off)").option("--reaction-ack-emoji <json>", "Per-channel emoji map as JSON").option("--ack-timeout <ms>", "Ack timeout in milliseconds", (v) => Number.parseInt(v, 10)).option("--token <token>", "Generic bot token (auto-resolves to channel-specific field)").option("--telegram-token <token>", "Telegram bot token").option("--discord-token <token>", "Discord bot token").option("--slack-bot-token <token>", "Slack bot token").option("--slack-app-token <token>", "Slack app token").option("--gupshup-api-key <key>", "Gupshup API key").option("--gupshup-app-name <name>", "Gupshup app name").option("--gupshup-source-phone <phone>", "Gupshup source phone (E.164)").option("--gupshup-webhook-verify-token <token>", "Gupshup webhook verify token").option("--is-default", "Set as default instance for channel").action(async (options) => {
|
|
81581
81585
|
const channel = options.channel;
|
|
81582
81586
|
if (!VALID_CHANNELS2.includes(channel)) {
|
|
81583
81587
|
error(`Invalid channel: ${channel}`, { validChannels: VALID_CHANNELS2 });
|
package/dist/server/index.js
CHANGED
|
@@ -22377,6 +22377,7 @@ var init_channel = __esm(() => {
|
|
|
22377
22377
|
"slack",
|
|
22378
22378
|
"telegram",
|
|
22379
22379
|
"a2a",
|
|
22380
|
+
"gupshup",
|
|
22380
22381
|
"internal"
|
|
22381
22382
|
];
|
|
22382
22383
|
CONTENT_TYPES = [
|
|
@@ -222785,7 +222786,7 @@ var init_sentry_scrub = __esm(() => {
|
|
|
222785
222786
|
var require_package8 = __commonJS((exports, module) => {
|
|
222786
222787
|
module.exports = {
|
|
222787
222788
|
name: "@omni/api",
|
|
222788
|
-
version: "2.
|
|
222789
|
+
version: "2.260404.1",
|
|
222789
222790
|
type: "module",
|
|
222790
222791
|
exports: {
|
|
222791
222792
|
".": {
|
|
@@ -228237,6 +228238,7 @@ var init_schema2 = __esm(() => {
|
|
|
228237
228238
|
"slack",
|
|
228238
228239
|
"telegram",
|
|
228239
228240
|
"a2a",
|
|
228241
|
+
"gupshup",
|
|
228240
228242
|
"internal"
|
|
228241
228243
|
];
|
|
228242
228244
|
agentTypes = ["agent", "team", "workflow"];
|
|
@@ -228478,6 +228480,10 @@ var init_schema2 = __esm(() => {
|
|
|
228478
228480
|
slackSigningSecret: text("slack_signing_secret"),
|
|
228479
228481
|
telegramBotToken: text("telegram_bot_token"),
|
|
228480
228482
|
telegramReactionLevel: varchar("telegram_reaction_level", { length: 20 }).notNull().default("off"),
|
|
228483
|
+
gupshupApiKey: text("gupshup_api_key"),
|
|
228484
|
+
gupshupAppName: varchar("gupshup_app_name", { length: 255 }),
|
|
228485
|
+
gupshupSourcePhone: varchar("gupshup_source_phone", { length: 20 }),
|
|
228486
|
+
webhookVerifyToken: text("webhook_verify_token"),
|
|
228481
228487
|
agentId: uuid("agent_id").references(() => agents.id, { onDelete: "set null" }),
|
|
228482
228488
|
agentTimeout: integer("agent_timeout").notNull().default(60),
|
|
228483
228489
|
agentStreamMode: boolean("agent_stream_mode").notNull().default(false),
|
|
@@ -332112,6 +332118,16 @@ function applyChannelSpecificConnectionOptions(options, input) {
|
|
|
332112
332118
|
if (input.slackSigningSecret)
|
|
332113
332119
|
options.signingSecret = input.slackSigningSecret;
|
|
332114
332120
|
}
|
|
332121
|
+
if (input.channel === "gupshup") {
|
|
332122
|
+
if (input.gupshupApiKey)
|
|
332123
|
+
options.gupshupApiKey = input.gupshupApiKey;
|
|
332124
|
+
if (input.gupshupAppName)
|
|
332125
|
+
options.gupshupAppName = input.gupshupAppName;
|
|
332126
|
+
if (input.gupshupSourcePhone)
|
|
332127
|
+
options.gupshupSourcePhone = input.gupshupSourcePhone;
|
|
332128
|
+
if (input.webhookVerifyToken)
|
|
332129
|
+
options.webhookVerifyToken = input.webhookVerifyToken;
|
|
332130
|
+
}
|
|
332115
332131
|
}
|
|
332116
332132
|
function buildInstanceConnectionOptions(input) {
|
|
332117
332133
|
const options = { forceNewQr: input.forceNewQr };
|
|
@@ -332304,6 +332320,10 @@ var init_instances3 = __esm(() => {
|
|
|
332304
332320
|
slackBotToken: exports_external.string().optional().nullable().describe("Slack bot token (persisted for reconnection)"),
|
|
332305
332321
|
slackAppToken: exports_external.string().optional().nullable().describe("Slack app token (persisted for reconnection)"),
|
|
332306
332322
|
slackSigningSecret: exports_external.string().optional().nullable().describe("Slack signing secret (persisted for reconnection)"),
|
|
332323
|
+
gupshupApiKey: exports_external.string().optional().nullable().describe("Gupshup API key"),
|
|
332324
|
+
gupshupAppName: exports_external.string().optional().nullable().describe("Gupshup app name"),
|
|
332325
|
+
gupshupSourcePhone: exports_external.string().optional().nullable().describe("Gupshup source phone (E.164)"),
|
|
332326
|
+
webhookVerifyToken: exports_external.string().optional().nullable().describe("Gupshup webhook verify token"),
|
|
332307
332327
|
readReceipts: exports_external.enum(["on", "off", "exclude-self"]).default("on").describe("Read receipt mode: on (default), off, or exclude-self (skip receipts for the instance own number)"),
|
|
332308
332328
|
groupHistorySize: exports_external.number().int().min(0).max(200).default(50).describe("Number of context messages to include when dispatching to agent. Groups use the full value; DMs are capped at 20. (0 = disabled, max 200)"),
|
|
332309
332329
|
markOnlineOnConnect: exports_external.boolean().default(true).describe("Mark the instance as online when connecting to WhatsApp (default: true). Set to false to preserve phone push notifications."),
|
|
@@ -332319,6 +332339,10 @@ var init_instances3 = __esm(() => {
|
|
|
332319
332339
|
discordBotToken: exports_external.string().nullable().optional(),
|
|
332320
332340
|
slackBotToken: exports_external.string().nullable().optional(),
|
|
332321
332341
|
slackAppToken: exports_external.string().nullable().optional(),
|
|
332342
|
+
gupshupApiKey: exports_external.string().nullable().optional(),
|
|
332343
|
+
gupshupAppName: exports_external.string().nullable().optional(),
|
|
332344
|
+
gupshupSourcePhone: exports_external.string().nullable().optional(),
|
|
332345
|
+
webhookVerifyToken: exports_external.string().nullable().optional(),
|
|
332322
332346
|
readReceipts: exports_external.enum(["on", "off", "exclude-self"]).optional(),
|
|
332323
332347
|
markOnlineOnConnect: exports_external.boolean().optional(),
|
|
332324
332348
|
groupHistorySize: exports_external.number().int().min(0).max(200).optional(),
|
|
@@ -332331,7 +332355,9 @@ var init_instances3 = __esm(() => {
|
|
|
332331
332355
|
"discordBotToken",
|
|
332332
332356
|
"slackBotToken",
|
|
332333
332357
|
"slackAppToken",
|
|
332334
|
-
"slackSigningSecret"
|
|
332358
|
+
"slackSigningSecret",
|
|
332359
|
+
"gupshupApiKey",
|
|
332360
|
+
"webhookVerifyToken"
|
|
332335
332361
|
];
|
|
332336
332362
|
instancesRoutes.get("/", zValidator("query", listQuerySchema10), async (c) => {
|
|
332337
332363
|
const { channel: channel4, status, limit: limit2, cursor } = c.req.valid("query");
|
|
@@ -332393,7 +332419,11 @@ var init_instances3 = __esm(() => {
|
|
|
332393
332419
|
token: connectToken,
|
|
332394
332420
|
telegramReactionLevel: instance4.telegramReactionLevel,
|
|
332395
332421
|
slackAppToken: instance4.slackAppToken,
|
|
332396
|
-
slackSigningSecret: instance4.slackSigningSecret
|
|
332422
|
+
slackSigningSecret: instance4.slackSigningSecret,
|
|
332423
|
+
gupshupApiKey: instance4.gupshupApiKey,
|
|
332424
|
+
gupshupAppName: instance4.gupshupAppName,
|
|
332425
|
+
gupshupSourcePhone: instance4.gupshupSourcePhone,
|
|
332426
|
+
webhookVerifyToken: instance4.webhookVerifyToken
|
|
332397
332427
|
});
|
|
332398
332428
|
const createPlugin = getPluginFromRegistry(channelRegistry2, data.channel);
|
|
332399
332429
|
if (createPlugin && "loadGuildConfigs" in createPlugin && instance4.guildConfigOverrides) {
|
|
@@ -332556,7 +332586,11 @@ var init_instances3 = __esm(() => {
|
|
|
332556
332586
|
telegramReactionLevel: instance4.telegramReactionLevel,
|
|
332557
332587
|
slackAppToken: body.slackAppToken ?? instance4.slackAppToken,
|
|
332558
332588
|
slackSigningSecret: body.slackSigningSecret ?? instance4.slackSigningSecret,
|
|
332559
|
-
whatsapp: body.whatsapp
|
|
332589
|
+
whatsapp: body.whatsapp,
|
|
332590
|
+
gupshupApiKey: instance4.gupshupApiKey,
|
|
332591
|
+
gupshupAppName: instance4.gupshupAppName,
|
|
332592
|
+
gupshupSourcePhone: instance4.gupshupSourcePhone,
|
|
332593
|
+
webhookVerifyToken: instance4.webhookVerifyToken
|
|
332560
332594
|
});
|
|
332561
332595
|
if (!channelRegistry2) {
|
|
332562
332596
|
return c.json({ error: { code: "NO_REGISTRY", message: "Channel registry not available" } }, 503);
|
|
@@ -336375,6 +336409,7 @@ function createApp(db2, eventBus = null, channelRegistry2 = null) {
|
|
|
336375
336409
|
app.use("*", contextMiddleware);
|
|
336376
336410
|
app.use("*", versionHeadersMiddleware);
|
|
336377
336411
|
app.onError(errorHandler2);
|
|
336412
|
+
app.get("/health", (c) => c.redirect("/api/v2/health", 307));
|
|
336378
336413
|
app.route("/api/v2", healthRoutes);
|
|
336379
336414
|
app.route("/api/v2", openapiRoutes);
|
|
336380
336415
|
if (process.env.A2A_ENABLED === "true") {
|
|
@@ -339792,12 +339827,52 @@ function createNatsGenieProviderInstance(provider, instance4) {
|
|
|
339792
339827
|
return null;
|
|
339793
339828
|
}
|
|
339794
339829
|
const natsUrl = typeof schemaConfig.natsUrl === "string" ? schemaConfig.natsUrl : "localhost:4222";
|
|
339795
|
-
|
|
339830
|
+
const channel4 = instance4.channel;
|
|
339831
|
+
const natsProvider = new NatsGenieProvider(provider.id, provider.name, {
|
|
339796
339832
|
agentName,
|
|
339797
339833
|
natsUrl,
|
|
339798
339834
|
instanceId: instance4.id,
|
|
339799
|
-
prefixSenderName: instance4.agentPrefixSenderName ?? true
|
|
339835
|
+
prefixSenderName: instance4.agentPrefixSenderName ?? true,
|
|
339836
|
+
onReply: async (chatId, content, metadata) => {
|
|
339837
|
+
try {
|
|
339838
|
+
await sendTextMessage5(channel4, instance4.id, chatId, content);
|
|
339839
|
+
} catch (error2) {
|
|
339840
|
+
log86.error("Failed to deliver agent reply", {
|
|
339841
|
+
chatId,
|
|
339842
|
+
instanceId: instance4.id,
|
|
339843
|
+
providerId: provider.id,
|
|
339844
|
+
agent: metadata?.agent,
|
|
339845
|
+
error: error2 instanceof Error ? error2.message : String(error2)
|
|
339846
|
+
});
|
|
339847
|
+
}
|
|
339848
|
+
}
|
|
339800
339849
|
});
|
|
339850
|
+
const startWithRetry = async (attempt = 1) => {
|
|
339851
|
+
try {
|
|
339852
|
+
await natsProvider.startReplySubscription();
|
|
339853
|
+
log86.info("NATS reply subscription started", { instanceId: instance4.id, attempt });
|
|
339854
|
+
} catch (err) {
|
|
339855
|
+
const delay2 = Math.min(2000 * 2 ** (attempt - 1), 60000);
|
|
339856
|
+
if (attempt < 10) {
|
|
339857
|
+
log86.warn("NATS reply subscription failed, retrying", {
|
|
339858
|
+
instanceId: instance4.id,
|
|
339859
|
+
providerId: provider.id,
|
|
339860
|
+
attempt,
|
|
339861
|
+
nextRetryMs: delay2,
|
|
339862
|
+
error: err instanceof Error ? err.message : String(err)
|
|
339863
|
+
});
|
|
339864
|
+
setTimeout(() => startWithRetry(attempt + 1), delay2);
|
|
339865
|
+
} else {
|
|
339866
|
+
log86.error("NATS reply subscription permanently failed", {
|
|
339867
|
+
instanceId: instance4.id,
|
|
339868
|
+
providerId: provider.id,
|
|
339869
|
+
error: err instanceof Error ? err.message : String(err)
|
|
339870
|
+
});
|
|
339871
|
+
}
|
|
339872
|
+
}
|
|
339873
|
+
};
|
|
339874
|
+
startWithRetry();
|
|
339875
|
+
return natsProvider;
|
|
339801
339876
|
}
|
|
339802
339877
|
function resolveProvider(provider, instance4, db2) {
|
|
339803
339878
|
const cacheKey = `${provider.id}:${instance4.id}`;
|
|
@@ -341439,6 +341514,16 @@ function buildInstanceConnectOptions(instance4) {
|
|
|
341439
341514
|
options.signingSecret = instance4.slackSigningSecret;
|
|
341440
341515
|
applySlackMetadata(options, instance4.profileMetadata);
|
|
341441
341516
|
}
|
|
341517
|
+
if (instance4.channel === "gupshup") {
|
|
341518
|
+
if (instance4.gupshupApiKey)
|
|
341519
|
+
options.gupshupApiKey = instance4.gupshupApiKey;
|
|
341520
|
+
if (instance4.gupshupAppName)
|
|
341521
|
+
options.gupshupAppName = instance4.gupshupAppName;
|
|
341522
|
+
if (instance4.gupshupSourcePhone)
|
|
341523
|
+
options.gupshupSourcePhone = instance4.gupshupSourcePhone;
|
|
341524
|
+
if (instance4.webhookVerifyToken)
|
|
341525
|
+
options.webhookVerifyToken = instance4.webhookVerifyToken;
|
|
341526
|
+
}
|
|
341442
341527
|
return options;
|
|
341443
341528
|
}
|
|
341444
341529
|
async function connectInstance(instance4, registry5) {
|
|
@@ -460672,6 +460757,14 @@ function buildMessageContent2(message2, buildVCard) {
|
|
|
460672
460757
|
return builder(message2, buildVCard);
|
|
460673
460758
|
}
|
|
460674
460759
|
|
|
460760
|
+
// ../channel-whatsapp/src/senders/contact.ts
|
|
460761
|
+
function computeWaid(digits) {
|
|
460762
|
+
if (digits.length === 13 && digits.startsWith("55") && digits.charAt(4) === "9") {
|
|
460763
|
+
return digits.slice(0, 4) + digits.slice(5);
|
|
460764
|
+
}
|
|
460765
|
+
return digits;
|
|
460766
|
+
}
|
|
460767
|
+
|
|
460675
460768
|
// ../channel-whatsapp/src/senders/reaction.ts
|
|
460676
460769
|
function buildReactionContent(targetJid, targetMessageId, emoji, fromMe = true) {
|
|
460677
460770
|
return {
|
|
@@ -462163,7 +462256,10 @@ class WhatsAppPlugin extends BaseChannelPlugin {
|
|
|
462163
462256
|
});
|
|
462164
462257
|
const correlationId = message2.metadata?.correlationId;
|
|
462165
462258
|
correlationId && this.captureT10(correlationId);
|
|
462166
|
-
await sendReaction(sock, jid, targetMessageId, reactionEmoji, fromMe);
|
|
462259
|
+
const reactionMsgId = await sendReaction(sock, jid, targetMessageId, reactionEmoji, fromMe);
|
|
462260
|
+
if (reactionMsgId) {
|
|
462261
|
+
this.trackSentMessageId(instanceId, reactionMsgId);
|
|
462262
|
+
}
|
|
462167
462263
|
correlationId && this.captureT11(correlationId);
|
|
462168
462264
|
return {
|
|
462169
462265
|
success: true,
|
|
@@ -462213,7 +462309,9 @@ class WhatsAppPlugin extends BaseChannelPlugin {
|
|
|
462213
462309
|
buildVCard(contact) {
|
|
462214
462310
|
const lines = ["BEGIN:VCARD", "VERSION:3.0", `FN:${contact.name}`];
|
|
462215
462311
|
if (contact.phone) {
|
|
462216
|
-
|
|
462312
|
+
const digits = contact.phone.replace(/[^\d]/g, "");
|
|
462313
|
+
const waid = computeWaid(digits);
|
|
462314
|
+
lines.push(`TEL;type=CELL;waid=${waid}:${contact.phone}`);
|
|
462217
462315
|
}
|
|
462218
462316
|
if (contact.email) {
|
|
462219
462317
|
lines.push(`EMAIL:${contact.email}`);
|
|
@@ -462248,12 +462346,18 @@ class WhatsAppPlugin extends BaseChannelPlugin {
|
|
|
462248
462346
|
async react(instanceId, chatId, messageId, emoji) {
|
|
462249
462347
|
const sock = this.getSocket(instanceId);
|
|
462250
462348
|
const jid = toJid(chatId);
|
|
462251
|
-
await sendReaction(sock, jid, messageId, emoji, false);
|
|
462349
|
+
const reactionMsgId = await sendReaction(sock, jid, messageId, emoji, false);
|
|
462350
|
+
if (reactionMsgId) {
|
|
462351
|
+
this.trackSentMessageId(instanceId, reactionMsgId);
|
|
462352
|
+
}
|
|
462252
462353
|
}
|
|
462253
462354
|
async unreact(instanceId, chatId, messageId, _emoji) {
|
|
462254
462355
|
const sock = this.getSocket(instanceId);
|
|
462255
462356
|
const jid = toJid(chatId);
|
|
462256
|
-
await removeReaction4(sock, jid, messageId, false);
|
|
462357
|
+
const reactionMsgId = await removeReaction4(sock, jid, messageId, false);
|
|
462358
|
+
if (reactionMsgId) {
|
|
462359
|
+
this.trackSentMessageId(instanceId, reactionMsgId);
|
|
462360
|
+
}
|
|
462257
462361
|
}
|
|
462258
462362
|
resolveMessageKey(instanceId, id, jid, isGroup, dataByExternalId, lidCache) {
|
|
462259
462363
|
const raw = dataByExternalId.get(id);
|
|
@@ -463016,7 +463120,7 @@ class WhatsAppPlugin extends BaseChannelPlugin {
|
|
|
463016
463120
|
emoji: ""
|
|
463017
463121
|
});
|
|
463018
463122
|
}
|
|
463019
|
-
if (process.env.OMNI_DUAL_EMIT_REACTIONS !== "false") {
|
|
463123
|
+
if (process.env.OMNI_DUAL_EMIT_REACTIONS !== "false" && !isFromMe2) {
|
|
463020
463124
|
await this.emitMessageReceived({
|
|
463021
463125
|
instanceId,
|
|
463022
463126
|
externalId,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@automagik/omni",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.260404.1",
|
|
4
4
|
"description": "LLM-optimized CLI for Omni",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
@@ -33,14 +33,14 @@
|
|
|
33
33
|
"qrcode-terminal": "^0.12.0"
|
|
34
34
|
},
|
|
35
35
|
"devDependencies": {
|
|
36
|
-
"@omni/api": "2.
|
|
37
|
-
"@omni/channel-discord": "2.
|
|
38
|
-
"@omni/channel-sdk": "2.
|
|
39
|
-
"@omni/channel-slack": "2.
|
|
40
|
-
"@omni/channel-telegram": "2.
|
|
41
|
-
"@omni/channel-whatsapp": "2.
|
|
42
|
-
"@omni/core": "2.
|
|
43
|
-
"@omni/sdk": "2.
|
|
36
|
+
"@omni/api": "2.260331.1",
|
|
37
|
+
"@omni/channel-discord": "2.260331.1",
|
|
38
|
+
"@omni/channel-sdk": "2.260331.1",
|
|
39
|
+
"@omni/channel-slack": "2.260331.1",
|
|
40
|
+
"@omni/channel-telegram": "2.260331.1",
|
|
41
|
+
"@omni/channel-whatsapp": "2.260331.1",
|
|
42
|
+
"@omni/core": "2.260331.1",
|
|
43
|
+
"@omni/sdk": "2.260331.1",
|
|
44
44
|
"@types/node": "^22.10.3",
|
|
45
45
|
"@types/qrcode-terminal": "^0.12.2",
|
|
46
46
|
"typescript": "^5.7.3"
|