(
msg: Api.Message,
mediaItems: T[],
prompt: string,
replyToId: number | undefined,
token: AbortToken | undefined,
options: {
previewEnabled: boolean;
poweredByTag: string;
collapse: boolean;
directory: string;
filePrefix: string;
rawFilePrefix?: string;
getExtension: (mimeType: string) => string;
resolve: (
item: T,
mediaToken?: AbortToken,
) => Promise<{ data?: Buffer; mimeType: string } | null>;
prepareForSend?: (rawPath: string, finalPath: string) => Promise<string>;
},
)
| 1391 | |
| 1392 | private async sendMedia<T extends AIImage | AIVideo>( |
| 1393 | msg: Api.Message, |
| 1394 | mediaItems: T[], |
| 1395 | prompt: string, |
| 1396 | replyToId: number | undefined, |
| 1397 | token: AbortToken | undefined, |
| 1398 | options: { |
| 1399 | previewEnabled: boolean; |
| 1400 | poweredByTag: string; |
| 1401 | collapse: boolean; |
| 1402 | directory: string; |
| 1403 | filePrefix: string; |
| 1404 | rawFilePrefix?: string; |
| 1405 | getExtension: (mimeType: string) => string; |
| 1406 | resolve: ( |
| 1407 | item: T, |
| 1408 | mediaToken?: AbortToken, |
| 1409 | ) => Promise<{ data?: Buffer; mimeType: string } | null>; |
| 1410 | prepareForSend?: (rawPath: string, finalPath: string) => Promise<string>; |
| 1411 | }, |
| 1412 | ): Promise<void> { |
| 1413 | if (!mediaItems.length) return; |
| 1414 | |
| 1415 | const peerId = msg.chatId || msg.peerId; |
| 1416 | const promptText = htmlEscape(prompt); |
| 1417 | const promptBlock = options.collapse |
| 1418 | ? `<blockquote expandable>${promptText}</blockquote>` |
| 1419 | : promptText; |
| 1420 | const poweredByText = `\n<i>🍀Powered by ${options.poweredByTag}</i>`; |
| 1421 | const caption = promptBlock + poweredByText; |
| 1422 | const mediaDir = createDirectoryInAssets(options.directory); |
| 1423 | const timestamp = Date.now(); |
| 1424 | |
| 1425 | for (let i = 0; i < mediaItems.length; i++) { |
| 1426 | const item = mediaItems[i]; |
| 1427 | token?.throwIfAborted(); |
| 1428 | |
| 1429 | const resolved = await options.resolve(item, token); |
| 1430 | if (!resolved?.data) continue; |
| 1431 | |
| 1432 | const extension = options.getExtension(resolved.mimeType); |
| 1433 | const rawPrefix = options.rawFilePrefix ?? options.filePrefix; |
| 1434 | const rawName = `${rawPrefix}_${timestamp}_${i}${extension}`; |
| 1435 | const finalName = `${options.filePrefix}_${timestamp}_${i}${extension}`; |
| 1436 | const rawPath = path.join(mediaDir, rawName); |
| 1437 | const finalPath = path.join(mediaDir, finalName); |
| 1438 | |
| 1439 | try { |
| 1440 | await fs.promises.writeFile(rawPath, resolved.data); |
| 1441 | const pathToSend = options.prepareForSend |
| 1442 | ? await options.prepareForSend(rawPath, finalPath) |
| 1443 | : rawPath; |
| 1444 | |
| 1445 | if (!msg.client) { |
| 1446 | throw new Error("客户端未初始化"); |
| 1447 | } |
| 1448 | |
| 1449 | const topicRootId = getTopicRootId(msg); |
| 1450 | const replyTo = replyToId ?? topicRootId; |
no test coverage detected