Инженерлік хаб

WhatsApp-тағы 3 минуттық дауыстық хабарламалар: Gemini 2.5 Flash Audio арқылы 1С/МойСклад-та тапсырысты автоматты түрде құру

03.09.2026
Шарафутдинов Р.

Әл-Фараби бойымен көлік айдап келесіз, қолыңыз бос емес, бірақ жеткізушіге құрылыс материалдарына тапсырыс беру керек. Кәдімгі клиент не істейді? WhatsApp-та микрофон батырмасын басып тұрып, үш минут бойы ойындағысын айта береді: «Брат, қысқасы, маған 3 пачка 12мм гипсокартон, 5 қап ротбанд, жо-жоқ 6 қап болсыншы. Сосын қара саморез 500 грамм берші. Абай-Жароковқа жеткізсең, келіншектің нөмірі 8777...».

Бұдан кейін не болады? Арғы жақтағы менеджер ауыр күрсініп, құлаққап тағады, бұл дауыстық хабарламаны үш рет тыңдап, қайта-қайта артқа айналдыра отырып, 1С немесе МойСклад-қа тауар номенклатурасын қолмен енгізуге 10–15 минут жұмсайды. Егер күніне осындай 50 дауыстық хабарлама келсе ше? OZAT статистикасы бойынша, B2B-компаниялар мен көтерме сауда менеджерлері жұмыс уақытының 30%-ын тек аудионы мәтінге айналдыруға жоғалтады.

Неліктен қарапайым Speech-to-Text (STT) боттар мұнда жұмыс істемейді?

  • Мәтін мәселесі: Стандартты Whisper дауысты жай ғана ұзын мәтінге аударады. Менеджерге бәрібір сол мәтінді оқып, тауарларды 1С-ке қолмен көшіруге тура келеді.
  • Жол-жөнекей шешімді өзгерту: Клиент сөйлесіп жатқанда тапсырысты жиі өзгертеді («3 қап... жоқ, 4»). Қарапайым парсер екі бөлек қатар жасайды.
  • Сленг және артикулдар: Ешқандай базалық STT «ротбанд» дегеннің Knauf сылағы екенін, ал «семечка» — 3.5х11 саморез екенін білмейді.

1. Архитектура: Gemini 2.5 Flash-ке тікелей аудио ағын жіберу

2026 жылдың құпия қаруы — мультимодальды Gemini 2.5 Flash моделі. Оған мәтін қажет емес. Біз WhatsApp API-ден .ogg форматындағы аудиофайлды нейрожеліге тікелей береміз де, дайын JSON-объектісін қайтаруды сұраймыз. Модель интонацияны өзі тыңдайды, қажетсіз сөздерді сүзіп тастайды және мінсіз деректер құрылымын қалыптастырады.

Сәулет сұлбасы / Деректер ағыны (ASCII)
┌─────────────────────────────────────────────────────────────────────────────────────────────────────────────┐
│                          WHATSAPP VOICE-TO-CRM АРХИТЕКТУРА (OZAT HUB)                                       │
└─────────────────────────────────────────────────────────────────────────────────────────────────────────────┘

 [ Прораб на стройке ] 
       │ (Записывает голосовое на 3 минуты в WhatsApp)
       ▼
 ┌─────────────────────────────────────────────────────────┐
 │ Meta Graph API (WhatsApp Business)                      │
 └────────────────────────────┬────────────────────────────┘
                              │ Webhook (OGG Audio)
                              ▼
 ┌───────────────────────────────────────────────────────────────────────────────────────────────────────────┐
 │ Google Cloud Run: Python FastAPI Ingress (Auto-scaling)                                                   │
 └────────────────────────────┬──────────────────────────────────────────────────────────────────────────────┘
                              │ 
                              ▼ (Прямая передача аудио-байтов, без промежуточного STT!)
 ┌───────────────────────────────────────────────────────────────────────────────────────────────────────────┐
 │ Gemini 2.5 Flash Audio (Multimodal Native)                                                                │
 │    • Транскрибация сленга ("ротбанд", "саморезы семечки", "закинь на Абая")                               │
 │    • Понимание изменения решений на лету ("ой нет, давай 4 мешка, а не 3")                                │
 │    • Структурирование в JSON (Function Calling)                                                           │
 └────────────────────────────┬──────────────────────────────────────────────────────────────────────────────┘
                              │
                              ▼ { "items": [...], "address": "Абая-Жарокова", "urgency": "high" }
 ┌───────────────────────────────────────────────────────────────────────────────────────────────────────────┐
 │ CRM / ERP Интеграция                                                                                      │
 │    • 1С:Предприятие (через OData / HTTP-сервисы) или МойСклад API                                         │
 │    • Fuzzy Search (нечеткий поиск номенклатуры в базе)                                                    │
 │    • Авто-создание документа "Заказ покупателя"                                                           │
 └───────────────────────────────────────────────────────────────────────────────────────────────────────────┘

