Розробка бота для автоматичної обробки відгуків на маркетплейсах

Наша компанія займається розробкою, підтримкою та обслуговуванням сайтів будь-якої складності. Від простих односторінкових сайтів до масштабних кластерних систем, побудованих на мікро сервісах. Досвід розробників підтверджено сертифікатами від вендорів.

Розробка та обслуговування будь-яких видів сайтів:

Інформаційні сайти або веб-програми
Сайти візитки, landing page, корпоративні сайти, онлайн каталоги, квіз, промо-сайти, блоги, ресурси новин, інформаційні портали, форуми, агрегатори
Сайти або веб-програми електронної комерції
Інтернет-магазини, B2B-портали, маркетплейси, онлайн-обмінники, кешбек-сайти, біржі, дропшиппінг-платформи, парсери товарів
Веб-програми для управління бізнес-процесами
CRM-системи, ERP-системи, корпоративні портали, системи управління виробництвом, парсери інформації
Сайти або веб-програми електронних послуг
Дошки оголошень, онлайн-школи, онлайн-кінотеатри, конструктори сайтів, портали надання електронних послуг, відеохостинги, тематичні портали

Це лише деякі з технічних типів сайтів, з якими ми працюємо, і кожен із них може мати свої специфічні особливості та функціональність, а також бути адаптованим під конкретні потреби та цілі клієнта.

Пропоновані послуги
Показано 1 з 1 послугУсі 2065 послуг
Розробка бота для автоматичної обробки відгуків на маркетплейсах
Середня
~3-5 робочих днів
Часті питання

Наші компетенції:

Етапи розробки

Останні роботи

  • image_website-b2b-advance_0.png
    Розробка сайту компанії B2B ADVANCE
    1262
  • image_web-applications_feedme_466_0.webp
    Розробка веб-додатків для компанії FEEDME
    1171
  • image_websites_belfingroup_462_0.webp
    Розробка веб-сайту для компанії БЕЛФІНГРУП
    874
  • image_ecommerce_furnoro_435_0.webp
    Розробка інтернет магазину для компанії FURNORO
    1094
  • image_crm_enviok_479_0.webp
    Розробка веб-додатків для компанії Enviok
    831
  • image_bitrix-bitrix-24-1c_fixper_448_0.png
    Розробка веб-сайту для компанії ФІКСПЕР
    851

Розроблення бота для автоматичної обробки відзивів на маркетплейсах

Маркетплейси — Ozon, Wildberries, Yandex.Market — вимагають оперативних відповідей на відзиви. Платформи враховують відсоток відповіданих відзивів при ранжуванні карток. Ручна обробка сотень відзивів на місяць — це втрата часу і постійні просрочки. Бот автоматизує три завдання: отримання нових відзивів, генерацію відповідей, публікацію через API.

Архітектура

Cron → API Polling → New Review Queue → Auto-Response Engine → Publish API
                                    ↓
                              Low-Score Alert → Human Queue

Логіка: відзиви з рейтингом 4–5 обробляються автоматично. Відзиви з рейтингом 1–3 йдуть у чергу для ручної відповіді зі сповіщенням у Telegram.

Інтеграція з Ozon API

class OzonReviewApiClient
{
    private string $clientId;
    private string $apiKey;
    private string $baseUrl = 'https://api-seller.ozon.ru';

    public function getUnprocessedReviews(): array
    {
        $response = Http::withHeaders([
            'Client-Id'   => $this->clientId,
            'Api-Key'     => $this->apiKey,
            'Content-Type' => 'application/json',
        ])->post("{$this->baseUrl}/v1/review/list", [
            'processed' => false,
            'with_text' => true,
            'page'      => 1,
            'page_size' => 100,
        ]);

        return $response->json('result.reviews', []);
    }

    public function replyToReview(string $reviewId, string $text): bool
    {
        $response = Http::withHeaders([
            'Client-Id'    => $this->clientId,
            'Api-Key'      => $this->apiKey,
            'Content-Type' => 'application/json',
        ])->post("{$this->baseUrl}/v1/review/comment/create", [
            'review_id' => $reviewId,
            'text'      => $text,
        ]);

        return $response->successful();
    }
}

Генератор відповідей

Відповіді генеруються з шаблонів з персоналізацією або через GPT для унікальності.

Шаблонний підхід:

class TemplateResponseGenerator
{
    private array $positiveTemplates = [
        "Дякуємо за відзив, {author}! Раді, що вам сподобалось {product_short}. До побачення!",
        "{author}, дякуємо за оцінку! Приємно чути позитивні слова про {product_short}.",
        "Дякуємо, {author}! Ваш відзив дуже важливий для нас. Приємного користування {product_short}!",
    ];

    private array $neutralTemplates = [
        "Дякуємо за відзив, {author}. Якщо у вас виникнуть питання по {product_short} — зверніться до нашої підтримки.",
    ];

