From b2e207cf4c6446064636a97a475578fb7aa4bf61 Mon Sep 17 00:00:00 2001 From: "lam.pt" Date: Tue, 26 Aug 2025 13:30:44 +0000 Subject: [PATCH] Update test.txt --- test.txt | 165 ++++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 164 insertions(+), 1 deletion(-) diff --git a/test.txt b/test.txt index 2a02d41..384d1c2 100644 --- a/test.txt +++ b/test.txt @@ -1 +1,164 @@ -TEST +import { IExpenseRequest, IExpenseResponse } from "../types"; +import { API_BASE_URL, EXPENSE_WEBHOOK_ENDPOINT } from "../utils/constants"; +import * as FileSystem from "expo-file-system"; + +export class ExpenseService { + private static readonly API_URL = `${API_BASE_URL}${EXPENSE_WEBHOOK_ENDPOINT}`; + + static async sendExpenseData( + data: IExpenseRequest + ): Promise { + try { + const response = await fetch(this.API_URL, { + method: "POST", + headers: { + "Content-Type": "application/json", + Accept: "application/json", + }, + body: JSON.stringify(data), + }); + + if (!response.ok) { + throw new Error(`HTTP error! status: ${response.status}`); + } + + const result = await response.json(); + return result; + } catch (error) { + console.error("Error sending expense data:", error); + throw new Error( + error instanceof Error ? error.message : "Có lỗi xảy ra khi gửi dữ liệu" + ); + } + } + + static async sendAudioExpense(audioUri: string): Promise { + try { + // Send audio file as multipart/form-data for n8n workflow + return await this.sendAudioToN8N(audioUri); + } catch (error) { + console.error("Error sending audio expense:", error); + throw error; + } + } + + static async sendTextExpense(text: string): Promise { + try { + const requestData: IExpenseRequest = { + textInput: text, + timestamp: new Date().toISOString(), + }; + + return await this.sendExpenseData(requestData); + } catch (error) { + console.error("Error sending text expense:", error); + throw error; + } + } + + private static async sendAudioToN8N( + audioUri: string + ): Promise { + try { + const formData = new FormData(); + + // Get file info + const fileInfo = await FileSystem.getInfoAsync(audioUri); + if (!fileInfo.exists) { + throw new Error("File audio không tồn tại"); + } + + console.log("File info:", fileInfo); + console.log("Audio URI:", audioUri); + + // Extract file name and extension + const fileName = + audioUri.split("/").pop() || `recording_${Date.now()}.m4a`; + const fileExtension = fileName.split(".").pop() || "m4a"; + const mimeType = "audio/x-m4a"; + const fileSizeBytes = fileInfo.size || 0; + const fileSizeMB = (fileSizeBytes / (1024 * 1024)).toFixed(2); + + // Try different approaches for React Native file upload + let audioFile: any; + + if (audioUri.startsWith("file://")) { + // For local files, create proper file object + audioFile = { + uri: audioUri, + type: mimeType, + name: fileName, + }; + } else { + // Fallback: read as base64 and convert + const base64Data = await FileSystem.readAsStringAsync(audioUri, { + encoding: FileSystem.EncodingType.Base64, + }); + + audioFile = { + uri: `data:${mimeType};base64,${base64Data}`, + type: mimeType, + name: fileName, + }; + } + + // Append audio file to form data (n8n sẽ nhận như binary data) + formData.append("audioFile", audioFile as any); + + // Append metadata as separate fields + formData.append("timestamp", new Date().toISOString()); + formData.append("fileName", fileName); + formData.append("fileExtension", fileExtension); + formData.append("mimeType", mimeType); + formData.append("fileSizeBytes", fileSizeBytes.toString()); + formData.append("fileSizeMB", `${fileSizeMB} MB`); + + console.log("File metadata:", { + fileName, + fileExtension, + mimeType, + fileSizeBytes, + fileSizeMB: `${fileSizeMB} MB`, + }); + + console.log("Sending FormData to:", this.API_URL); + + const response = await fetch(this.API_URL, { + method: "POST", + // Không set Content-Type header - fetch sẽ tự động set với boundary + body: formData, + }); + + console.log("Response status:", response.status); + console.log("Response headers:", response.headers); + + if (!response.ok) { + const errorText = await response.text(); + console.error("Error response:", errorText); + throw new Error( + `HTTP error! status: ${response.status}, message: ${errorText}` + ); + } + + const result = await response.json(); + return result; + } catch (error) { + console.error("Error sending audio to n8n:", error); + throw new Error( + error instanceof Error ? error.message : "Có lỗi xảy ra khi gửi audio" + ); + } + } + + private static async convertAudioToBase64(audioUri: string): Promise { + try { + const base64 = await FileSystem.readAsStringAsync(audioUri, { + encoding: FileSystem.EncodingType.Base64, + }); + return base64; + } catch (error) { + console.error("Error converting audio to base64:", error); + throw new Error("Không thể chuyển đổi file audio"); + } + } +}