@automagik/omni 2.260914.8 → 2.260914.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.
- package/dist/index.js +2 -2
- package/dist/server/index.js +159 -32
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -115809,7 +115809,7 @@ var require_client2 = __commonJS((exports) => {
|
|
|
115809
115809
|
|
|
115810
115810
|
// ../../node_modules/.bun/@sentry+node-core@10.52.0+2c50d7e904f6cfd7/node_modules/@sentry/node-core/build/cjs/sdk/esmLoader.js
|
|
115811
115811
|
var require_esmLoader = __commonJS((exports) => {
|
|
115812
|
-
var __filename = "/home/runner/work/omni/omni
|
|
115812
|
+
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";
|
|
115813
115813
|
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
115814
115814
|
var core = require_cjs();
|
|
115815
115815
|
var importInTheMiddle = require_import_in_the_middle();
|
|
@@ -137252,7 +137252,7 @@ import { fileURLToPath } from "url";
|
|
|
137252
137252
|
// package.json
|
|
137253
137253
|
var package_default = {
|
|
137254
137254
|
name: "@automagik/omni",
|
|
137255
|
-
version: "2.260914.
|
|
137255
|
+
version: "2.260914.9",
|
|
137256
137256
|
repository: {
|
|
137257
137257
|
type: "git",
|
|
137258
137258
|
url: "git+https://github.com/automagik-dev/omni.git",
|
package/dist/server/index.js
CHANGED
|
@@ -44926,11 +44926,14 @@ class BaseChannelPlugin {
|
|
|
44926
44926
|
ingestMode: isHistorySync ? "history-sync" : "realtime"
|
|
44927
44927
|
};
|
|
44928
44928
|
return this.publishClaimed("message.received", payload, instanceId, {
|
|
44929
|
-
idempotencyKey: `${this.id}:${instanceId}:${payload.externalId}:${payload.content.type}`,
|
|
44929
|
+
idempotencyKey: `${this.id}:${instanceId}:${this.ingressKeyId(payload.chatId, payload.externalId)}:${payload.content.type}`,
|
|
44930
44930
|
externalId: payload.externalId,
|
|
44931
44931
|
options
|
|
44932
44932
|
});
|
|
44933
44933
|
}
|
|
44934
|
+
ingressKeyId(_chatId, id) {
|
|
44935
|
+
return id;
|
|
44936
|
+
}
|
|
44934
44937
|
async publishClaimed(type, payload, instanceId, params) {
|
|
44935
44938
|
const { idempotencyKey, externalId, options = {} } = params;
|
|
44936
44939
|
if (!this.ingressClaim) {
|
|
@@ -44960,11 +44963,19 @@ class BaseChannelPlugin {
|
|
|
44960
44963
|
reactionClaimParams(kind, instanceId, payload) {
|
|
44961
44964
|
const raw = payload.rawPayload?.externalId;
|
|
44962
44965
|
const externalId = typeof raw === "string" && raw.length > 0 ? raw : `${payload.messageId}:${payload.from}`;
|
|
44963
|
-
|
|
44966
|
+
const keyId = this.ingressKeyId(payload.chatId, externalId);
|
|
44967
|
+
return { idempotencyKey: `${this.id}:${instanceId}:${keyId}:${kind}:${payload.emoji}`, externalId };
|
|
44964
44968
|
}
|
|
44965
44969
|
async emitMessageSent(params) {
|
|
44966
44970
|
const { instanceId, ...payload } = params;
|
|
44967
|
-
|
|
44971
|
+
if (!payload.externalId) {
|
|
44972
|
+
await this.publishEventInternal("message.sent", payload, instanceId);
|
|
44973
|
+
return;
|
|
44974
|
+
}
|
|
44975
|
+
await this.publishClaimed("message.sent", payload, instanceId, {
|
|
44976
|
+
idempotencyKey: `${this.id}:${instanceId}:${this.ingressKeyId(payload.chatId, payload.externalId)}:message.sent`,
|
|
44977
|
+
externalId: payload.externalId
|
|
44978
|
+
});
|
|
44968
44979
|
}
|
|
44969
44980
|
async emitMessageFailed(params) {
|
|
44970
44981
|
const { instanceId, ...payload } = params;
|
|
@@ -77027,7 +77038,7 @@ var require_ClientVoiceManager = __commonJS((exports, module) => {
|
|
|
77027
77038
|
|
|
77028
77039
|
// ../../node_modules/.bun/@discordjs+ws@1.2.3/node_modules/@discordjs/ws/dist/index.js
|
|
77029
77040
|
var require_dist9 = __commonJS((exports, module) => {
|
|
77030
|
-
var __dirname = "/home/runner/work/omni/omni
|
|
77041
|
+
var __dirname = "/home/runner/work/omni/omni/node_modules/.bun/@discordjs+ws@1.2.3/node_modules/@discordjs/ws/dist";
|
|
77031
77042
|
var __create2 = Object.create;
|
|
77032
77043
|
var __defProp2 = Object.defineProperty;
|
|
77033
77044
|
var __getOwnPropDesc2 = Object.getOwnPropertyDescriptor;
|
|
@@ -161540,7 +161551,7 @@ var require_indexes = __commonJS((exports, module) => {
|
|
|
161540
161551
|
|
|
161541
161552
|
// ../../node_modules/.bun/thread-stream@3.1.0/node_modules/thread-stream/index.js
|
|
161542
161553
|
var require_thread_stream = __commonJS((exports, module) => {
|
|
161543
|
-
var __dirname = "/home/runner/work/omni/omni
|
|
161554
|
+
var __dirname = "/home/runner/work/omni/omni/node_modules/.bun/thread-stream@3.1.0/node_modules/thread-stream";
|
|
161544
161555
|
var { version } = require_package5();
|
|
161545
161556
|
var { EventEmitter: EventEmitter3 } = __require("events");
|
|
161546
161557
|
var { Worker } = __require("worker_threads");
|
|
@@ -161961,7 +161972,7 @@ var require_thread_stream = __commonJS((exports, module) => {
|
|
|
161961
161972
|
|
|
161962
161973
|
// ../../node_modules/.bun/pino@9.14.0/node_modules/pino/lib/transport.js
|
|
161963
161974
|
var require_transport2 = __commonJS((exports, module) => {
|
|
161964
|
-
var __dirname = "/home/runner/work/omni/omni
|
|
161975
|
+
var __dirname = "/home/runner/work/omni/omni/node_modules/.bun/pino@9.14.0/node_modules/pino/lib";
|
|
161965
161976
|
var { createRequire: createRequire2 } = __require("module");
|
|
161966
161977
|
var getCallers = require_caller();
|
|
161967
161978
|
var { join: join8, isAbsolute, sep: sep2 } = __require("path");
|
|
@@ -243709,7 +243720,7 @@ var require_client3 = __commonJS((exports) => {
|
|
|
243709
243720
|
|
|
243710
243721
|
// ../../node_modules/.bun/@sentry+node-core@10.52.0+2c50d7e904f6cfd7/node_modules/@sentry/node-core/build/cjs/sdk/esmLoader.js
|
|
243711
243722
|
var require_esmLoader = __commonJS((exports) => {
|
|
243712
|
-
var __filename = "/home/runner/work/omni/omni
|
|
243723
|
+
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";
|
|
243713
243724
|
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
243714
243725
|
var core3 = require_cjs6();
|
|
243715
243726
|
var importInTheMiddle = require_import_in_the_middle();
|
|
@@ -250935,7 +250946,7 @@ var init_sentry_scrub = __esm(() => {
|
|
|
250935
250946
|
var require_package7 = __commonJS((exports, module) => {
|
|
250936
250947
|
module.exports = {
|
|
250937
250948
|
name: "@omni/api",
|
|
250938
|
-
version: "2.260914.
|
|
250949
|
+
version: "2.260914.9",
|
|
250939
250950
|
private: true,
|
|
250940
250951
|
type: "module",
|
|
250941
250952
|
exports: {
|
|
@@ -278037,7 +278048,7 @@ var require_src45 = __commonJS((exports) => {
|
|
|
278037
278048
|
|
|
278038
278049
|
// ../../node_modules/.bun/@grpc+grpc-js@1.14.3/node_modules/@grpc/grpc-js/build/src/channelz.js
|
|
278039
278050
|
var require_channelz = __commonJS((exports) => {
|
|
278040
|
-
var __dirname = "/home/runner/work/omni/omni
|
|
278051
|
+
var __dirname = "/home/runner/work/omni/omni/node_modules/.bun/@grpc+grpc-js@1.14.3/node_modules/@grpc/grpc-js/build/src";
|
|
278041
278052
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
278042
278053
|
exports.registerChannelzSocket = exports.registerChannelzServer = exports.registerChannelzSubchannel = exports.registerChannelzChannel = exports.ChannelzCallTrackerStub = exports.ChannelzCallTracker = exports.ChannelzChildrenTrackerStub = exports.ChannelzChildrenTracker = exports.ChannelzTrace = exports.ChannelzTraceStub = undefined;
|
|
278043
278054
|
exports.unregisterChannelzRef = unregisterChannelzRef;
|
|
@@ -283440,7 +283451,7 @@ var require_duration = __commonJS((exports) => {
|
|
|
283440
283451
|
|
|
283441
283452
|
// ../../node_modules/.bun/@grpc+grpc-js@1.14.3/node_modules/@grpc/grpc-js/build/src/orca.js
|
|
283442
283453
|
var require_orca = __commonJS((exports) => {
|
|
283443
|
-
var __dirname = "/home/runner/work/omni/omni
|
|
283454
|
+
var __dirname = "/home/runner/work/omni/omni/node_modules/.bun/@grpc+grpc-js@1.14.3/node_modules/@grpc/grpc-js/build/src";
|
|
283444
283455
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
283445
283456
|
exports.OrcaOobMetricsSubchannelWrapper = exports.GRPC_METRICS_HEADER = exports.ServerMetricRecorder = exports.PerRequestMetricRecorder = undefined;
|
|
283446
283457
|
exports.createOrcaClient = createOrcaClient;
|
|
@@ -362462,7 +362473,7 @@ function createIngressClaim(db2) {
|
|
|
362462
362473
|
channel: channelTypes.includes(channelType) ? channelType : "discord",
|
|
362463
362474
|
instanceId,
|
|
362464
362475
|
eventType,
|
|
362465
|
-
direction: "inbound",
|
|
362476
|
+
direction: eventType === "message.sent" ? "outbound" : "inbound",
|
|
362466
362477
|
status: "received",
|
|
362467
362478
|
idempotencyKey,
|
|
362468
362479
|
receivedAt: new Date,
|
|
@@ -397426,11 +397437,11 @@ async function setupMessageListener(eventBus) {
|
|
|
397426
397437
|
try {
|
|
397427
397438
|
await eventBus.subscribe("message.received", async (event) => {
|
|
397428
397439
|
const { externalId, chatId, from, content, rawPayload } = event.payload;
|
|
397429
|
-
const
|
|
397430
|
-
messageLog.info("Received", { from, chatId, externalId });
|
|
397431
|
-
messageLog.debug("Payload", { content: JSON.stringify(content) });
|
|
397440
|
+
const { instanceId, channelType } = event.metadata;
|
|
397441
|
+
messageLog.info("Received", { instanceId, channel: channelType, from, chatId, externalId });
|
|
397442
|
+
messageLog.debug("Payload", { instanceId, content: JSON.stringify(content) });
|
|
397432
397443
|
if (process.env.DEBUG_PAYLOADS === "true" && rawPayload) {
|
|
397433
|
-
messageLog.debug("Raw payload", { rawPayload });
|
|
397444
|
+
messageLog.debug("Raw payload", { instanceId, rawPayload });
|
|
397434
397445
|
}
|
|
397435
397446
|
});
|
|
397436
397447
|
messageLog.info("Listening for message.received events");
|
|
@@ -397671,8 +397682,7 @@ async function setupEventPersistence(eventBus, db2) {
|
|
|
397671
397682
|
const sdb = scopedHandle(db2);
|
|
397672
397683
|
const chatLink = await resolveChatLink(sdb, metadata.instanceId, payload.chatId);
|
|
397673
397684
|
const replyToEventId = await resolveReplyToEventId(sdb, metadata.instanceId, payload.replyToId);
|
|
397674
|
-
const
|
|
397675
|
-
...eventIdInsert(event.id),
|
|
397685
|
+
const columns2 = {
|
|
397676
397686
|
externalId: payload.externalId,
|
|
397677
397687
|
channel: mapChannelType(metadata.channelType),
|
|
397678
397688
|
instanceId: metadata.instanceId,
|
|
@@ -397702,7 +397712,7 @@ async function setupEventPersistence(eventBus, db2) {
|
|
|
397702
397712
|
conversationId: null,
|
|
397703
397713
|
...chatLink
|
|
397704
397714
|
};
|
|
397705
|
-
await sdb.insert(omniEvents).values(
|
|
397715
|
+
await sdb.insert(omniEvents).values({ ...eventIdInsert(event.id), ...columns2 }).onConflictDoUpdate({ target: omniEvents.id, set: columns2 });
|
|
397706
397716
|
});
|
|
397707
397717
|
log127.debug("Persisted message.sent", {
|
|
397708
397718
|
externalId: payload.externalId,
|
|
@@ -410017,6 +410027,7 @@ var import_bolt = __toESM(require_dist16(), 1);
|
|
|
410017
410027
|
var import_web_api = __toESM(require_dist13(), 1);
|
|
410018
410028
|
var HTTP_MAX_BODY_BYTES = 1024 * 1024;
|
|
410019
410029
|
var SOCKET_OPEN_TIMEOUT_MS = 1e4;
|
|
410030
|
+
var SOCKET_STALE_AFTER_MS = 5 * 60000;
|
|
410020
410031
|
function buildActingClients(options, botClient) {
|
|
410021
410032
|
if (options.authMode !== "user")
|
|
410022
410033
|
return { actingClient: botClient };
|
|
@@ -410078,8 +410089,15 @@ function watchSocketLifecycle(connection, logger5) {
|
|
|
410078
410089
|
connection.socketState = state;
|
|
410079
410090
|
connection.onSocketStateChange?.(state);
|
|
410080
410091
|
};
|
|
410092
|
+
const touch = () => {
|
|
410093
|
+
connection.lastSocketActivityAt = Date.now();
|
|
410094
|
+
};
|
|
410095
|
+
socketClient.on("ws_message", touch);
|
|
410081
410096
|
socketClient.on("connected", () => {
|
|
410082
410097
|
logger5.info("Slack Socket Mode WebSocket connected");
|
|
410098
|
+
touch();
|
|
410099
|
+
const raw = socketClient.websocket?.websocket;
|
|
410100
|
+
raw?.on?.("ping", touch);
|
|
410083
410101
|
transition("connected");
|
|
410084
410102
|
});
|
|
410085
410103
|
socketClient.on("reconnecting", () => {
|
|
@@ -410219,6 +410237,7 @@ async function resolveIdentities(connection, logger5) {
|
|
|
410219
410237
|
try {
|
|
410220
410238
|
const authResult = await connection.app.client.auth.test();
|
|
410221
410239
|
connection.botUserId = authResult.user_id ?? undefined;
|
|
410240
|
+
connection.botId = authResult.bot_id ?? undefined;
|
|
410222
410241
|
connection.botName = authResult.user ?? undefined;
|
|
410223
410242
|
connection.teamId = authResult.team_id ?? undefined;
|
|
410224
410243
|
connection.teamName = authResult.team ?? undefined;
|
|
@@ -410275,9 +410294,15 @@ function isSocketOpen(connection) {
|
|
|
410275
410294
|
return false;
|
|
410276
410295
|
const websocket = socketClient.websocket;
|
|
410277
410296
|
if (websocket)
|
|
410278
|
-
return websocket.isActive();
|
|
410297
|
+
return websocket.isActive() && !isSocketStale(connection);
|
|
410279
410298
|
return connection.socketState === "connected";
|
|
410280
410299
|
}
|
|
410300
|
+
function isSocketStale(connection, now = Date.now()) {
|
|
410301
|
+
const last = connection.lastSocketActivityAt;
|
|
410302
|
+
if (last === undefined)
|
|
410303
|
+
return false;
|
|
410304
|
+
return now - last > (connection.socketStaleAfterMs ?? SOCKET_STALE_AFTER_MS);
|
|
410305
|
+
}
|
|
410281
410306
|
async function destroyBoltConnection(connection, logger5) {
|
|
410282
410307
|
connection.onSocketStateChange = undefined;
|
|
410283
410308
|
try {
|
|
@@ -410627,12 +410652,14 @@ function extractMessageMeta(event) {
|
|
|
410627
410652
|
channelType
|
|
410628
410653
|
};
|
|
410629
410654
|
}
|
|
410630
|
-
function shouldSkipMessage(msg, selfUserIds) {
|
|
410631
|
-
if (msg.subtype === "bot_message" || msg.bot_id)
|
|
410632
|
-
return true;
|
|
410655
|
+
function shouldSkipMessage(msg, selfUserIds, ownBotId) {
|
|
410633
410656
|
if (msg.subtype === "message_changed" || msg.subtype === "message_deleted")
|
|
410634
410657
|
return true;
|
|
410635
410658
|
const userId = msg.user;
|
|
410659
|
+
if (msg.subtype === "bot_message" && !userId)
|
|
410660
|
+
return true;
|
|
410661
|
+
if (msg.bot_id && (!userId || msg.bot_id === ownBotId))
|
|
410662
|
+
return true;
|
|
410636
410663
|
if (!userId)
|
|
410637
410664
|
return true;
|
|
410638
410665
|
if (selfUserIds.some((id) => id && id === userId))
|
|
@@ -410754,20 +410781,30 @@ async function processMessage2(instanceId, msg, currentBotUserId, callbacks, log
|
|
|
410754
410781
|
}
|
|
410755
410782
|
await callbacks.onMessage(instanceId, meta.ts, meta.channelId, userId, content, replyToId, rawPayload, platformTimestamp, meta);
|
|
410756
410783
|
}
|
|
410757
|
-
function setupMessageHandlers2(app, instanceId, botUserId, callbacks, dmPolicyConfig, logger5, filterConfig, reliability, actingUserId) {
|
|
410784
|
+
function setupMessageHandlers2(app, instanceId, botUserId, callbacks, dmPolicyConfig, logger5, filterConfig, reliability, actingUserId, ownBotId) {
|
|
410758
410785
|
const resolveBotUserId = () => typeof botUserId === "function" ? botUserId() : botUserId;
|
|
410759
410786
|
const resolveActingUserId = () => typeof actingUserId === "function" ? actingUserId() : actingUserId;
|
|
410760
|
-
|
|
410761
|
-
|
|
410762
|
-
|
|
410787
|
+
const handle = async (msg) => {
|
|
410788
|
+
if (shouldSkipMessage(msg, [resolveBotUserId(), resolveActingUserId()], ownBotId?.())) {
|
|
410789
|
+
logger5.debug("Message skipped: bot/self/edit", {
|
|
410790
|
+
instanceId,
|
|
410791
|
+
channelId: msg.channel,
|
|
410792
|
+
ts: msg.ts,
|
|
410793
|
+
subtype: msg.subtype,
|
|
410794
|
+
botId: msg.bot_id,
|
|
410795
|
+
userId: msg.user
|
|
410796
|
+
});
|
|
410763
410797
|
return;
|
|
410798
|
+
}
|
|
410764
410799
|
const userId = msg.user;
|
|
410765
410800
|
const meta = extractMessageMeta(msg);
|
|
410766
410801
|
if (await enforceDmPolicy(meta, userId, dmPolicyConfig, instanceId, callbacks, logger5))
|
|
410767
410802
|
return;
|
|
410768
410803
|
await processMessage2(instanceId, msg, resolveBotUserId(), callbacks, logger5, reliability, filterConfig);
|
|
410769
|
-
}
|
|
410804
|
+
};
|
|
410805
|
+
app.message(async ({ message: message2 }) => handle(message2));
|
|
410770
410806
|
logger5.info("Message handlers registered", { instanceId });
|
|
410807
|
+
return handle;
|
|
410771
410808
|
}
|
|
410772
410809
|
|
|
410773
410810
|
// ../channel-slack/src/handlers/pins.ts
|
|
@@ -411586,6 +411623,8 @@ class SlackPlugin extends BaseChannelPlugin {
|
|
|
411586
411623
|
presenceStatusTimers = new Map;
|
|
411587
411624
|
pendingAckReactions = new Map;
|
|
411588
411625
|
activeNativeStreams = new Map;
|
|
411626
|
+
lastSeenTs = new Map;
|
|
411627
|
+
inboundHandlers = new Map;
|
|
411589
411628
|
async onInitialize(_context) {}
|
|
411590
411629
|
async onDestroy() {
|
|
411591
411630
|
for (const [instanceId, connection] of this.connections) {
|
|
@@ -411677,6 +411716,7 @@ class SlackPlugin extends BaseChannelPlugin {
|
|
|
411677
411716
|
ownerIdentifier: connection.botUserId
|
|
411678
411717
|
});
|
|
411679
411718
|
this.watchSocketState(instanceId, config2, connection);
|
|
411719
|
+
this.backfillMissedMessages(instanceId, connection);
|
|
411680
411720
|
this.logger.info("Slack instance connected", {
|
|
411681
411721
|
instanceId,
|
|
411682
411722
|
botName: connection.botName,
|
|
@@ -411706,6 +411746,8 @@ class SlackPlugin extends BaseChannelPlugin {
|
|
|
411706
411746
|
await destroyBoltConnection(connection, this.logger);
|
|
411707
411747
|
this.connections.delete(instanceId);
|
|
411708
411748
|
this.slackConfigs.delete(instanceId);
|
|
411749
|
+
this.lastSeenTs.delete(instanceId);
|
|
411750
|
+
this.inboundHandlers.delete(instanceId);
|
|
411709
411751
|
for (const key of this.userNameCache.keys()) {
|
|
411710
411752
|
if (key.startsWith(`${instanceId}:`))
|
|
411711
411753
|
this.userNameCache.delete(key);
|
|
@@ -411765,6 +411807,7 @@ class SlackPlugin extends BaseChannelPlugin {
|
|
|
411765
411807
|
return;
|
|
411766
411808
|
if (state === "connected") {
|
|
411767
411809
|
this.logger.info("Slack Socket Mode connection restored", { instanceId });
|
|
411810
|
+
this.backfillMissedMessages(instanceId, connection);
|
|
411768
411811
|
setStatus({
|
|
411769
411812
|
state: "connected",
|
|
411770
411813
|
since: new Date,
|
|
@@ -412218,7 +412261,7 @@ class SlackPlugin extends BaseChannelPlugin {
|
|
|
412218
412261
|
cursor
|
|
412219
412262
|
});
|
|
412220
412263
|
for (const msg of response.messages ?? []) {
|
|
412221
|
-
const result = await this.buildHistorySyncMessage(msg, channelId, botUserId, botToken);
|
|
412264
|
+
const result = await this.buildHistorySyncMessage(msg, channelId, botUserId, botToken, connection.botId);
|
|
412222
412265
|
if (result)
|
|
412223
412266
|
messages.push(result);
|
|
412224
412267
|
if (messages.length >= maxMessages)
|
|
@@ -412244,9 +412287,9 @@ class SlackPlugin extends BaseChannelPlugin {
|
|
|
412244
412287
|
return { mimeType, localPath: undefined };
|
|
412245
412288
|
}
|
|
412246
412289
|
}
|
|
412247
|
-
async buildHistorySyncMessage(msg, channelId, botUserId, botToken) {
|
|
412290
|
+
async buildHistorySyncMessage(msg, channelId, botUserId, botToken, ownBotId) {
|
|
412248
412291
|
const userId = msg.user;
|
|
412249
|
-
if (
|
|
412292
|
+
if (!userId || shouldSkipMessage(msg, [botUserId], ownBotId))
|
|
412250
412293
|
return null;
|
|
412251
412294
|
const ts = msg.ts;
|
|
412252
412295
|
const text = msg.text ?? "";
|
|
@@ -412362,6 +412405,83 @@ class SlackPlugin extends BaseChannelPlugin {
|
|
|
412362
412405
|
instanceId
|
|
412363
412406
|
});
|
|
412364
412407
|
}
|
|
412408
|
+
recordSeen(instanceId, msg) {
|
|
412409
|
+
const channelId = msg.channel;
|
|
412410
|
+
const ts = msg.ts;
|
|
412411
|
+
if (!channelId || !ts)
|
|
412412
|
+
return;
|
|
412413
|
+
let seen = this.lastSeenTs.get(instanceId);
|
|
412414
|
+
if (!seen) {
|
|
412415
|
+
seen = new Map;
|
|
412416
|
+
this.lastSeenTs.set(instanceId, seen);
|
|
412417
|
+
}
|
|
412418
|
+
const threadTs = msg.thread_ts;
|
|
412419
|
+
const keys = threadTs && threadTs !== ts ? [channelId, `${channelId}:${threadTs}`] : [channelId];
|
|
412420
|
+
for (const key of keys) {
|
|
412421
|
+
const prev = seen.get(key);
|
|
412422
|
+
if (!prev || Number.parseFloat(ts) > Number.parseFloat(prev))
|
|
412423
|
+
seen.set(key, ts);
|
|
412424
|
+
}
|
|
412425
|
+
}
|
|
412426
|
+
async backfillMissedMessages(instanceId, connection) {
|
|
412427
|
+
const seen = this.lastSeenTs.get(instanceId);
|
|
412428
|
+
const handle = this.inboundHandlers.get(instanceId);
|
|
412429
|
+
if (!seen?.size || !handle)
|
|
412430
|
+
return 0;
|
|
412431
|
+
const missed = new Map;
|
|
412432
|
+
const collect = (channelId, oldest, msgs) => {
|
|
412433
|
+
for (const raw of msgs ?? []) {
|
|
412434
|
+
const ts = raw.ts;
|
|
412435
|
+
if (!ts || Number.parseFloat(ts) <= Number.parseFloat(oldest))
|
|
412436
|
+
continue;
|
|
412437
|
+
missed.set(`${channelId}:${ts}`, {
|
|
412438
|
+
...raw,
|
|
412439
|
+
channel: channelId,
|
|
412440
|
+
channel_type: raw.channel_type ?? (channelId.startsWith("D") ? "im" : undefined)
|
|
412441
|
+
});
|
|
412442
|
+
}
|
|
412443
|
+
};
|
|
412444
|
+
for (const [key, oldest] of [...seen]) {
|
|
412445
|
+
const [channelId, threadTs] = key.split(":");
|
|
412446
|
+
try {
|
|
412447
|
+
if (threadTs) {
|
|
412448
|
+
const res2 = await connection.actingClient.conversations.replies({ channel: channelId, ts: threadTs, oldest });
|
|
412449
|
+
collect(channelId, oldest, res2.messages);
|
|
412450
|
+
continue;
|
|
412451
|
+
}
|
|
412452
|
+
const res = await connection.actingClient.conversations.history({ channel: channelId, oldest, limit: 200 });
|
|
412453
|
+
collect(channelId, oldest, res.messages);
|
|
412454
|
+
for (const parent of res.messages ?? []) {
|
|
412455
|
+
const latestReply = parent.latest_reply;
|
|
412456
|
+
if (!latestReply || Number.parseFloat(latestReply) <= Number.parseFloat(oldest))
|
|
412457
|
+
continue;
|
|
412458
|
+
const replies = await connection.actingClient.conversations.replies({
|
|
412459
|
+
channel: channelId,
|
|
412460
|
+
ts: parent.ts,
|
|
412461
|
+
oldest
|
|
412462
|
+
});
|
|
412463
|
+
collect(channelId, oldest, replies.messages);
|
|
412464
|
+
}
|
|
412465
|
+
} catch (err2) {
|
|
412466
|
+
this.logger.warn("Slack backfill fetch failed", { instanceId, channelId, threadTs, error: String(err2) });
|
|
412467
|
+
}
|
|
412468
|
+
}
|
|
412469
|
+
const ordered = [...missed.values()].sort((a, b2) => Number.parseFloat(a.ts) - Number.parseFloat(b2.ts));
|
|
412470
|
+
for (const msg of ordered) {
|
|
412471
|
+
this.recordSeen(instanceId, msg);
|
|
412472
|
+
try {
|
|
412473
|
+
await handle(msg);
|
|
412474
|
+
} catch (err2) {
|
|
412475
|
+
this.logger.warn("Slack backfill dispatch failed", { instanceId, ts: msg.ts, error: String(err2) });
|
|
412476
|
+
}
|
|
412477
|
+
}
|
|
412478
|
+
this.logger.info("Slack reconnect backfill complete", {
|
|
412479
|
+
instanceId,
|
|
412480
|
+
conversations: seen.size,
|
|
412481
|
+
recovered: ordered.length
|
|
412482
|
+
});
|
|
412483
|
+
return ordered.length;
|
|
412484
|
+
}
|
|
412365
412485
|
trackActiveThread(instanceId, channelId, threadTs) {
|
|
412366
412486
|
this.activeThreads.set(`${instanceId}:${channelId}`, threadTs);
|
|
412367
412487
|
}
|
|
@@ -412440,7 +412560,10 @@ class SlackPlugin extends BaseChannelPlugin {
|
|
|
412440
412560
|
await this.handleMessageReceived(instanceId, args.externalId, args.chatId, args.from, args.content, args.replyToId, enrichedPayload, args.platformTimestamp);
|
|
412441
412561
|
}
|
|
412442
412562
|
setupHandlers(instanceId, connection, config2, reliability) {
|
|
412443
|
-
|
|
412563
|
+
connection.app.message(async ({ message: message2 }) => {
|
|
412564
|
+
this.recordSeen(instanceId, message2);
|
|
412565
|
+
});
|
|
412566
|
+
const handleInbound = setupMessageHandlers2(connection.app, instanceId, () => connection.botUserId, {
|
|
412444
412567
|
onMessage: async (_instId, externalId, chatId, from, content, replyToId, rawPayload, platformTimestamp, _meta) => {
|
|
412445
412568
|
const threadTs = rawPayload.threadTs;
|
|
412446
412569
|
this.trackActiveThread(instanceId, chatId, threadTs ?? externalId);
|
|
@@ -412473,7 +412596,8 @@ class SlackPlugin extends BaseChannelPlugin {
|
|
|
412473
412596
|
channelAllowlist: config2.channelAllowlist,
|
|
412474
412597
|
channelBlocklist: config2.channelBlocklist,
|
|
412475
412598
|
channels: config2.channels
|
|
412476
|
-
}, reliability, () => connection.actingUserId);
|
|
412599
|
+
}, reliability, () => connection.actingUserId, () => connection.botId);
|
|
412600
|
+
this.inboundHandlers.set(instanceId, handleInbound);
|
|
412477
412601
|
setupReactionHandlers2(connection.app, instanceId, () => connection.botUserId, {
|
|
412478
412602
|
onReaction: async (instId, messageId, chatId, userId, emoji, action) => {
|
|
412479
412603
|
await this.handleReactionReceived(instId, messageId, chatId, userId, emoji, action);
|
|
@@ -414973,6 +415097,9 @@ class TelegramPlugin extends BaseChannelPlugin {
|
|
|
414973
415097
|
configs = new Map;
|
|
414974
415098
|
cleanups = new Map;
|
|
414975
415099
|
dedupeCaches = new Map;
|
|
415100
|
+
ingressKeyId(chatId, id) {
|
|
415101
|
+
return `${chatId}:${id}`;
|
|
415102
|
+
}
|
|
414976
415103
|
typingIntervals = new Map;
|
|
414977
415104
|
async onInitialize(_context) {
|
|
414978
415105
|
this.logger.info("Telegram plugin initialized");
|