    public function generate(ReviewDTO $review): string
    {
        $templates = $review->rating >= 4
            ? $this->positiveTemplates
            : $this->neutralTemplates;

        $template = $templates[array_rand($templates)];

        return str_replace(
            ['{author}', '{product_short}'],
            [$review->author, $this->shortProductName($review->productName)],
            $template,
        );
    }
}

GPT-підхід для якісних унікальних відповідей:

class GptResponseGenerator
{
    public function generate(ReviewDTO $review): string
    {
        $response = $this->openai->chat()->create([
            'model'    => 'gpt-4o-mini',
            'messages' => [
                [
                    'role'    => 'system',
                    'content' => implode("\n", [
                        'Ти — спеціаліст підтримки інтернет-магазину. Пишеш відповідь на відзив покупця.',
                        'Вимоги: 1–3 речення. Без канцелярита. Називай покупця по імені якщо воно є.',
                        'Якщо плюси — поблагодари. Нейтральний — поблагодари і запропонуй допомогу.',
                        'Без обіцянок скидок і конкретних дат.',
                    ]),
                ],
                [
                    'role'    => 'user',
                    'content' => "Товар: {$review->productName}\nРейтинг: {$review->rating}/5\nАвтор: {$review->author}\nВідзив: {$review->text}",
                ],
            ],
            'max_tokens'  => 150,
            'temperature' => 0.8,
        ]);

        return $response->choices[0]->message->content;
    }
}

Job обробки відзиву

class ProcessMarketplaceReviewJob implements ShouldQueue
{
    public int $tries = 3;

    public function handle(
        TemplateResponseGenerator $templateGen,
        GptResponseGenerator      $gptGen,
        ReviewPublisher           $publisher,
        ReviewAlertService        $alerts,
    ): void {
        $review = $this->review;

        if ($review->rating <= 3) {
            // Сповістити команду — відповідь потрібна вручну
            $alerts->urgentReviewAlert($review);
            return;
        }

        // Вибір генератора
        $text = config('reviews.use_gpt')
            ? $gptGen->generate($review)
            : $templateGen->generate($review);

        // Публікація через API маркетплейса
        $success = $publisher->publish($review->platform, $review->externalId, $text);

        if (!$success) {
            throw new \RuntimeException("Не вдалося опублікувати відповідь на {$review->platform}");
        }

        // Запис відповіді в БД
        Review::where('external_id', $review->externalId)
            ->update([
                'reply_text'       => $text,
                'reply_published_at' => now(),
                'is_processed'     => true,
            ]);
    }
}

Wildberries API

class WildberriesReviewApiClient
{
    private string $apiKey;
    private string $baseUrl = 'https://feedbacks-api.wildberries.ru';

    public function getFeedbacks(bool $onlyNew = true): array
    {
        $response = Http::withToken($this->apiKey)
            ->get("{$this->baseUrl}/api/v1/feedbacks", [
                'isAnswered' => $onlyNew ? 'false' : 'true',
                'take'       => 100,
                'skip'       => 0,
            ]);

        return $response->json('data.feedbacks', []);
    }

    public function replyToFeedback(string $id, string $text): bool
    {
        $response = Http::withToken($this->apiKey)
            ->patch("{$this->baseUrl}/api/v1/feedbacks", [
                'id'   => $id,
                'text' => $text,
            ]);

        return $response->successful();
    }
}

Контроль якості відповідей

До публікації відповідь проходить валідацію:

class ReplyValidator
{
    public function validate(string $reply): ValidationResult
    {
        $errors = [];

        if (mb_strlen($reply) < 20) {
            $errors[] = 'Занадто коротка відповідь';
        }

        if (mb_strlen($reply) > 1000) {
            $errors[] = 'Перевищено ліміт символів';
        }

        // Маркетплейси запрещают упоминание конкурентов и внешних ссылок
        if (preg_match('/https?:\/\//i', $reply)) {
            $errors[] = 'Посилання в відповідях заборонені';
        }

        $forbidden = ['wildberries', 'ozon', 'yandex', 'aliexpress'];
        foreach ($forbidden as $word) {
            if (mb_stripos($reply, $word) !== false) {
                $errors[] = "Упоминание конкурента: {$word}";
            }
        }

        return new ValidationResult(errors: $errors);
    }
}

Метрики ефективності

Метрика Цільове значення
Відсоток оброблених відзивів > 95% у протязі 24 годин
Доля автовідповідей (рейтинг 4–5) 70–80% від всіх відзивів
Середній час відповіді < 2 годин
Помилки публікації < 1%

Розписання

// Перевірка нових відзивів кожні 30 хвилин
$schedule->command('reviews:marketplace:poll')->everyThirtyMinutes();

// Щотижневий звіт зі статистикою відповідей
$schedule->job(new MarketplaceReviewsWeeklyReportJob)->weekly()->mondays()->at('09:00');

Графік реалізації

  • Ozon API клієнт + шаблонний генератор: 1 день
  • Wildberries + Yandex.Market API: +1 день
  • GPT-генератор + валідатор: 1 день
  • Job-система + черга ручних відповідей: 0.5 дня
  • Telegram-сповіщення + метрики: 0.5 дня

Разом: 3–4 робочі дні.