File size: 2,470 Bytes
cd2a4c2
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
import { z } from "zod";
import { COOKIE_NAME } from "../shared/const.js";
import { getSessionCookieOptions } from "./_core/cookies";
import { systemRouter } from "./_core/systemRouter";
import { publicProcedure, router } from "./_core/trpc";
import { transcribeAudio } from "./_core/voiceTranscription";
import { storagePut } from "./storage";

export const appRouter = router({
  system: systemRouter,
  auth: router({
    me: publicProcedure.query((opts) => opts.ctx.user),
    logout: publicProcedure.mutation(({ ctx }) => {
      const cookieOptions = getSessionCookieOptions(ctx.req);
      ctx.res.clearCookie(COOKIE_NAME, { ...cookieOptions, maxAge: -1 });
      return { success: true } as const;
    }),
  }),

  voice: router({
    /**
     * يستقبل ملف صوتي مُرمَّز بـ Base64، يرفعه إلى S3، ثم يُرسله لـ Whisper للتعرف على الكلام العربي
     */
    transcribe: publicProcedure
      .input(
        z.object({
          audioBase64: z.string(), // ملف الصوت مُرمَّز بـ base64
          mimeType: z.string().default("audio/m4a"), // نوع الملف
          language: z.string().default("ar"), // اللغة (ar للعربية)
        })
      )
      .mutation(async ({ input }) => {
        // 1. تحويل base64 إلى Buffer
        const audioBuffer = Buffer.from(input.audioBase64, "base64");

        // 2. رفع الملف إلى S3 بمفتاح عشوائي
        const suffix = Date.now().toString(36);
        const ext = input.mimeType.split("/")[1]?.split(";")[0] ?? "m4a";
        const fileKey = `voice-recordings/rec-${suffix}.${ext}`;

        const { url: audioUrl } = await storagePut(
          fileKey,
          audioBuffer,
          input.mimeType
        );

        // 3. إرسال الرابط لـ Whisper مع تحديد اللغة العربية
        const result = await transcribeAudio({
          audioUrl,
          language: input.language,
          prompt: "هذا تسجيل صوتي باللغة العربية",
        });

        // التحقق من نوع النتيجة (نجاح أو خطأ)
        if ("error" in result) {
          throw new Error(result.details ?? result.error);
        }

        return {
          text: result.text ?? "",
          language: result.language ?? input.language,
          segments: result.segments ?? [],
        };
      }),
  }),
});

export type AppRouter = typeof appRouter;