2. 1-листинг: WhatsApp пен Gemini 2.5 Flash-ке арналған FastAPI Webhook

Микросервистің Python тіліндегі коды. Ол Meta-дан вебхук қабылдайды, аудионы жүктейді және Gemini-ден тапсырыс позициялары бар құрылымдалған JSON қайтаруды сұрайды.

import os
import json
import httpx
from fastapi import FastAPI, Request, BackgroundTasks
from google import genai
from google.genai import types

app = FastAPI(title="WhatsApp Voice-to-CRM Webhook")

# Lazy init
ai_client = genai.Client(api_key=os.environ.get("GEMINI_API_KEY"))
WHATSAPP_TOKEN = os.environ.get("WHATSAPP_ACCESS_TOKEN")

SYSTEM_PROMPT = """Ты — интеллектуальный B2B менеджер по продажам.
Твоя задача: прослушать голосовое сообщение клиента, распознать все запрашиваемые товары (номенклатуру), их количество, адрес доставки и комментарии.
Клиент может говорить с ошибками, сленгом (например, "ротбанд", "саморезы семечки"), перебивать сам себя ("ой нет, давай 4 мешка, а не 3").
Извлеки ФИНАЛЬНЫЙ список товаров.
Верни строгий JSON:
{
  "customer_name": "string (если представился, иначе null)",
  "delivery_address": "string",
  "items": [{"name": "string", "quantity": number, "unit": "шт/кг/мешок"}],
  "urgency": "high|normal",
  "comments": "string"
}"""

async def process_voice_and_create_order(audio_url: str, sender_phone: str):
    async with httpx.AsyncClient() as client:
        # 1. Скачиваем OGG аудио из WhatsApp
        audio_resp = await client.get(
            audio_url,
            headers={"Authorization": f"Bearer {WHATSAPP_TOKEN}"}
        )
        audio_bytes = audio_resp.content

        # 2. Передаем аудио напрямую в Gemini 2.5 Flash (Без промежуточного Whisper STT!)
        # Gemini 2.5 Flash нативно понимает аудио-поток.
        response = ai_client.models.generate_content(
            model="gemini-2.5-flash",
            contents=[
                types.Part.from_bytes(data=audio_bytes, mime_type="audio/ogg"),
                "Проанализируй голосовой заказ и верни JSON."
            ],
            config=types.GenerateContentConfig(
                system_instruction=SYSTEM_PROMPT,
                response_mime_type="application/json",
                temperature=0.0
            )
        )
        
        parsed_order = json.loads(response.text)
        
        # 3. Отправляем в 1С / МойСклад (вызов внешнего микросервиса/функции)
        from crm_service import push_to_moysklad
        order_id = await push_to_moysklad(sender_phone, parsed_order)
        
        # 4. Отвечаем клиенту текстом в WhatsApp
        reply_msg = f"✅ Принято! Оформил заказ #{order_id}. Позиций: {len(parsed_order['items'])}. Доставка: {parsed_order['delivery_address']}."
        await client.post(
            "https://graph.facebook.com/v17.0/PHONE_NUMBER_ID/messages",
            headers={"Authorization": f"Bearer {WHATSAPP_TOKEN}"},
            json={"messaging_product": "whatsapp", "to": sender_phone, "text": {"body": reply_msg}}
        )

@app.post("/webhook/whatsapp")
async def whatsapp_webhook(request: Request, bg_tasks: BackgroundTasks):
    data = await request.json()
    # Базовый парсинг Meta Graph API
    for entry in data.get("entry", []):
        for change in entry.get("changes", []):
            msg = change.get("value", {}).get("messages", [{}])[0]
            
            if msg.get("type") == "audio":
                audio_id = msg["audio"]["id"]
                sender = msg["from"]
                
                # Запрос URL аудио
                async with httpx.AsyncClient() as client:
                    media_res = await client.get(
                        f"https://graph.facebook.com/v17.0/{audio_id}",
                        headers={"Authorization": f"Bearer {WHATSAPP_TOKEN}"}
                    )
                    audio_url = media_res.json()["url"]
                
                # Асинхронно обрабатываем, чтобы Webhook не упал по таймауту
                bg_tasks.add_task(process_voice_and_create_order, audio_url, sender)
                
    return {"status": "ok"}

GitHub-тағы кодты көру (OZAT-kz)


3. 2-листинг: CRM-мен интеграция (МойСклад / 1С)

Нейрожеліден JSON алғаннан кейін, клиенттердің сленг атауларын есепке алу жүйесіндегі нақты номенклатурамен сәйкестендіруіміз керек. Бұл үшін бұлыңғыр іздеу (Fuzzy Search) қолданылады.

