🏷️ 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)