Files
PIT_Channel/src/outbound.ts

119 lines
3.2 KiB
TypeScript
Raw Normal View History

/**
* Outbound -
* @module outbound
*/
import type { SendResult } from "./types.js";
import { chunkText } from "./utils/chunker.js";
import { createLogger } from "./utils/logger.js";
const MODULE = "outbound";
// 外部 Gateway 管理器 - 由 channel.ts 注入
let gatewayMap: Map<string, {
sendText: (to: string, content: string, replyTo?: string) => Promise<{ success: boolean; messageId?: string; error?: string }>;
sendMedia: (to: string, mediaUrl: string, text?: string, replyTo?: string) => Promise<{ success: boolean; messageId?: string; error?: string }>;
}> | null = null;
/**
* Gateway channel.ts
*/
export function setGatewayMap(map: Map<string, never>): void {
gatewayMap = map as unknown as typeof gatewayMap;
}
/**
*
*/
export async function sendText(options: {
to: string;
text: string;
accountId: string;
replyToId?: string;
}): Promise<SendResult> {
const { to, text, accountId, replyToId } = options;
const log = createLogger(MODULE);
try {
const gateway = gatewayMap?.get(accountId);
if (!gateway) {
return { messageId: "", error: "Gateway not available" };
}
// 获取分块限制
const chunkLimit = 4000;
const chunks = chunkText(text, { limit: chunkLimit, mode: "markdown" });
if (chunks.length === 1) {
const result = await gateway.sendText(to, text, replyToId);
return {
messageId: result.messageId ?? "",
error: result.error,
};
}
// 多块消息,逐块发送
const messageIds: string[] = [];
let lastError: string | undefined;
for (let i = 0; i < chunks.length; i++) {
const chunk = chunks[i];
const chunkSuffix = chunks.length > 1 ? `\n\n--- [${i + 1}/${chunks.length}] ---` : "";
const result = await gateway.sendText(to, chunk + chunkSuffix, replyToId);
if (result.messageId) {
messageIds.push(result.messageId);
}
if (result.error) {
lastError = result.error;
}
// 块之间添加延迟
if (i < chunks.length - 1) {
await new Promise(resolve => setTimeout(resolve, 100));
}
}
return {
messageId: messageIds.join(","),
error: lastError,
};
} catch (error) {
const message = error instanceof Error ? error.message : String(error);
log.error("Failed to send text", { to, error: message });
return { messageId: "", error: message };
}
}
/**
*
*/
export async function sendMedia(options: {
to: string;
text?: string;
mediaUrl: string;
accountId: string;
replyToId?: string;
}): Promise<SendResult> {
const { to, text, mediaUrl, accountId, replyToId } = options;
const log = createLogger(MODULE);
try {
const gateway = gatewayMap?.get(accountId);
if (!gateway) {
return { messageId: "", error: "Gateway not available" };
}
const result = await gateway.sendMedia(to, mediaUrl, text, replyToId);
return {
messageId: result.messageId ?? "",
error: result.error,
};
} catch (error) {
const message = error instanceof Error ? error.message : String(error);
log.error("Failed to send media", { to, mediaUrl, error: message });
return { messageId: "", error: message };
}
}