111 lines
		
	
	
		
			3.1 KiB
		
	
	
	
		
			TypeScript
		
	
	
	
	
	
			
		
		
	
	
			111 lines
		
	
	
		
			3.1 KiB
		
	
	
	
		
			TypeScript
		
	
	
	
	
	
| import { transcribe } from "@lib/openai.ts";
 | |
| import { createDocument } from "@lib/documents.ts";
 | |
| import { createLogger } from "./log/index.ts";
 | |
| import { convertOggToMp3 } from "./helpers.ts";
 | |
| 
 | |
| const log = createLogger("taskManager");
 | |
| 
 | |
| // In-memory task state
 | |
| const activeTasks: Record<
 | |
|   string,
 | |
|   {
 | |
|     noteName: string;
 | |
|     entries: Array<
 | |
|       { type: string; content: string | ArrayBufferLike; fileName?: string }
 | |
|     >;
 | |
|   }
 | |
| > = {};
 | |
| 
 | |
| export function startTask(chatId: string, noteName: string) {
 | |
|   activeTasks[chatId] = { noteName, entries: [] };
 | |
|   log.info(`Started note: ${noteName}`);
 | |
| }
 | |
| 
 | |
| export async function endTask(chatId: string): Promise<string | null> {
 | |
|   const task = activeTasks[chatId];
 | |
|   if (!task) return null;
 | |
| 
 | |
|   log.info("Ending note", task.noteName);
 | |
| 
 | |
|   let finalNote = `# ${task.noteName}\n\n`;
 | |
| 
 | |
|   const photoTasks: { content: ArrayBuffer; path: string }[] = [];
 | |
| 
 | |
|   let photoIndex = 0;
 | |
|   for (const entry of task.entries) {
 | |
|     if (entry.type === "text") {
 | |
|       finalNote += entry.content + "\n\n";
 | |
|     } else if (entry.type === "voice") {
 | |
|       try {
 | |
|         log.info("Converting OGG to MP3");
 | |
|         const mp3Data = await convertOggToMp3(entry.content as ArrayBuffer);
 | |
|         log.info("Finished converting OGG to MP3, transcribing...");
 | |
|         const transcript = await transcribe(mp3Data);
 | |
|         finalNote += `**Voice Transcript:**\n${transcript}\n\n`;
 | |
|         log.info("Finished transcribing");
 | |
|       } catch (error) {
 | |
|         log.error(error);
 | |
|         finalNote += "**[Voice message could not be transcribed]**\n\n";
 | |
|       }
 | |
|     } else if (entry.type === "photo") {
 | |
|       const photoUrl = `${
 | |
|         task.noteName.replace(/\.md$/, "")
 | |
|       }/photo-${photoIndex++}.jpg`;
 | |
| 
 | |
|       finalNote += `**Photo**:\n ${photoUrl}\n\n`;
 | |
|       photoTasks.push({
 | |
|         content: entry.content as ArrayBuffer,
 | |
|         path: photoUrl,
 | |
|       });
 | |
|     }
 | |
|   }
 | |
| 
 | |
|   try {
 | |
|     for (const entry of photoTasks) {
 | |
|       await createDocument(entry.path, entry.content, "image/jpeg");
 | |
|     }
 | |
|   } catch (err) {
 | |
|     log.error("Error creating photo document:", err);
 | |
|   }
 | |
|   try {
 | |
|     await createDocument(task.noteName, finalNote, "text/markdown");
 | |
|   } catch (error) {
 | |
|     log.error("Error creating document:", error);
 | |
|     return error instanceof Error
 | |
|       ? error.toString()
 | |
|       : "Error creating document";
 | |
|   }
 | |
| 
 | |
|   delete activeTasks[chatId];
 | |
|   log.debug({ finalNote });
 | |
|   return finalNote;
 | |
| }
 | |
| 
 | |
| export function addTextEntry(chatId: string, text: string) {
 | |
|   const task = activeTasks[chatId];
 | |
|   if (!task) return;
 | |
|   const entry = { type: "text", content: text };
 | |
|   log.debug("New Entry", entry);
 | |
|   task.entries.push(entry);
 | |
| }
 | |
| 
 | |
| export function addVoiceEntry(chatId: string, buffer: ArrayBufferLike) {
 | |
|   const task = activeTasks[chatId];
 | |
|   if (!task) return;
 | |
|   const entry = { type: "voice", content: buffer };
 | |
|   log.debug("New Entry", entry);
 | |
|   task.entries.push(entry);
 | |
| }
 | |
| 
 | |
| export function addPhotoEntry(
 | |
|   chatId: string,
 | |
|   buffer: ArrayBufferLike,
 | |
|   fileName: string,
 | |
| ) {
 | |
|   const task = activeTasks[chatId];
 | |
|   if (!task) return;
 | |
|   const entry = { type: "photo", content: buffer, fileName };
 | |
|   log.debug("New Entry", entry);
 | |
|   task.entries.push(entry);
 | |
| }
 |