This commit is contained in:
Vaica committed 2026-06-24 17:35:07 +08:00
1 parent b86b170814
commit 192032d780
2 files changed
+46 -112

No files matched your search

+40 -112
View File
@@ -391,6 +391,17 @@ async function handleInlineCallback(chatId: number, queryId: string, data: strin
try { await tg("answerCallbackQuery", { callback_query_id: queryId }); } catch (_e) {}
}
// ============================================================
// 新增:处理语音消息(增强版:保存文件 + 转文字 + 生成短代码)
// ============================================================
async function handleVoiceEnhanced(chatId: number, fileId: string, duration?: number) {
try {
const fs = await import("fs");
const path = await import("path");
const { getSession } = await import("./sessions");
const { transcribeAudio } = await import("@/lib/voice");
const s = getSession(chatId);
if (!s.dirPath) {
await sendMessage(chatId, "❌ 请先发 /new 或 /edit 开始写作");
@@ -438,7 +449,11 @@ async function handleInlineCallback(chatId: number, queryId: string, data: strin
}
}
async function handleAudio(chatId: number, fileId: string, fileName?: string, mimeType?: string) {
// ============================================================
// 新增:处理音频文件(增强版:支持封面图)
// ============================================================
async function handleAudioEnhanced(chatId: number, fileId: string, fileName?: string) {
try {
const fs = await import("fs");
const path = await import("path");
@@ -470,7 +485,7 @@ async function handleAudio(chatId: number, fileId: string, fileName?: string, mi
fs.writeFileSync(path.join(articleDir, filename), Buffer.from(audioBuffer));
const session = getSession(chatId);
session._pendingAudio = { filename, fileId };
session._pendingAudio = { filename, fileId, name: null, artist: null };
await tg("sendMessage", {
chat_id: chatId,
@@ -486,31 +501,8 @@ async function handleAudio(chatId: number, fileId: string, fileName?: string, mi
}
}
async function handleAudioInfo(chatId: number, text: string): Promise<boolean> {
try {
const { getSession } = await import("./sessions");
const s = getSession(chatId);
if (!s._pendingAudio) {
return false;
}
const { filename } = s._pendingAudio;
delete s._pendingAudio;
let name = "未知歌曲";
let artist = "未知艺术家";
const parts = text.split(/[-–—]/);
if (parts.length >= 2) {
name = parts[0].trim();
artist = parts.slice(1).join("-").trim();
} else if (text.trim()) {
name = text.trim();
}
co// ============================================================
// 增强版 handlePhoto:支持封面图上传 + 实况照片引导
// ============================================================
// 新增:处理图片(增强版:支持封面图上传 + 实况照片引导)
// ============================================================
async function handlePhotoEnhanced(chatId: number, photos: { file_id: string }[], caption?: string) {
@@ -540,7 +532,6 @@ async function handlePhotoEnhanced(chatId: number, photos: { file_id: string }[]
const fileUrl = "https://api.telegram.org/file/bot" + TG_TOKEN + "/" + filePath;
const imgBuffer = await fetch(fileUrl).then((r) => r.arrayBuffer());
// 保存图片
const articleDir = s.dirPath;
if (!fs.existsSync(articleDir)) fs.mkdirSync(articleDir, { recursive: true });
@@ -551,7 +542,6 @@ async function handlePhotoEnhanced(chatId: number, photos: { file_id: string }[]
const imgCaption = caption || "image";
appendContent(chatId, `\n![${imgCaption}](${filename})\n`);
// 实况照片引导提示
await sendMessage(chatId, `📷 图片已保存:${filename}
💡 <b>提示:</b>如果您发送的是 iOS 实况照片(Live Photo),
@@ -561,7 +551,6 @@ async function handlePhotoEnhanced(chatId: number, photos: { file_id: string }[]
2. 或者单独发送视频部分
继续发送其他内容...</b>`, { parse_mode: "HTML" });
} catch (e) {
console.error("[bot:photo]", e instanceof Error ? e.message : String(e));
await sendMessage(chatId, "❌ 图片保存失败");
@@ -569,7 +558,7 @@ async function handlePhotoEnhanced(chatId: number, photos: { file_id: string }[]
}
// ============================================================
// 处理音乐封面图
// 新增:处理音乐封面图
// ============================================================
async function handleAudioCover(chatId: number, photos: { file_id: string }[]) {
@@ -584,9 +573,8 @@ async function handleAudioCover(chatId: number, photos: { file_id: string }[]) {
return;
}
const { filename } = s._pendingAudio;
const { filename, name, artist } = s._pendingAudio;
// 获取最大的图片
const largestPhoto = photos[photos.length - 1];
const fileRes = await tg<{ file_path?: string }>("getFile", { file_id: largestPhoto.file_id });
if (!fileRes.ok || !fileRes.result?.file_path) {
@@ -598,25 +586,13 @@ async function handleAudioCover(chatId: number, photos: { file_id: string }[]) {
const fileUrl = "https://api.telegram.org/file/bot" + TG_TOKEN + "/" + filePath;
const imgBuffer = await fetch(fileUrl).then((r) => r.arrayBuffer());
// 保存封面图
const articleDir = s.dirPath;
const ext = filePath.split(".").pop() || "jpg";
const coverFilename = Date.now() + "-cover." + ext;
fs.writeFileSync(path.join(articleDir, coverFilename), Buffer.from(imgBuffer));
// 更新音频信息
const audioInfo = s._pendingAudio;
delete s._pendingAudio;
// 生成带封面的音乐卡片
let name = "未知歌曲";
let artist = "未知艺术家";
if (audioInfo.name && audioInfo.artist) {
name = audioInfo.name;
artist = audioInfo.artist;
}
const musicCardShortcode = `\n\n{{< music-card src="${filename}" name="${name}" artist="${artist}" cover="${coverFilename}" >}}\n\n`;
appendContent(chatId, musicCardShortcode);
@@ -626,7 +602,6 @@ async function handleAudioCover(chatId: number, photos: { file_id: string }[]) {
📌 歌曲:${name}
🎤 歌手:${artist}
🖼️ 封面:${coverFilename}`, { parse_mode: "HTML" });
} catch (e) {
console.error("[bot:audio-cover]", e instanceof Error ? e.message : String(e));
await sendMessage(chatId, "❌ 封面图保存失败");
@@ -634,66 +609,10 @@ async function handleAudioCover(chatId: number, photos: { file_id: string }[]) {
}
// ============================================================
// 增强版 handleAudio:支持封面图询问
// 新增:处理音频信息回复
// ============================================================
async function handleAudioEnhanced(chatId: number, fileId: string, fileName?: string, mimeType?: string) {
try {
const fs = await import("fs");
const path = await import("path");
const { getSession } = await import("./sessions");
const s = getSession(chatId);
if (!s.dirPath) {
await sendMessage(chatId, "❌ 请先发 /new 或 /edit 开始写作");
return;
}
await sendMessage(chatId, "🎵 正在处理音频文件...");
// 获取文件
const fileRes = await tg<{ file_path?: string }>("getFile", { file_id: fileId });
if (!fileRes.ok || !fileRes.result?.file_path) {
await sendMessage(chatId, "❌ 音频文件获取失败");
return;
}
const filePath = fileRes.result.file_path;
const fileUrl = "https://api.telegram.org/file/bot" + TG_TOKEN + "/" + filePath;
const audioBuffer = await fetch(fileUrl).then(r => r.arrayBuffer());
// 保存音频文件
const articleDir = s.dirPath;
if (!fs.existsSync(articleDir)) fs.mkdirSync(articleDir, { recursive: true });
const ext = fileName?.split(".").pop() || filePath.split(".").pop() || "mp3";
const filename = Date.now() + "-music." + ext;
fs.writeFileSync(path.join(articleDir, filename), Buffer.from(audioBuffer));
// 询问歌曲信息
const session = getSession(chatId);
session._pendingAudio = { filename, fileId, name: null, artist: null };
await tg("sendMessage", {
chat_id: chatId,
text: `✅ 音频已保存:${filename}\n\n请输入歌曲信息(格式:歌名 - 歌手):`,
reply_markup: {
force_reply: true,
input_field_placeholder: "例如:晴天 - 周杰伦"
}
});
} catch (e) {
console.error("[bot:audio]", e instanceof Error ? e.message : String(e));
await sendMessage(chatId, "❌ 音频处理失败:" + (e instanceof Error ? e.message : "未知错误"));
}
}
// ============================================================
// 增强版 handleAudioInfo:支持封面图询问
// ============================================================
async function handleAudioInfoEnhanced(chatId: number, text: string): Promise<boolean> {
async function handleAudioInfo(chatId: number, text: string): Promise<boolean> {
try {
const { getSession } = await import("./sessions");
const s = getSession(chatId);
@@ -702,7 +621,6 @@ async function handleAudioInfoEnhanced(chatId: number, text: string): Promise<bo
return false;
}
// 解析歌名和歌手
let name = "未知歌曲";
let artist = "未知艺术家";
@@ -714,11 +632,9 @@ async function handleAudioInfoEnhanced(chatId: number, text: string): Promise<bo
name = text.trim();
}
// 保存歌曲信息
s._pendingAudio.name = name;
s._pendingAudio.artist = artist;
// 询问是否添加封面图
await tg("sendMessage", {
chat_id: chatId,
text: `🎵 歌曲:${name}\n🎤 歌手:${artist}\n\n是否添加封面图?`,
@@ -739,7 +655,10 @@ async function handleAudioInfoEnhanced(chatId: number, text: string): Promise<bo
}
}
// 处理封面图选择回调
// ============================================================
// 新增:处理封面图选择回调
// ============================================================
async function handleAudioCoverCallback(chatId: number, data: string) {
try {
const { getSession } = await import("./sessions");
@@ -751,7 +670,6 @@ async function handleAudioCoverCallback(chatId: number, data: string) {
}
if (data === "audio_skip_cover") {
// 跳过封面图,直接生成音乐卡片
const { filename, name, artist } = s._pendingAudio;
delete s._pendingAudio;
@@ -762,7 +680,17 @@ async function handleAudioCoverCallback(chatId: number, data: string) {
📌 歌曲:${name}
🎤 歌手:${artist}`, { parse_mode: "HTML" });
} else if (data === "audio_add_cover") {
// 等待用户发送封面图
await tg("sendMessag
await tg("sendMessage", {
chat_id: chatId,
text: "🖼️ 请发送封面图片:",
reply_markup: {
force_reply: true,
input_field_placeholder: "发送一张图片作为封面"
}
});
}
} catch (e) {
console.error("[bot:audio-cover-callback]", e instanceof Error ? e.message : String(e));
}
}