Przesyłanie rozmów
Formaty, role mówców, limity rozmiaru i obsługa duplikatów.
Rozmowy przesyłasz do projektu jako multipart/form-data:
curl -X POST "$BASE/v1/projects/$PROJECT_ID/calls/upload" \
-H "X-API-Key: $AFTERTALK_KEY" \
-F "file=@call.wav;type=audio/wav"Odpowiedź to 202 Accepted z identyfikatorem zadania przetwarzania — przetwarzanie odbywa się w tle. Zobacz
pobieranie wyników.
Obsługiwane formaty nagrań
| Formaty | MP3 (audio/mpeg), WAV (audio/wav, audio/x-wav), MP4/M4A (audio/mp4, audio/x-m4a), AAC (audio/aac), OGG (audio/ogg), WebM (audio/webm) |
| Maks. rozmiar | 10 MB na plik jako multipart/form-data; 50 MB przy bezpośrednim przesłaniu |
Przy nieobsługiwanym formacie lub zbyt dużym pliku API zwraca 400. Wyślij właściwy Content-Type dla części
formularza z plikiem — to on jest sprawdzany, a nie rozszerzenie pliku. curl nie zna typów nagrań i wysyła
application/octet-stream, chyba że dodasz ;type= do pliku, jak w przykładach na tej stronie.
Pliki powyżej 10 MB: bezpośrednie przesłanie
Większe pliki trafiają bezpośrednio do magazynu plików zamiast przez API, w trzech krokach. Poproś o adres URL do przesłania, podając nazwę, typ i dokładny rozmiar pliku:
SIZE=$(wc -c < call.wav | tr -d ' ')
UPLOAD=$(curl -s -X POST "$BASE/v1/projects/$PROJECT_ID/calls/upload-url" \
-H "X-API-Key: $AFTERTALK_KEY" \
-H "Content-Type: application/json" \
-d '{"filename":"call.wav","contentType":"audio/wav","sizeBytes":'"$SIZE"'}')
export UPLOAD_ID=$(echo "$UPLOAD" | jq -r '.uploadId')
export UPLOAD_URL=$(echo "$UPLOAD" | jq -r '.uploadUrl')Na tym etapie sprawdzane są format, rozmiar, dostęp do projektu i dostępny limit audio, więc plik, którego
nie dałoby się przetworzyć, zostaje odrzucony, zanim go wyślesz. Odpowiedź zawiera uploadId oraz
uploadUrl, który jest ważny przez 10 minut. Wyślij plik metodą PUT na ten adres URL, bez klucza API,
z dokładnie tym Content-Type i rozmiarem, które podano w pierwszym kroku; oba są częścią podpisu adresu URL,
więc cokolwiek innego zostanie odrzucone z kodem 403:
curl -X PUT "$UPLOAD_URL" -H "Content-Type: audio/wav" --data-binary "@call.wav"Następnie dodaj plik do kolejki. language, channelRoles (w JSON-ie odpowiednik channel_roles) i force działają
tak samo jak przy przesłaniu multipart:
curl -X POST "$BASE/v1/projects/$PROJECT_ID/calls/upload-complete" \
-H "X-API-Key: $AFTERTALK_KEY" \
-H "Content-Type: application/json" \
-d '{"uploadId":"'"$UPLOAD_ID"'","filename":"call.wav","contentType":"audio/wav","language":"pl"}'To wywołanie zwraca 202 Accepted, a identyfikatorem zadania przetwarzania jest uploadId. Wywołanie
upload-complete przed zakończeniem PUT zwraca 404, a ponowne wywołanie dla tego samego przesłania — 409.
Duplikat również zwraca 409, ale plik zostaje zachowany: wyślij to samo
żądanie z "force": true, aby mimo to go przetworzyć bez ponownego przesyłania.
Język transkrypcji
Rozmowy są transkrybowane po polsku lub po angielsku. Przekaż language jako pl lub en, aby
wskazać język:
curl -X POST "$BASE/v1/projects/$PROJECT_ID/calls/upload" \
-H "X-API-Key: $AFTERTALK_KEY" \
-F "file=@call.wav;type=audio/wav" \
-F "language=en"Pominięcie parametru oznacza użycie defaultLanguage projektu, czyli pl, chyba że ustawisz
inaczej (PUT /v1/projects/{projectId} z {"defaultLanguage": "en"} albo defaultLanguage
przy tworzeniu). Dla nagrań w języku angielskim wybierz język świadomie — niewłaściwy pogarsza
transkrypcję, a wraz z nią każdą analizę opartą na transkrypcji. Wartość language inna niż pl
lub en jest odrzucana z kodem 400; nic nie zostaje zapisane ani dodane do kolejki.
Jawnie podany language obowiązuje dla każdego przesłania osobno, więc projekt może zawierać rozmowy w obu językach —
domyślny język projektu określa język tylko dla przesłań, w których go nie podano. Nie ma automatycznego wykrywania:
nieustawiony language oznacza domyślny język projektu, a nie „rozpoznaj go z nagrania”.
Przypisywanie mówców do ról
W przypadku nagrań stereo, w których każdy kanał to jedna strona rozmowy, przekaż channel_roles
jako obiekt JSON przypisujący role do numerów kanałów (0 = lewy, 1 = prawy). Transkrypcja przypisuje wtedy każdą
wypowiedź do nazwanej roli zamiast ogólnego „Mówca 1”:
curl -X POST "$BASE/v1/projects/$PROJECT_ID/calls/upload" \
-H "X-API-Key: $AFTERTALK_KEY" \
-F "file=@call.wav;type=audio/wav" \
-F 'channel_roles={"0":"agent","1":"customer"}'Niepoprawny JSON w tym miejscu jest ignorowany, a nie odrzucany — rozmowa i tak zostaje przetworzona, tylko bez przypisania ról. Sprawdź tę wartość, jeśli w wyniku brakuje ról.
Aby używać tego samego przypisania w całym projekcie, skonfiguruj zestaw ról mówców i pomiń ten parametr.
Zduplikowane przesłania
Przesłania są deduplikowane w obrębie projektu na podstawie skrótu (hash) zawartości nagrania. Ponowne
wysłanie nagrania, które już jest w projekcie, zwraca 409 Conflict z identyfikatorem pierwotnego
zadania przetwarzania:
{
"existingJobId": "8f14e45f-ea0f-4e21-9c1a-2b3c4d5e6f70",
"existingFilename": "call.wav",
"code": "DUPLICATE_FILE"
}Dzięki temu ponawianie żądań jest bezpieczne: jeśli żądanie przekroczy limit czasu i wyślesz je ponownie,
dostaniesz 409 wskazujące na istniejące zadanie przetwarzania zamiast ponownej opłaty. Traktuj 409 jako
sukces i kontynuuj z existingJobId:
const res = await fetch(uploadUrl, { method: 'POST', headers, body: form });
if (res.status === 409) {
const { existingJobId } = await res.json();
return existingJobId; // already uploaded — carry on
}
const { jobId } = await res.json();
return jobId;Wcześniejsze przesłanie zakończone niepowodzeniem nie blokuje ponowienia — po błędzie możesz
wysłać to samo nagranie jeszcze raz. Aby celowo przesłać identyczne nagranie, dodaj force=true,
co pomija sprawdzanie duplikatów i tworzy osobną rozmowę.
Wyczerpany limit audio
Jeśli organizacja wykorzystała cały limit audio, przesłanie jest odrzucane z kodem 402 Payment Required,
zanim plik zostanie zapisany. Zobacz limity żądań i rozliczenia.