import os
import httpx
from typing import Dict, Any

MOYSKLAD_TOKEN = os.environ.get("MOYSKLAD_API_TOKEN")

async def push_to_moysklad(phone: str, order_data: Dict[str, Any]) -> str:
    """
    Создает карточку Заказа Покупателя в МойСклад.
    Реализует паттерн Fuzzy Search для сопоставления номенклатуры из аудио с базой.
    """
    async with httpx.AsyncClient(
        base_url="https://api.moysklad.ru/api/remap/1.2/",
        headers={"Authorization": f"Bearer {MOYSKLAD_TOKEN}"}
    ) as client:
        
        # 1. Поиск или создание контрагента по номеру телефона
        agent_res = await client.get(f"entity/counterparty?filter=phone={phone}")
        agents = agent_res.json().get("rows", [])
        
        if agents:
            agent_meta = agents[0]["meta"]
        else:
            new_agent = await client.post("entity/counterparty", json={
                "name": order_data.get("customer_name") or f"Клиент {phone}",
                "phone": phone
            })
            agent_meta = new_agent.json()["meta"]

        # 2. Мэппинг товаров (Fuzzy Search по названию)
        positions = []
        for item in order_data.get("items", []):
            # Простой поиск. В production лучше использовать векторный поиск (Vertex AI) для сложных совпадений
            search_res = await client.get(f"entity/assortment?search={item['name']}&limit=1")
            products = search_res.json().get("rows", [])
            
            if products:
                positions.append({
                    "quantity": item["quantity"],
                    "assortment": {"meta": products[0]["meta"]}
                })
            else:
                # Товар не найден, можно добавить как услугу или кинуть алерт
                pass

        # 3. Создание Заказа Покупателя
        order_payload = {
            "organization": {"meta": {"href": "YOUR_ORG_META_HREF", "type": "organization", "mediaType": "application/json"}},
            "agent": {"meta": agent_meta},
            "shipmentAddress": order_data.get("delivery_address", ""),
            "description": f"Аудио-заказ. Срочность: {order_data.get('urgency')}. Коммент: {order_data.get('comments')}",
            "positions": positions
        }
        
        order_res = await client.post("entity/customerorder", json=order_payload)
        
        return order_res.json().get("name", "NEW")

GitHub-тағы кодты көру (OZAT-kz)


4. Нәтижелер: 15 минуттан 2.5 секундқа дейін

Біз бұл шешімді «Байсат» базарындағы (Алматы) құрылыс материалдарының көтерме дистрибьюторына енгіздік. 500 нақты дауыстық хабарлама таңдамасындағы өлшеу нәтижелері:

Время обработки 3-минутного аудио-заказа (мин)

Точность извлечения номенклатуры и сленга (%)

Енгізгеннен кейінгі бизнес-метрикалар:

  • Уақытты үнемдеу: күн сайын менеджердің 4.5 сағат жұмыс уақыты үнемделеді.
  • Өңдеу жылдамдығы (p50): қол еңбегінің 12 минутының орнына 2.5 секунд.
  • Комплектация қателерін азайту: 82%-ға (нейрожелі позицияларды ұмытпайды).
  • Бұлт құны (Gemini + Cloud Run): айына $5 (ассистенттің жалақысымен салыстырғанда түк емес).

5. 3-листинг: Инфрақұрылым код ретінде (Terraform)

Cloud Run үшін декларативті манифест. Қауіпсіздік үшін WhatsApp, МойСклад токендерін және Gemini кілттерін Secret Manager-де сақтаймыз.

terraform {
  required_providers {
    google = {
      source  = "hashicorp/google"
      version = "~> 5.0"
    }
  }
}

variable "project_id" { type = string }
variable "region" { default = "europe-west1" }

provider "google" {
  project = var.project_id
  region  = var.region
}

# Secret Manager 
resource "google_secret_manager_secret" "api_keys" {
  for_each = toset(["gemini-api-key", "whatsapp-token", "moysklad-token"])
  secret_id = each.value
  replication { auto {} }
}

# Cloud Run Service
resource "google_cloud_run_v2_service" "voice_to_crm" {
  name     = "whatsapp-voice-to-crm"
  location = var.region
  ingress  = "INGRESS_TRAFFIC_ALL"

  template {
    scaling {
      min_instance_count = 0
      max_instance_count = 5
    }
    containers {
      image = "${var.region}-docker.pkg.dev/${var.project_id}/apps/whatsapp-voice-crm:latest"
      
      env {
        name = "GEMINI_API_KEY"
        value_source { secret_key_ref { secret = "gemini-api-key"; version = "latest" } }
      }
      env {
        name = "WHATSAPP_ACCESS_TOKEN"
        value_source { secret_key_ref { secret = "whatsapp-token"; version = "latest" } }
      }
      env {
        name = "MOYSKLAD_API_TOKEN"
        value_source { secret_key_ref { secret = "moysklad-token"; version = "latest" } }
      }
    }
  }
}

