Fix multiple issues

This commit is contained in:
2026-03-07 21:33:40 +01:00
parent 6926df9a2c
commit 2763de2711
11 changed files with 524 additions and 156 deletions

View File

@@ -12,29 +12,78 @@ import { copyMessageToUser, sendTextMessage, sendPhotoMessage } from "./tdlib/cl
const log = childLogger("send-listener");
let pgClient: pg.PoolClient | null = null;
let stopped = false;
/** Delay (ms) before attempting to reconnect after a connection loss. */
const RECONNECT_DELAY_MS = 5_000;
/**
* Start listening for pg_notify signals:
* - `bot_send` — payload = requestId → send a package to a user
* - `new_package` — payload = JSON { packageId, fileName, creator } → notify subscribers
*
* If the underlying connection is lost, the listener automatically reconnects
* so that pg_notify signals are never silently dropped.
*/
export async function startSendListener(): Promise<void> {
pgClient = await pool.connect();
await pgClient.query("LISTEN bot_send");
await pgClient.query("LISTEN new_package");
stopped = false;
await connectListener();
}
pgClient.on("notification", (msg) => {
if (msg.channel === "bot_send" && msg.payload) {
handleBotSend(msg.payload);
} else if (msg.channel === "new_package" && msg.payload) {
handleNewPackage(msg.payload);
async function connectListener(): Promise<void> {
try {
pgClient = await pool.connect();
await pgClient.query("LISTEN bot_send");
await pgClient.query("LISTEN new_package");
pgClient.on("notification", (msg) => {
if (msg.channel === "bot_send" && msg.payload) {
handleBotSend(msg.payload);
} else if (msg.channel === "new_package" && msg.payload) {
handleNewPackage(msg.payload);
}
});
// Reconnect automatically when the connection ends unexpectedly
pgClient.on("end", () => {
if (!stopped) {
log.warn("Send listener connection lost — reconnecting");
pgClient = null;
scheduleReconnect();
}
});
pgClient.on("error", (err) => {
log.error({ err }, "Send listener connection error");
if (!stopped && pgClient) {
try {
pgClient.release(true);
} catch (releaseErr) {
log.debug({ err: releaseErr }, "Failed to release pg client after error");
}
pgClient = null;
scheduleReconnect();
}
});
log.info("Send listener started (bot_send, new_package)");
} catch (err) {
log.error({ err }, "Failed to start send listener — retrying");
scheduleReconnect();
}
}
function scheduleReconnect(): void {
if (stopped) return;
setTimeout(() => {
if (!stopped) {
connectListener();
}
});
log.info("Send listener started (bot_send, new_package)");
}, RECONNECT_DELAY_MS);
}
export function stopSendListener(): void {
stopped = true;
if (pgClient) {
pgClient.release();
pgClient = null;

View File

@@ -33,7 +33,7 @@ export async function createBotClient(): Promise<tdl.Client> {
await client.login(() => ({
type: "bot",
token: config.botToken,
getToken: () => Promise.resolve(config.botToken),
}));
log.info("Bot client authenticated successfully");
@@ -54,7 +54,10 @@ export async function closeBotClient(): Promise<void> {
/**
* Forward a message from a channel to a user's DM.
* Uses copyMessage to make it appear as sent by the bot.
* Uses forwardMessages with send_copy to make it appear as sent by the bot.
*
* The fromChatId is the TDLib chat ID stored in the DB — already in the correct
* format (negative for supergroups/channels, e.g. -1001234567890).
*/
export async function copyMessageToUser(
fromChatId: bigint,
@@ -63,14 +66,10 @@ export async function copyMessageToUser(
): Promise<void> {
if (!client) throw new Error("Bot client not initialized");
// TDLib uses negative chat IDs for channels/supergroups
// The telegramId from the DB is the raw Telegram ID; for channels it needs -100 prefix
const fromChatIdNum = Number(-100n * 1n) + Number(fromChatId);
await client.invoke({
_: "forwardMessages",
chat_id: Number(toUserId),
from_chat_id: Number(fromChatId) > 0 ? -Number(fromChatId) : Number(fromChatId),
from_chat_id: Number(fromChatId),
message_ids: [Number(messageId)],
send_copy: true,
remove_caption: false,