Recording
Nhóm endpoint phát/tải ghi âm từng cuộc gọi, tạo tác vụ xuất hàng loạt (ZIP), theo dõi và quản lý tác vụ và tạm dừng/tiếp tục ghi âm thời gian thực để tuân thủ PCI.
Tạm dừng / tiếp tục ghi âm (PCI compliance)
POST /api/telesales/calls/{uuid}/recording/pause
POST /api/telesales/calls/{uuid}/recording/resumePath parameter
| Field | Type | Mô tả |
|---|---|---|
uuid | string | UUID cuộc gọi đang diễn ra |
Response fields
| Field | Type | Mô tả | Giá trị hợp lệ |
|---|---|---|---|
uuid | string | UUID cuộc gọi | |
recording | string | Trạng thái ghi âm sau khi gọi endpoint | paused / recording |
Response 200: { "data": { "uuid": "...", "recording": "paused" } }
Use case
Agent có thể tạm dừng ghi âm khi khách hàng đang đọc thông tin nhạy cảm (số thẻ tín dụng, CVV, ...) để đảm bảo tuân thủ PCI-DSS, sau đó tiếp tục ghi khi đoạn nhạy cảm đã kết thúc.
Tổng quan endpoint
| Endpoint | Mục đích |
|---|---|
GET /api/telesales/recordings/{uuid} | Phát trực tiếp file ghi âm (trả audio/wav, hỗ trợ Range request) |
GET /api/telesales/recordings/{uuid}/download | Tải file .wav kèm filename |
POST /api/telesales/recordings/export-bulk | Tạo tác vụ xuất ZIP (xử lý bất đồng bộ) |
GET /api/telesales/recordings/export-bulk/{jobId} | Kiểm tra trạng thái tác vụ |
GET /api/telesales/recordings/export-bulk/{jobId}/download | Tải ZIP khi job hoàn tất |
DELETE /api/telesales/recordings/export-bulk/{jobId} | Huỷ job / dọn ZIP sớm |
GET /api/telesales/recordings/{uuid} — stream
Path parameter
| Field | Type | Mô tả |
|---|---|---|
uuid | string | UUID cuộc gọi |
Response headers
| Header | Mô tả | Giá trị |
|---|---|---|
Content-Type | Loại MIME | audio/wav |
Accept-Ranges | Hỗ trợ HTTP Range Request | bytes |
Content-Length | Kích thước file (byte) | |
Cache-Control | Cache policy | private, max-age=3600 |
Response 200:
Content-Type: audio/wavAccept-Ranges: bytes(cho HTML5 audio scrubbing)Content-Length: <bytes>Cache-Control: private, max-age=3600
Response 206 Partial Content (HTTP Range request) — trình phát âm thanh dùng để tua đến vị trí mong muốn.
Response 404 — không có ghi âm:
{ "message": "Recording not found.", "error_code": "RECORDING_NOT_FOUND" }Response 410 Gone — ghi âm đã hết hạn theo retention rule do admin cấu hình:
{ "message": "Recording has exceeded the retention window.", "expired_at": "2026-03-01T00:00:00Z" }GET /api/telesales/recordings/{uuid}/download
Path parameter
| Field | Type | Mô tả |
|---|---|---|
uuid | string | UUID cuộc gọi |
Response headers
| Header | Mô tả | Giá trị |
|---|---|---|
Content-Type | Loại MIME | audio/wav |
Content-Disposition | Filename gợi ý cho trình duyệt | attachment; filename="call-{uuid}-{date}.wav" |
Response 200:
Content-Type: audio/wavContent-Disposition: attachment; filename="call-093e1024-2026-06-06.wav"
Lỗi 404/410 giống endpoint stream.
POST /api/telesales/recordings/export-bulk — tạo job ZIP
Request body fields
| Field | Type | Required | Mô tả | Giá trị hợp lệ |
|---|---|---|---|---|
campaign_id | integer | optional | Lọc theo chiến dịch | |
date_from | datetime | ✅ | Mốc bắt đầu (ISO 8601 UTC) | |
date_to | datetime | ✅ | Mốc kết thúc (ISO 8601 UTC) | Khoảng date_from..date_to ≤ 31 ngày |
agent_ids[] | array<integer> | optional | Lọc theo agent | |
disposition_codes[] | array<string> | optional | Chỉ export cuộc có disposition này | mã disposition của tài khoản |
Body:
{
"campaign_id": 36,
"date_from": "2026-06-01T00:00:00Z",
"date_to": "2026-06-05T23:59:59Z",
"agent_ids": [25, 26],
"disposition_codes": ["SALE-OK", "CALLBACK_REQ"]
}Response fields
| Field | Type | Mô tả | Giá trị hợp lệ |
|---|---|---|---|
job_id | string | ID job export | exp_<hex> |
status | string | Trạng thái khởi tạo | queued |
estimated_files | integer | Ước tính số file ghi âm sẽ đóng gói | ≥ 1 |
estimated_size_mb | integer | Ước tính dung lượng ZIP (MB) | ≥ 0 |
created_at | datetime | Lúc tạo job (ISO 8601 UTC) | |
expires_at | datetime | Lúc ZIP bị xoá tự động (default +30 ngày) | ISO 8601 UTC |
Response 201:
{
"data": {
"job_id": "exp_abc123",
"status": "queued",
"estimated_files": 215,
"estimated_size_mb": 480,
"created_at": "2026-06-06T07:00:00Z",
"expires_at": "2026-07-06T07:00:00Z"
}
}Response 422 — các trường hợp validate sai:
// Khoảng thời gian vượt 31 ngày
{
"message": "The given data was invalid.",
"errors": { "date_to": ["The date_from..date_to range may not exceed 31 days."] }
}
// Không có bản ghi nào phù hợp với bộ lọc → không tạo job
{
"message": "No recordings match the filter.",
"errors": { "filter": ["Estimated 0 files. Adjust date range or filters."] }
}Response 403 — người gọi API không có quyền supervisor / admin:
{ "message": "You are not allowed to bulk-export recordings. Supervisor or admin role is required." }GET /api/telesales/recordings/export-bulk/{jobId} — kiểm tra trạng thái
Path parameter
| Field | Type | Mô tả |
|---|---|---|
jobId | string | ID job trả về từ POST tạo job |
Response fields
| Field | Type | Mô tả | Giá trị hợp lệ |
|---|---|---|---|
job_id | string | ID job export | |
status | string | Trạng thái job | queued / running / ready / failed / expired / cancelled |
progress_pct | integer | Phần trăm hoàn thành | 0-100 |
files | integer | Số file đã đóng gói (chỉ khi ready) | ≥ 0 |
files_processed | integer | Số file đã xử lý (chỉ khi running) | ≥ 0 |
size_mb | integer | Dung lượng ZIP thực tế (MB) | |
download_url | string | URL tải ZIP (khi status=ready) | |
created_at | datetime | Lúc tạo job (ISO 8601 UTC) | |
completed_at | datetime|null | Lúc đóng gói xong | |
expires_at | datetime | Lúc ZIP bị xoá tự động | |
error_code | string | Mã lỗi khi status=failed | vd STORAGE_ERROR |
error_message | string | Mô tả lỗi khi status=failed | |
failed_at | datetime | Lúc job thất bại |
Response 200:
{
"data": {
"job_id": "exp_abc123",
"status": "ready",
"progress_pct": 100,
"files": 215,
"size_mb": 478,
"download_url": "/api/telesales/recordings/export-bulk/exp_abc123/download",
"created_at": "2026-06-06T07:00:00Z",
"completed_at": "2026-06-06T07:08:42Z",
"expires_at": "2026-07-06T07:00:00Z"
}
}Enum status: queued | running | ready | failed | expired | cancelled.
Trạng thái running trả thêm progress_pct (0..99) + files_processed.
Trạng thái failed trả thêm:
{
"data": {
"job_id": "exp_abc123",
"status": "failed",
"error_code": "STORAGE_ERROR",
"error_message": "Storage unavailable during ZIP packaging.",
"failed_at": "2026-06-06T07:05:00Z"
}
}Response 404 — job không tồn tại hoặc không thuộc tài khoản.
GET /api/telesales/recordings/export-bulk/{jobId}/download
Path parameter
| Field | Type | Mô tả |
|---|---|---|
jobId | string | ID job (status phải = ready) |
Response headers
| Header | Mô tả | Giá trị |
|---|---|---|
Content-Type | Loại MIME | application/zip |
Content-Disposition | Filename ZIP | attachment; filename="recordings-{jobId}.zip" |
Response 200:
Content-Type: application/zipContent-Disposition: attachment; filename="recordings-exp_abc123.zip"
ZIP chứa các file .wav cùng một manifest.csv (danh sách các file trong gói ZIP) (danh sách các file trong gói ZIP) (call UUID, extension agent, tên agent, disposition code, start_time, duration, số điện thoại lead).
Response 410 Gone — ZIP đã hết hạn (30 ngày):
{ "message": "Export ZIP has expired. Please create a new job." }Response 409 Conflict — job chưa sẵn sàng:
{ "message": "Job exp_abc123 is currently in state 'running' (38%). Wait until ready before downloading." }DELETE /api/telesales/recordings/export-bulk/{jobId} — huỷ / dọn
Path parameter
| Field | Type | Mô tả |
|---|---|---|
jobId | string | ID job cần huỷ hoặc dọn |
| Nếu tác vụ đang chờ hoặc đang xử lý sẽ bị hủy. Nếu đã hoàn thành, tệp ZIP sẽ được xóa để giải phóng dung lượng lưu trữ. |