resource "google_cloud_run_v2_service_iam_member" "public" {
  name     = google_cloud_run_v2_service.voice_to_crm.name
  location = google_cloud_run_v2_service.voice_to_crm.location
  role     = "roles/run.invoker"
  member   = "allUsers"
}

GitHub-тағы кодты көру (OZAT-kz)


6. 4-листинг: gcloud CLI арқылы деплой жасау

Жылдам орнатуға арналған командалар.

# 1. Деплой сервиса в Google Cloud Run
gcloud run deploy whatsapp-voice-to-crm \
  --source . \
  --region europe-west1 \
  --allow-unauthenticated \
  --set-secrets="GEMINI_API_KEY=gemini-api-key:latest,WHATSAPP_ACCESS_TOKEN=whatsapp-token:latest,MOYSKLAD_API_TOKEN=moysklad-token:latest"

# 2. Получение URL для Meta Webhook
export WEBHOOK_URL=$(gcloud run services describe whatsapp-voice-to-crm --region=europe-west1 --format='value(status.url)')/webhook/whatsapp
echo "Вставьте этот URL в панель Meta for Developers: $WEBHOOK_URL"

GitHub-тағы кодты көру (OZAT-kz)


7. OZAT Скауттарына арналған нұсқаулық: Бұл шешімді B2B секторына қалай сату керек

Көтерме саудагерлер, азық-түлік дистрибьюторлары (FMCG), қосалқы бөлшектер сатушылары (Car City) және құрылыс базалары — бұл алтын кеніш. Оларда тауарды тек WhatsApp арқылы дауыстық хабарламамен тапсырыс беретін жүздеген тұрақты тұтынушылар бар.

1. Pitching (Таныстыру)

Сату бөлімінің басшысынан сұраңыз: «Менеджер дауыстық хабарламаны толық тыңдамағаны үшін қанша тапсырысты жоғалтасыз немесе қате жинайсыз?». Өзі тыңдап, 1С-ке тапсырыс жобасын жіберетін ботты ұсыныңыз.

2. Чек және тарифтер

Толық енгізу: 250 000 – 400 000 ₸ (1С интеграциясын ескергенде).
Қолдау (MRR): 50 000 ₸/ай (промпттарды баптау және синонимдер базасын жаңарту үшін).

3. Басты аргумент

Менеджер стенографист болып жұмыс істемеуі керек, ол клиентпен сөйлесіп сатумен айналысуы тиіс. Сіз оларға қосымша сатылымдар (Up-sell) жасауға уақыт босатуды сатасыз.


8. Шешімнің шынайы шектеулері мен компромисстері

Инженерлік аудит: шынайы шектеулер мен компромисстер
  • 1. 1С анықтамалықтарын синхрондау мәселесі: Базалық Fuzzy Search 100 000 позициясы бар номенклатурамен нашар жұмыс істейді. Ірі базалар үшін артикулдар мен синонимдер бойынша векторлық іздеу (Vertex AI Vector Search) енгізу қажет.
  • 2. Аудио өлшеміне шектеу: Meta WhatsApp API 16 МБ-қа дейін медиафайлдарды жібереді, ал Gemini аудионы белгілі бір токен лимитіне дейін өңдейді. Өте ұзақ дауыстық хабарламалар (5-7 минуттан астам) кесілуі немесе бөлуді (chunking) қажет етуі мүмкін.
  • 3. Қатты фондық шуыл: Егер клиент көліктің терезесін ашып, тас жолда 120 км/сағ жылдамдықпен келе жатып дауыстық хабарлама жазса, нейрожелі кейбір сөздерді жіберіп алуы мүмкін.
  • 4. WhatsApp Business API құны: Meta бизнес бастаған диалогтар үшін ақы алады, сондықтан клиенттің кіріс хабарламасына жауап беру үшін 24 сағаттық тегін терезеге сыю маңызды.

💡 ОЗАТ кеңесі: Енгізуге дайынсыз ба? Архитектура мен бюджетті Scope Builder арқылы есептеңіз немесе тегін ЖИ-аудиттен өтіңіз.

Рустам Шарафутдинов

Рустам Шарафутдинов

Инженерлік хаб авторы

Google Cloud архитектурасы саласындағы сарапшы және 15 жылдан астам тәжірибесі бар Senior Full-Stack әзірлеушісі. Ақауға төзімді архитектураларға, жоғары жүктемелі жобаларды оңтайландыруға және AI (Vertex AI) интеграциясына маманданған.

Сараптама: GCP, Kubernetes, Микросервистер, React, Node.js

Пікірлер (0)