Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions src/handlers/onAudio.ts
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ export async function processAudio(
const link = await ctx.telegram.getFileLink(voice.file_id);
const oggPath = tmp.tmpNameSync({ postfix: ".ogg" });
let mp3Path: string | null = null;
let progressTimer: NodeJS.Timeout | null = null;

try {
const response = await fetch(link.href);
Expand All @@ -50,6 +51,16 @@ export async function processAudio(
await fs.promises.writeFile(oggPath, Buffer.from(arrayBuffer));

mp3Path = await convertToMp3(oggPath);

progressTimer = setInterval(() => {
void sendTelegramMessage(
chatId,
"Распознавание продолжается...",
undefined,
ctx,
);
}, 60_000);

const res = (await sendAudioWhisper({ mp3Path })) as WhisperResponse;

if (res.error) {
Expand Down Expand Up @@ -110,6 +121,7 @@ export async function processAudio(
);
} finally {
try {
if (progressTimer) clearInterval(progressTimer);
if (fs.existsSync(oggPath)) fs.unlinkSync(oggPath);
if (mp3Path && fs.existsSync(mp3Path)) fs.unlinkSync(mp3Path);
} catch (cleanupError) {
Expand Down
37 changes: 20 additions & 17 deletions src/utils/text.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,37 +22,40 @@ export function splitBigMessage(text: string) {
msg += line + "\n";
}
}

// Handle any remaining text in the buffer
if (msg) {
// Remove trailing newline if present
const trimmedMsg = msg.endsWith("\n") ? msg.slice(0, -1) : msg;
if (trimmedMsg) msgs.push(trimmedMsg);
}

return msgs;
}

export function prettyText(text: string) {
const paragraphs = [];
const sentences = text.split(/[.?!][ \n]/g);
// console.log("sentences:", sentences.length);
let paragraph = '';
while (sentences.length > 0) {
paragraph += sentences.shift() + '. ';
paragraph = paragraph.replace(/\.\. $/, '. '); // remove ..
if (!text) return "";

const paragraphs: string[] = [];
const sentences = text.match(/[^.?!]+[.?!]?/g) || [];

let paragraph = "";
for (let sentence of sentences) {
sentence = sentence.trim();
if (!/[.?!]$/.test(sentence)) sentence += ".";

paragraph += sentence + " ";
paragraph = paragraph.replace(/\.\. $/, ". ");

if (paragraph.length > 200) {
paragraphs.push(paragraph.trim() + '');
// console.log("zero paragraph:", paragraph);
paragraph = '';
paragraphs.push(paragraph.trim());
paragraph = "";
}
}
if (paragraph.length > 0) {
paragraphs.push(paragraph.trim() + '');

if (paragraph.trim()) {
paragraphs.push(paragraph.trim());
}
// console.log("paragraphs", paragraphs);

const prettyText = paragraphs.join('\n\n');
return prettyText;
return paragraphs.join("\n\n");
}
2 changes: 1 addition & 1 deletion tests/handlers/onAudioProcess.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ describe("processAudio", () => {
await processAudio(ctx as Context, { file_id: "f" }, 1);
expect(mockSendTelegramMessage).toHaveBeenCalledWith(
1,
"hello",
"hello.",
undefined,
ctx,
);
Expand Down
21 changes: 11 additions & 10 deletions tests/utils/text.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,41 +13,42 @@ describe("splitBigMessage", () => {

it("truncates single oversized line", () => {
const line = "x".repeat(4100);
const [msg] = splitBigMessage(line);
expect(msg.length).toBe(4096);
expect(msg.endsWith("...")).toBe(true);
const msgs = splitBigMessage(line);
expect(msgs.length).toBe(2);
expect(msgs[0].length).toBe(4096);
expect(msgs[1].length).toBe(4);
});

it("keeps blank lines", () => {
const res = splitBigMessage("a\n\nb");
expect(res).toEqual(["a\n\nb\n"]);
expect(res).toEqual(["a\n\nb"]);
});
});

describe("prettyText", () => {
it("formats a simple sentence correctly", () => {
const input = "Hello world.";
const result = prettyText(input);
expect(result).toBe("Hello world. ");
expect(result).toBe("Hello world.");
});

it("combines short sentences into one paragraph", () => {
const input = "First sentence. Second sentence. Third sentence.";
const result = prettyText(input);
expect(result).toBe("First sentence. Second sentence. Third sentence. ");
expect(result).toBe("First sentence. Second sentence. Third sentence.");
});

it("splits long text into multiple paragraphs", () => {
const longText =
const longText =
"This is a long sentence that should be in the first paragraph. " +
"This is another long sentence that should be in the first paragraph. " +
"This is a very long sentence that should trigger a new paragraph because " +
"it makes the total length exceed the 200 character limit. " +
"This should be in the second paragraph.";

const result = prettyText(longText);
const paragraphs = result.split("\n\n");

expect(paragraphs.length).toBe(2);
expect(paragraphs[0].length).toBeGreaterThan(200);
expect(paragraphs[0]).toContain("first paragraph.");
Expand All @@ -67,6 +68,6 @@ describe("prettyText", () => {
});

it("handles single word", () => {
expect(prettyText("Hello")).toBe("Hello. ");
expect(prettyText("Hello")).toBe("Hello.");
});
});