mirror of
https://github.com/xCyanGrizzly/DragonsStash.git
synced 2026-05-10 22:01:16 +00:00
feat: fix multi-part archive forwarding and add kickstarter package linking
All checks were successful
continuous-integration/drone/push Build is passing
All checks were successful
continuous-integration/drone/push Build is passing
Multi-part send fix: - Add destMessageIds BigInt[] to Package schema with backfill migration - Worker uploadToChannel now returns all message IDs, stored in DB - Bot forwards all parts of multi-part archives (not just the first) - Add retry logic for upload rate limits (429) and download stalls Kickstarter package linking: - Add package search/linking queries and API routes - Add PackageLinkerDialog with search + checkbox selection - Add "Link Packages" and "Send All" actions to kickstarter table - Add sendAllKickstarterPackages server action Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -122,6 +122,9 @@ export async function getPendingSendRequest(requestId: string) {
|
||||
archiveType: true,
|
||||
destChannelId: true,
|
||||
destMessageId: true,
|
||||
destMessageIds: true,
|
||||
isMultipart: true,
|
||||
partCount: true,
|
||||
previewData: true,
|
||||
sourceChannel: { select: { title: true, telegramId: true } },
|
||||
},
|
||||
|
||||
@@ -7,7 +7,7 @@ import {
|
||||
findMatchingSubscriptions,
|
||||
getGlobalDestinationChannel,
|
||||
} from "./db/queries.js";
|
||||
import { copyMessageToUser, sendTextMessage, sendPhotoMessage } from "./tdlib/client.js";
|
||||
import { copyMessageToUser, copyMultipleMessagesToUser, sendTextMessage, sendPhotoMessage } from "./tdlib/client.js";
|
||||
import { sleep } from "./util/flood-wait.js";
|
||||
|
||||
const log = childLogger("send-listener");
|
||||
@@ -154,11 +154,25 @@ async function processSendRequest(requestId: string): Promise<void> {
|
||||
}
|
||||
|
||||
// Forward the actual archive file(s) from destination channel
|
||||
await copyMessageToUser(
|
||||
destChannel.telegramId,
|
||||
pkg.destMessageId,
|
||||
targetUserId
|
||||
);
|
||||
const messageIds = pkg.destMessageIds as bigint[] | undefined;
|
||||
if (messageIds && messageIds.length > 1) {
|
||||
log.info(
|
||||
{ requestId, parts: messageIds.length },
|
||||
"Sending multi-part archive"
|
||||
);
|
||||
await copyMultipleMessagesToUser(
|
||||
destChannel.telegramId,
|
||||
messageIds,
|
||||
targetUserId
|
||||
);
|
||||
} else {
|
||||
// Single part or legacy (no destMessageIds populated)
|
||||
await copyMessageToUser(
|
||||
destChannel.telegramId,
|
||||
pkg.destMessageId,
|
||||
targetUserId
|
||||
);
|
||||
}
|
||||
|
||||
await updateSendRequest(requestId, "SENT");
|
||||
log.info({ requestId }, "Send request completed successfully");
|
||||
|
||||
@@ -121,6 +121,25 @@ export async function copyMessageToUser(
|
||||
}, fileName);
|
||||
}
|
||||
|
||||
/**
|
||||
* Send multiple document messages from a channel to a user's DM.
|
||||
* Used for multi-part archives where each part is a separate Telegram message.
|
||||
* Sends parts sequentially with a small delay to avoid rate limits.
|
||||
*/
|
||||
export async function copyMultipleMessagesToUser(
|
||||
fromChatId: bigint,
|
||||
messageIds: bigint[],
|
||||
toUserId: bigint
|
||||
): Promise<void> {
|
||||
for (let i = 0; i < messageIds.length; i++) {
|
||||
await copyMessageToUser(fromChatId, messageIds[i], toUserId);
|
||||
// Small delay between parts to avoid rate limits
|
||||
if (i < messageIds.length - 1) {
|
||||
await new Promise((resolve) => setTimeout(resolve, 1000));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Send a message and wait for Telegram to confirm delivery.
|
||||
* Returns when updateMessageSendSucceeded fires for the temp message.
|
||||
|
||||
Reference in New Issue
Block a user