π·οΈ FBS Labels API - ΠΡΠΈΠΊΠ΅ΡΠΊΠΈ ΠΈ ΠΏΠ΅ΡΠ°ΡΡ
π·οΈ FBS Labels API - ΠΡΠΈΠΊΠ΅ΡΠΊΠΈ ΠΈ ΠΏΠ΅ΡΠ°ΡΡ
ΠΠ΅ΡΠΎΠ΄Ρ Π΄Π»Ρ ΡΠΎΠ·Π΄Π°Π½ΠΈΡ ΠΈ ΠΏΠΎΠ»ΡΡΠ΅Π½ΠΈΡ ΡΡΠΈΠΊΠ΅ΡΠΎΠΊ ΠΎΡΠΏΡΠ°Π²Π»Π΅Π½ΠΈΠΉ FBS β ΠΏΠ΅ΡΠ°ΡΡ ΡΡΠΈΠΊΠ΅ΡΠΎΠΊ Π΄Π»Ρ ΡΠΏΠ°ΠΊΠΎΠ²Π°Π½Π½ΡΡ ΡΠΎΠ²Π°ΡΠΎΠ² ΠΏΠ΅ΡΠ΅Π΄ ΠΎΡΠ³ΡΡΠ·ΠΊΠΎΠΉ.
π ΠΠ΅ΡΠΎΠ΄Ρ (4 endpoints)
ΠΠ΅ΡΠΎΠ΄ | Endpoint | ΠΠ°Π·Π½Π°ΡΠ΅Π½ΠΈΠ΅ |
---|---|---|
packageLabel |
/v2/posting/fbs/package-label |
ΠΡΡΠΌΠ°Ρ ΠΏΠ΅ΡΠ°ΡΡ ΡΡΠΈΠΊΠ΅ΡΠΎΠΊ (Π΄ΠΎ 20 Π·Π° ΡΠ°Π·) |
createLabelBatch |
/v1/posting/fbs/package-label/create |
Π‘ΠΎΠ·Π΄Π°Π½ΠΈΠ΅ Π·Π°Π΄Π°Π½ΠΈΡ Π½Π° ΡΡΠΈΠΊΠ΅ΡΠΊΠΈ (Π°ΡΠΈΠ½Ρ ΡΠΎΠ½Π½ΠΎ) |
createLabelBatchV2 |
/v2/posting/fbs/package-label/create |
Π£Π»ΡΡΡΠ΅Π½Π½Π°Ρ Π²Π΅ΡΡΠΈΡ Ρ ΠΏΠΎΠ΄Π΄Π΅ΡΠΆΠΊΠΎΠΉ ΡΠ°Π·ΠΌΠ΅ΡΠΎΠ² |
getLabelBatch |
/v1/posting/fbs/package-label/get |
ΠΠΎΠ»ΡΡΠ΅Π½ΠΈΠ΅ Π³ΠΎΡΠΎΠ²ΡΡ ΡΡΠΈΠΊΠ΅ΡΠΎΠΊ |
π ΠΡΡΡΡΡΠΉ ΡΡΠ°ΡΡ
ΠΡΡΠΌΠ°Ρ ΠΏΠ΅ΡΠ°ΡΡ ΡΡΠΈΠΊΠ΅ΡΠΎΠΊ
try {
// ΠΠ΅ΡΠ°ΡΡ ΡΡΠΈΠΊΠ΅ΡΠΎΠΊ ΡΡΠ°Π·Ρ (Π΄ΠΎ 20 ΠΎΡΠΏΡΠ°Π²Π»Π΅Π½ΠΈΠΉ)
const label = await client.fbs.packageLabel({
posting_number: ['12345-0001-1', '12345-0002-1']
});
if (label.content) {
// Π‘ΠΎΡ
ΡΠ°Π½ΠΈΡΡ PDF ΠΈΠ· base64
const pdfBuffer = Buffer.from(label.content, 'base64');
console.log(`β
PDF ΡΡΠΈΠΊΠ΅ΡΠΊΠ° Π³ΠΎΡΠΎΠ²Π°: ${pdfBuffer.length} Π±Π°ΠΉΡ`);
// Π‘ΠΎΡ
ΡΠ°Π½ΠΈΡΡ Π² ΡΠ°ΠΉΠ»
await fs.writeFile('labels.pdf', pdfBuffer);
}
} catch (error) {
if (error.message.includes("aren't ready")) {
console.log('β³ ΠΡΠΈΠΊΠ΅ΡΠΊΠΈ Π½Π΅ Π³ΠΎΡΠΎΠ²Ρ, ΠΏΠΎΠ²ΡΠΎΡΠΈΡΠ΅ ΡΠ΅ΡΠ΅Π· 45-60 ΡΠ΅ΠΊ');
}
}
ΠΠ°ΠΊΠ΅ΡΠ½ΠΎΠ΅ ΡΠΎΠ·Π΄Π°Π½ΠΈΠ΅ ΡΡΠΈΠΊΠ΅ΡΠΎΠΊ
try {
// 1. Π‘ΠΎΠ·Π΄Π°ΡΡ Π·Π°Π΄Π°Π½ΠΈΠ΅ Π½Π° ΡΡΠΈΠΊΠ΅ΡΠΊΠΈ (Π΄Π»Ρ Π±ΠΎΠ»ΡΡΠΈΡ
ΠΎΠ±ΡΠ΅ΠΌΠΎΠ²)
const batchTask = await client.fbs.createLabelBatchV2({
posting_number: postingNumbers, // ΠΌΠ°ΡΡΠΈΠ² Π΄ΠΎ 1000 ΠΎΡΠΏΡΠ°Π²Π»Π΅Π½ΠΈΠΉ
label_type: 1 // ΡΠΈΠΏ ΡΡΠΈΠΊΠ΅ΡΠΊΠΈ
});
console.log(`π ΠΠ°Π΄Π°Π½ΠΈΠ΅ ΡΠΎΠ·Π΄Π°Π½ΠΎ: ${batchTask.result.task_id}`);
// 2. ΠΠΎΠ»ΡΡΠΈΡΡ Π³ΠΎΡΠΎΠ²ΡΠ΅ ΡΡΠΈΠΊΠ΅ΡΠΊΠΈ
const labels = await client.fbs.getLabelBatch({
task_id: batchTask.result.task_id
});
if (labels.result?.status === 'completed') {
console.log(`β
ΠΡΠΈΠΊΠ΅ΡΠΊΠΈ Π³ΠΎΡΠΎΠ²Ρ: ${labels.result.file_url}`);
} else {
console.log(`β³ Π‘ΡΠ°ΡΡΡ: ${labels.result?.status}`);
}
} catch (error) {
console.error('β ΠΡΠΈΠ±ΠΊΠ° ΡΠΎΠ·Π΄Π°Π½ΠΈΡ ΡΡΠΈΠΊΠ΅ΡΠΎΠΊ:', error);
}
π― ΠΠ΅ΡΠΎΠ΄Ρ API
packageLabel()
- ΠΡΡΠΌΠ°Ρ ΠΏΠ΅ΡΠ°ΡΡ
interface FbsPackageLabelRequest {
/** ΠΠΎΠΌΠ΅ΡΠ° ΠΎΡΠΏΡΠ°Π²Π»Π΅Π½ΠΈΠΉ (ΠΌΠ°ΠΊΡΠΈΠΌΡΠΌ 20) */
posting_number: string[];
}
interface FbsPackageLabelResponse {
/** PDF ΡΠ°ΠΉΠ» ΡΡΠΈΠΊΠ΅ΡΠΎΠΊ Π² base64 */
content?: string;
}
createLabelBatchV2()
- ΠΠ°ΠΊΠ΅ΡΠ½ΠΎΠ΅ ΡΠΎΠ·Π΄Π°Π½ΠΈΠ΅
interface FbsCreateLabelBatchRequest {
/** ΠΠΎΠΌΠ΅ΡΠ° ΠΎΡΠΏΡΠ°Π²Π»Π΅Π½ΠΈΠΉ (Π΄ΠΎ 1000) */
posting_number: string[];
/** Π’ΠΈΠΏ ΡΡΠΈΠΊΠ΅ΡΠΊΠΈ */
label_type?: number;
}
interface FbsCreateLabelBatchResponse {
result: {
/** ID Π·Π°Π΄Π°Π½ΠΈΡ Π΄Π»Ρ ΠΏΠΎΠ»ΡΡΠ΅Π½ΠΈΡ ΡΡΠΈΠΊΠ΅ΡΠΎΠΊ */
task_id: number;
};
}
getLabelBatch()
- ΠΠΎΠ»ΡΡΠ΅Π½ΠΈΠ΅ Π³ΠΎΡΠΎΠ²ΡΡ
ΡΡΠΈΠΊΠ΅ΡΠΎΠΊ
interface FbsGetLabelBatchRequest {
/** ID Π·Π°Π΄Π°Π½ΠΈΡ Π½Π° ΡΠΎΠ·Π΄Π°Π½ΠΈΠ΅ ΡΡΠΈΠΊΠ΅ΡΠΎΠΊ */
task_id: number;
}
interface FbsGetLabelBatchResponse {
result?: {
/** Π‘ΡΠ°ΡΡΡ Π·Π°Π΄Π°Π½ΠΈΡ */
status: 'processing' | 'completed' | 'failed';
/** URL ΡΠ°ΠΉΠ»Π° Ρ ΡΡΠΈΠΊΠ΅ΡΠΊΠ°ΠΌΠΈ (Π΅ΡΠ»ΠΈ Π³ΠΎΡΠΎΠ²ΠΎ) */
file_url?: string;
};
}
π‘ ΠΡΠ°ΠΊΡΠΈΡΠ΅ΡΠΊΠΈΠ΅ ΠΏΡΠΈΠΌΠ΅ΡΡ
ΠΠ±ΡΠ°Π±ΠΎΡΠΊΠ° Ρ ΠΏΠΎΠ²ΡΠΎΡΠΎΠΌ
const createLabelWithRetry = async (postingNumbers: string[]) => {
let attempts = 0;
const maxAttempts = 5;
while (attempts < maxAttempts) {
try {
const label = await client.fbs.packageLabel({
posting_number: postingNumbers
});
return label;
} catch (error) {
if (error.message.includes("aren't ready")) {
attempts++;
console.log(`β³ ΠΠΎΠΏΡΡΠΊΠ° ${attempts}/${maxAttempts}`);
await new Promise(resolve => setTimeout(resolve, 60000)); // 1 ΠΌΠΈΠ½ΡΡΠ°
} else {
throw error;
}
}
}
throw new Error('ΠΡΠΈΠΊΠ΅ΡΠΊΠΈ Π½Π΅ Π³ΠΎΡΠΎΠ²Ρ ΠΏΠΎΡΠ»Π΅ ΠΌΠ°ΠΊΡΠΈΠΌΠ°Π»ΡΠ½ΠΎΠ³ΠΎ ΠΊΠΎΠ»ΠΈΡΠ΅ΡΡΠ²Π° ΠΏΠΎΠΏΡΡΠΎΠΊ');
};
ΠΠ°ΡΡΠΎΠ²Π°Ρ ΠΎΠ±ΡΠ°Π±ΠΎΡΠΊΠ°
const processLargeLabeBatch = async (postingNumbers: string[]) => {
const batchSize = 20; // ΠΠΈΠΌΠΈΡ Π΄Π»Ρ ΠΏΡΡΠΌΠΎΠΉ ΠΏΠ΅ΡΠ°ΡΠΈ
const results = [];
for (let i = 0; i < postingNumbers.length; i += batchSize) {
const batch = postingNumbers.slice(i, i + batchSize);
try {
const labels = await createLabelWithRetry(batch);
results.push(labels);
console.log(`β
Batch ${Math.floor(i / batchSize) + 1} Π³ΠΎΡΠΎΠ²`);
// ΠΠ°ΡΠ·Π° ΠΌΠ΅ΠΆΠ΄Ρ Π·Π°ΠΏΡΠΎΡΠ°ΠΌΠΈ
if (i + batchSize < postingNumbers.length) {
await new Promise(resolve => setTimeout(resolve, 2000));
}
} catch (error) {
console.error(`β ΠΡΠΈΠ±ΠΊΠ° Π² batch ${Math.floor(i / batchSize) + 1}:`, error);
}
}
return results;
};
β οΈ ΠΠ³ΡΠ°Π½ΠΈΡΠ΅Π½ΠΈΡ
- ΠΡΡΠΌΠ°Ρ ΠΏΠ΅ΡΠ°ΡΡ: ΠΌΠ°ΠΊΡΠΈΠΌΡΠΌ 20 ΠΎΡΠΏΡΠ°Π²Π»Π΅Π½ΠΈΠΉ Π·Π° Π·Π°ΠΏΡΠΎΡ
- ΠΠ°ΠΊΠ΅ΡΠ½Π°Ρ ΠΏΠ΅ΡΠ°ΡΡ: Π΄ΠΎ 1000 ΠΎΡΠΏΡΠ°Π²Π»Π΅Π½ΠΈΠΉ Π² Π·Π°Π΄Π°Π½ΠΈΠΈ
- ΠΠΎΡΠΎΠ²Π½ΠΎΡΡΡ: ΡΠ΅ΠΊΠΎΠΌΠ΅Π½Π΄ΡΠ΅ΡΡΡ Π·Π°ΠΏΡΠ°ΡΠΈΠ²Π°ΡΡ ΡΠ΅ΡΠ΅Π· 45-60 ΡΠ΅ΠΊΡΠ½Π΄ ΠΏΠΎΡΠ»Π΅ ΡΠ±ΠΎΡΠΊΠΈ
- ΠΠΎΠ²ΡΠΎΡΡ: Π΅ΡΠ»ΠΈ ΡΡΠΈΠΊΠ΅ΡΠΊΠΈ Π½Π΅ Π³ΠΎΡΠΎΠ²Ρ, ΠΏΠΎΠ²ΡΠΎΡΠΈΡΡ ΡΠ΅ΡΠ΅Π· ΠΌΠΈΠ½ΡΡΡ
π‘ Π‘Π»Π΅Π΄ΡΡΡΠΈΠΉ ΡΠ°Π·Π΄Π΅Π»: Π Π°Π±ΠΎΡΠ° Ρ ΡΠΎΠ²Π°ΡΠ°ΠΌΠΈ (fbs-products.md)