ChatbotAssistant

Custom Tools - Kompletna Dokumentacja

Custom Tools to zaawansowana funkcjonalność pozwalająca chatbotom wywoływać zewnętrzne API poprzez webhooks. Dzięki temu Twój chatbot może wykonywać akcje w zewnętrznych systemach - od dodawania leadów do CRM, przez wysyłanie powiadomień, po aktualizację danych w bazach danych. Ta dokumentacja zawiera wszystko, czego potrzebujesz do stworzenia i wdrożenia własnych narzędzi.

Wymagania wstępne: Aby korzystać z Custom Tools, potrzebujesz aktywnego chatbota oraz systemu zdolnego do odbierania webhooks (endpoint HTTPS). System musi być dostępny z internetu.
1

Czym są Custom Tools?

Custom Tools to funkcje, które chatbot może wywołać podczas konwersacji z użytkownikiem. Każde narzędzie to zdefiniowany przez Ciebie webhook, który zostanie wywołany, gdy chatbot uzna, że jest to potrzebne.

Kluczowe cechy

  • Integracja z OpenAI Function Calling - Narzędzia są automatycznie eksponowane do modelu AI jako funkcje
  • Webhook-based - Każde wywołanie narzędzia to żądanie HTTP POST do Twojego endpointu
  • Bezpieczne - HMAC-SHA256 signing, rate limiting, retry logic, szyfrowane sekrety
  • Elastyczne - Pełna kontrola nad parametrami, request/response mapping, custom headers
  • Monitorowane - Pełna historia wykonań, analytics, metryki wydajności

Podstawowy przepływ

  1. Użytkownik pisze wiadomość do chatbota (np. "Dodaj mnie do newslettera")
  2. Model AI analizuje wiadomość i decyduje, że potrzebne jest wywołanie narzędzia
  3. System wysyła webhook do Twojego endpointu z parametrami wyodrębnionymi przez AI
  4. Twój system przetwarza żądanie (np. dodaje email do bazy danych)
  5. Zwracasz odpowiedź z wynikiem operacji
  6. Chatbot przekazuje rezultat użytkownikowi w naturalny sposób
Przykład: Wyobraź sobie użytkownika, który pisze: "Chcę umówić się na wizytę w środę o 15:00". Chatbot automatycznie wywoła Twoje narzędzie create_appointment z parametrami date: "2024-01-10" i time: "15:00", a następnie poinformuje użytkownika o wyniku.
2

Przykładowe zastosowania

Custom Tools otwierają nieograniczone możliwości integracji. Oto najpopularniejsze zastosowania:

🎯 Marketing & Sprzedaż

  • Zbieranie leadów - automatyczne zapisywanie kontaktów do CRM (Salesforce, HubSpot, Pipedrive)
  • Zarządzanie newsletterem - zapisywanie/wypisywanie z list mailingowych
  • Generowanie ofert - tworzenie spersonalizowanych wycen na podstawie rozmowy
  • Śledzenie konwersji - wysyłanie eventów do Google Analytics, Facebook Pixel

📅 Rezerwacje & Kalendarze

  • Umówienie wizyt - integracja z Calendly, Google Calendar, systemami rezerwacji
  • Sprawdzanie dostępności - weryfikacja wolnych terminów w czasie rzeczywistym
  • Zarządzanie rezerwacjami - odwoływanie, przesuwanie, potwierdzanie spotkań

🛒 E-commerce

  • Sprawdzanie stanów magazynowych - weryfikacja dostępności produktów
  • Tworzenie zamówień - inicjowanie procesu zakupowego
  • Status dostawy - śledzenie przesyłek
  • Rekomendacje produktów - personalizowane sugestie na podstawie preferencji

💬 Komunikacja

  • Wysyłanie powiadomień - integracja ze Slack, Microsoft Teams, Discord
  • SMS/Email alerts - wysyłanie powiadomień przez Twilio, SendGrid
  • Eskalacja do agenta - przekazywanie rozmowy do człowieka

📊 Analityka & Dane

  • Pobieranie danych - wyszukiwanie informacji w bazach danych
  • Generowanie raportów - tworzenie zestawień na żądanie
  • Aktualizacja rekordów - modyfikacja danych w systemach zewnętrznych

🎫 Wsparcie klienta

  • Tworzenie ticketów - integracja z Zendesk, Freshdesk, JIRA
  • Sprawdzanie statusu zgłoszeń - weryfikacja postępu w rozwiązywaniu problemów
  • Baza wiedzy - wyszukiwanie w dokumentacji, FAQ
Bez limitów: Możesz stworzyć dowolne narzędzie, które komunikuje się przez HTTP. Jedyne ograniczenie to Twoja wyobraźnia i możliwości Twojego backendu!
3

Jak to działa? - Architektura systemu

Zrozumienie architektury pomoże Ci lepiej wykorzystać Custom Tools i debugować ewentualne problemy.

Cykl życia Custom Tool

1. Definicja narzędzia

Tworzysz narzędzie w panelu ChatbotAssistant, definiując:

  • Nazwę funkcji (np. create_lead)
  • Opis - jasne wyjaśnienie, kiedy AI powinno użyć tego narzędzia
  • Parametry - schema OpenAI definiująca argumenty (JSON Schema)
  • URL webhooka - endpoint w Twoim systemie

2. Rejestracja w OpenAI

Narzędzie jest automatycznie rejestrowane w modelu AI jako funkcja. Gdy chatbot rozmawia z użytkownikiem, model widzi dostępne narzędzia i może zdecydować o ich wywołaniu na podstawie kontekstu rozmowy.

3. Wykrywanie intencji przez AI

Model analizuje wiadomość użytkownika i kontekst rozmowy. Jeśli uzna, że narzędzie jest potrzebne (np. użytkownik pyta o produkt, a masz narzędzie search_products), AI:

  • Wybiera odpowiednie narzędzie
  • Ekstrahuje potrzebne parametry z wiadomości użytkownika
  • Generuje wywołanie funkcji z argumentami

4. Wykonanie webhooka

Nasz system:

  1. Sprawdza rate limit - czy nie przekroczono limitu wywołań
  2. Tworzy log wykonania - zapisuje wszystkie szczegóły do bazy danych
  3. Buduje payload - używając opcjonalnego template lub domyślnej struktury
  4. Generuje HMAC signature - podpisuje żądanie (jeśli webhook secret jest skonfigurowany)
  5. Wysyła HTTP POST do Twojego endpointu z timeout i retry logic
  6. Przetwarza odpowiedź - mapuje według response_mapping (jeśli skonfigurowano)

5. Przetwarzanie przez Twój system

Twój endpoint:

  1. Weryfikuje HMAC signature (jeśli używasz webhook secret)
  2. Przetwarza żądanie - wykonuje logikę biznesową
  3. Zwraca odpowiedź w formacie JSON

6. Kontynuacja rozmowy

Chatbot otrzymuje wynik narzędzia i kontynuuje rozmowę, przekazując informację użytkownikowi w naturalny sposób (np. "Świetnie! Dodałem Cię do naszego newslettera. Będziesz otrzymywać wiadomości na adres [email protected]").

Statusy narzędzia

Status Opis Możliwe akcje
DRAFT Narzędzie utworzone, ale nie zweryfikowane Edycja, weryfikacja, usunięcie
VERIFYING Trwa weryfikacja URL webhooka Oczekiwanie na rezultat
VERIFIED URL zweryfikowany, gotowe do aktywacji Aktywacja, edycja, test
ACTIVE Narzędzie aktywne i dostępne dla chatbota Deaktywacja, test, analiza
INACTIVE Tymczasowo wyłączone przez użytkownika Aktywacja, edycja
FAILED Weryfikacja nie powiodła się Sprawdź błąd, edytuj URL, ponów weryfikację
Monitorowanie: Każde wywołanie narzędzia jest logowane z pełnymi szczegółami: parametry, request/response payload, czas wykonania, błędy. Możesz przeglądać historię i analytics w panelu zarządzania.
4

Tworzenie Custom Tool - Krok po kroku

Stworzenie pierwszego Custom Tool jest proste. Postępuj zgodnie z poniższymi krokami:

Krok 1: Przejdź do zarządzania narzędziami

  1. Zaloguj się do panelu ChatbotAssistant
  2. Wybierz chatbota, dla którego chcesz dodać narzędzie
  3. W opcjach chatbota kliknij "Zarządzaj Custom Tools"
  4. Kliknij przycisk "Utwórz nowe narzędzie"

Krok 2: Wypełnij podstawowe informacje

Pole Wymagane Opis Przykład
Nazwa funkcji Tak Nazwa używana przez AI do wywołania narzędzia. Tylko litery, cyfry i podkreślnik. 3-100 znaków. create_newsletter_subscription
Opis Tak Jasny opis, kiedy AI powinno użyć tego narzędzia. To kluczowe - model AI decyduje na podstawie opisu! "Zapisuje użytkownika do newslettera. Użyj gdy użytkownik chce się zapisać, otrzymywać aktualności lub newsletter."
URL webhooka Tak Endpoint HTTPS w Twoim systemie, który obsłuży wywołanie. Musi być dostępny z internetu. https://api.twojafirma.pl/webhooks/newsletter
Webhook Secret Nie Tajny klucz do podpisywania żądań (HMAC-SHA256). Silnie zalecane dla bezpieczeństwa! whsec_... (wygeneruj bezpieczny klucz)
Opis jest kluczowy! Model AI decyduje, czy użyć narzędzia na podstawie opisu. Podaj jasne, konkretne wyjaśnienie KIEDY użyć narzędzia. Unikaj ogólników. Dobry opis: "Tworzy rezerwację stolika w restauracji. Użyj gdy użytkownik chce zarezerwować stolik lub umówić się na wizytę." Zły opis: "Zarządza rezerwacjami."

Krok 3: Zdefiniuj parametry

Parametry określają, jakie informacje AI powinno wyodrębnić z rozmowy i przekazać do Twojego webhooka. Używamy formatu OpenAI Function Calling (JSON Schema).

Szczegółowy opis w następnej sekcji → Definicja parametrów

Krok 4: Konfiguracja zaawansowana (opcjonalnie)

  • Timeout - maksymalny czas oczekiwania na odpowiedź (konfigurowalne)
  • Retry policy - liczba ponownych prób w przypadku błędu (konfigurowalne)
  • Rate limiting - ograniczenie liczby wywołań na jednostkę czasu
  • Custom headers - dodatkowe nagłówki HTTP (format JSON)
  • Request template - Jinja2 template do budowy payloadu
  • Response mapping - mapowanie odpowiedzi webhooka
  • Fallback response - odpowiedź zwracana w przypadku błędu

Krok 5: Zapisz i zweryfikuj

  1. Kliknij "Zapisz narzędzie"
  2. System utworzy narzędzie w statusie DRAFT
  3. Kliknij "Zweryfikuj URL" - system wyśle testowe żądanie do Twojego endpointu
  4. Jeśli weryfikacja powiedzie się, status zmieni się na VERIFIED
  5. Kliknij "Aktywuj" aby narzędzie stało się dostępne dla chatbota
Testowanie: Przed aktywacją użyj funkcji "Test" aby sprawdzić, czy webhook działa poprawnie. Możesz podać przykładowe parametry i zobaczyć request/response.
5

Definicja parametrów (OpenAI Schema)

Parametry definiują, jakie dane AI powinno wyodrębnić z rozmowy i przekazać do Twojego webhooka. Używamy standardu JSON Schema zgodnego z OpenAI Function Calling API.

Podstawowa struktura

{
  "type": "object",
  "properties": {
    "nazwa_parametru": {
      "type": "string",
      "description": "Opis parametru dla AI"
    }
  },
  "required": ["nazwa_parametru"]
}

Typy parametrów

Typ Opis Przykład wartości
string Tekst dowolnej długości "Jan Kowalski"
number Liczba (integer lub float) 42, 3.14
integer Liczba całkowita 100
boolean Wartość logiczna true, false
array Lista wartości ["tag1", "tag2"]
object Zagnieżdżony obiekt {"street": "...", "city": "..."}

Przykład 1: Newsletter subscription

{
  "type": "object",
  "properties": {
    "email": {
      "type": "string",
      "description": "Adres email użytkownika do zapisania do newslettera"
    },
    "full_name": {
      "type": "string",
      "description": "Imię i nazwisko użytkownika (opcjonalne)"
    },
    "interests": {
      "type": "array",
      "items": {
        "type": "string"
      },
      "description": "Lista kategorii zainteresowań użytkownika (np. technologia, marketing)"
    }
  },
  "required": ["email"]
}

Przykład 2: Rezerwacja stolika

{
  "type": "object",
  "properties": {
    "date": {
      "type": "string",
      "description": "Data rezerwacji w formacie YYYY-MM-DD"
    },
    "time": {
      "type": "string",
      "description": "Godzina rezerwacji w formacie HH:MM"
    },
    "guests_count": {
      "type": "integer",
      "description": "Liczba osób (minimum 1)"
    },
    "phone": {
      "type": "string",
      "description": "Numer telefonu kontaktowego"
    },
    "special_requests": {
      "type": "string",
      "description": "Specjalne życzenia lub uwagi (opcjonalne)"
    }
  },
  "required": ["date", "time", "guests_count", "phone"]
}

Przykład 3: Tworzenie lead w CRM

{
  "type": "object",
  "properties": {
    "email": {
      "type": "string",
      "description": "Adres email potencjalnego klienta"
    },
    "company_name": {
      "type": "string",
      "description": "Nazwa firmy"
    },
    "industry": {
      "type": "string",
      "enum": ["IT", "Finance", "Healthcare", "Retail", "Other"],
      "description": "Branża firmy"
    },
    "budget_range": {
      "type": "string",
      "enum": ["< 10k", "10k-50k", "50k-100k", "> 100k"],
      "description": "Szacowany budżet projektu"
    },
    "contact_preference": {
      "type": "string",
      "enum": ["email", "phone", "meeting"],
      "description": "Preferowana forma kontaktu"
    },
    "notes": {
      "type": "string",
      "description": "Dodatkowe notatki z rozmowy"
    }
  },
  "required": ["email", "company_name"]
}

Zaawansowane właściwości

Właściwość Opis Przykład
enum Ograniczenie do konkretnych wartości "enum": ["small", "medium", "large"]
minimum/maximum Ograniczenie zakresu liczb "minimum": 1, "maximum": 100
pattern Regex pattern dla string "pattern": "^[0-9]{9}$"
minLength/maxLength Długość stringa "minLength": 3, "maxLength": 50
items Typ elementów w array "items": {"type": "string"}
Ważne wskazówki:
  • description jest kluczowy - AI używa go do zrozumienia, co należy wyodrębnić
  • Bądź konkretny - podaj format daty, jednostki, oczekiwane wartości
  • Używaj enum gdy możliwe - ogranicza to błędy i poprawia wyniki
  • Oznacz required - AI będzie próbowało uzyskać te dane przed wywołaniem
Sprawdź: Możesz walidować swoją schema online używając narzędzi JSON Schema validator. Upewnij się, że schema jest poprawna przed zapisaniem!
6

Weryfikacja URL webhooka

Przed aktywacją narzędzia, system musi zweryfikować, że Twój endpoint jest dostępny i poprawnie skonfigurowany. Weryfikacja zapewnia, że webhook będzie działał gdy chatbot będzie go potrzebował.

Proces weryfikacji

  1. Klikasz przycisk "Weryfikuj URL" w panelu zarządzania
  2. System generuje unikalny verification_token
  3. Wysyła żądanie POST do Twojego endpointu:
POST https://twoj-endpoint.pl/webhook
Content-Type: application/json

{
  "verification_token": "abc123def456...",
  "tool_name": "nazwa_twojego_narzedzia",
  "action": "verify"
}

4. Twój endpoint powinien odpowiedzieć z kodem 200 OK i zwrócić token:

HTTP/1.1 200 OK
Content-Type: application/json

{
  "success": true,
  "verification_token": "abc123def456..."
}

5. System sprawdza, czy zwrócony token zgadza się z wysłanym

6. Jeśli tak - status zmienia się na VERIFIED

Przykład implementacji (Python/Flask)

@app.route('/webhook', methods=['POST'])
def handle_webhook():
    data = request.json

    # Weryfikacja URL
    if data.get('action') == 'verify':
        return jsonify({
            'success': True,
            'verification_token': data.get('verification_token')
        }), 200

    # Normalna obsługa narzędzia
    # ... twoja logika ...

    return jsonify({'success': True, 'result': 'OK'}), 200

Przykład implementacji (Node.js/Express)

app.post('/webhook', (req, res) => {
    const data = req.body;

    // Weryfikacja URL
    if (data.action === 'verify') {
        return res.json({
            success: true,
            verification_token: data.verification_token
        });
    }

    // Normalna obsługa narzędzia
    // ... twoja logika ...

    res.json({ success: true, result: 'OK' });
});

Częste problemy weryfikacji

Problem Przyczyna Rozwiązanie
Timeout Endpoint nie odpowiada w ciągu 10 sekund Sprawdź czy URL jest poprawny i dostępny. Użyj curl do testu.
SSL Error Nieprawidłowy certyfikat HTTPS Upewnij się, że certyfikat SSL jest ważny i zaufany
404 Not Found Endpoint nie istnieje Sprawdź ścieżkę URL - upewnij się, że route jest poprawnie zdefiniowany
Token mismatch Zwrócony token nie zgadza się Upewnij się, że zwracasz DOKŁADNIE ten sam token który otrzymałeś
Wymagania bezpieczeństwa:
  • Endpoint MUSI używać HTTPS (nie HTTP)
  • Nie może być adresem lokalnym (localhost, 192.168.x.x, 10.x.x.x)
  • Certyfikat SSL musi być ważny i zaufany
  • Port musi być standardowy (443) lub jawnie określony w URL
7

Format żądania webhook

Gdy chatbot wywołuje Twoje narzędzie, system wysyła żądanie HTTP POST do Twojego endpointu webhook. Poznaj format żądania aby poprawnie obsłużyć wywołania.

Domyślna struktura payloadu

Jeśli nie skonfigurowałeś custom request template, wysyłamy standardową strukturę:

POST https://twoj-endpoint.pl/webhook
Content-Type: application/json
X-Signature-Timestamp: 1704034800
X-Signature-Nonce: abc123def456...
X-Signature-Hash: hmac_sha256_signature

{
  "tool_name": "create_newsletter_subscription",
  "arguments": {
    "email": "[email protected]",
    "full_name": "Jan Kowalski",
    "interests": ["technology", "AI"]
  },
  "timestamp": "2024-01-10T15:30:00+01:00"
}

Pola payloadu

Pole Typ Opis
tool_name string Nazwa wywołanego narzędzia
arguments object Parametry wyodrębnione przez AI zgodnie z Twoją schema
timestamp string (ISO 8601) Znacznik czasu wywołania

Custom headers

Możesz skonfigurować własne nagłówki HTTP w ustawieniach narzędzia (format JSON):

{
  "X-API-Key": "twoj-klucz-api",
  "X-Custom-Header": "wartość",
  "Authorization": "Bearer token123"
}

Request Body Template (zaawansowane)

Jeśli potrzebujesz custom formatu payloadu, możesz użyć Jinja2 template. Template ma dostęp do zmiennej arguments zawierającej parametry:

Przykład template:

{
  "event": "subscription",
  "data": {
    "subscriber_email": "{{ arguments.email }}",
    "name": "{{ arguments.full_name }}",
    "tags": {{ arguments.interests | tojson }},
    "source": "chatbot",
    "subscribed_at": "{{ now().isoformat() }}"
  }
}

Wynikowy payload:

{
  "event": "subscription",
  "data": {
    "subscriber_email": "[email protected]",
    "name": "Jan Kowalski",
    "tags": ["technology", "AI"],
    "source": "chatbot",
    "subscribed_at": "2024-01-10T15:30:00+01:00"
  }
}
Bezpieczeństwo templates:
  • Długość template jest ograniczona dla bezpieczeństwa
  • Renderowanie ma timeout chroniący przed zawieszeniem
  • Rozmiar wyniku jest limitowany
  • Template jest wykonywany w bezpiecznym środowisku (brak dostępu do systemu plików i zasobów serwera)
8

Zabezpieczenie webhooków (HMAC-SHA256)

HMAC (Hash-based Message Authentication Code) zapewnia, że webhook pochodzi od nas i nie został zmodyfikowany podczas transmisji. Jeśli skonfigurowałeś webhook secret, każde żądanie jest podpisywane.

Nagłówki podpisu

Nagłówek Opis Przykład
X-Signature-Timestamp Unix timestamp wywołania (sekundy) 1704034800
X-Signature-Nonce Losowy identyfikator zapobiegający replay attacks (32 hex chars) a1b2c3d4e5f6...
X-Signature-Hash HMAC-SHA256 podpis 7f8b9c...

Algorytm weryfikacji

  1. Odczytaj timestamp, nonce i hash z nagłówków
  2. Sprawdź, czy timestamp nie jest starszy niż 5 minut (ochrona przed replay attack)
  3. Odczytaj surowy body żądania (JSON string)
  4. Złóż message: timestamp.nonce.body
  5. Oblicz HMAC-SHA256 używając Twojego webhook secret
  6. Porównaj obliczony hash z otrzymanym

Przykład weryfikacji (Python)

import hmac
import hashlib
import time
from flask import request, abort

WEBHOOK_SECRET = "twoj-webhook-secret"
MAX_TIMESTAMP_AGE = 300  # Zalecane: kilka minut

@app.route('/webhook', methods=['POST'])
def handle_webhook():
    # 1. Pobierz nagłówki
    timestamp = request.headers.get('X-Signature-Timestamp')
    nonce = request.headers.get('X-Signature-Nonce')
    received_hash = request.headers.get('X-Signature-Hash')

    if not all([timestamp, nonce, received_hash]):
        abort(401, 'Missing signature headers')

    # 2. Sprawdź aktualność timestamp
    if abs(time.time() - int(timestamp)) > MAX_TIMESTAMP_AGE:
        abort(401, 'Request timestamp too old')

    # 3. Pobierz surowe body
    body = request.get_data(as_text=True)

    # 4. Złóż message
    message = f"{timestamp}.{nonce}.{body}"

    # 5. Oblicz HMAC
    expected_hash = hmac.new(
        WEBHOOK_SECRET.encode('utf-8'),
        message.encode('utf-8'),
        hashlib.sha256
    ).hexdigest()

    # 6. Porównaj
    if not hmac.compare_digest(expected_hash, received_hash):
        abort(401, 'Invalid signature')

    # Podpis poprawny - przetwarzaj żądanie
    data = request.json
    # ... twoja logika ...

    return {'success': True, 'result': 'OK'}

Przykład weryfikacji (Node.js)

const crypto = require('crypto');

const WEBHOOK_SECRET = 'twoj-webhook-secret';
const MAX_TIMESTAMP_AGE = 300; // 5 minut

app.post('/webhook', express.raw({type: 'application/json'}), (req, res) => {
    // 1. Pobierz nagłówki
    const timestamp = req.headers['x-signature-timestamp'];
    const nonce = req.headers['x-signature-nonce'];
    const receivedHash = req.headers['x-signature-hash'];

    if (!timestamp || !nonce || !receivedHash) {
        return res.status(401).json({error: 'Missing signature headers'});
    }

    // 2. Sprawdź aktualność
    const now = Math.floor(Date.now() / 1000);
    if (Math.abs(now - parseInt(timestamp)) > MAX_TIMESTAMP_AGE) {
        return res.status(401).json({error: 'Request too old'});
    }

    // 3. Pobierz surowe body (jako Buffer/string)
    const body = req.body.toString('utf8');

    // 4. Złóż message
    const message = `${timestamp}.${nonce}.${body}`;

    // 5. Oblicz HMAC
    const expectedHash = crypto
        .createHmac('sha256', WEBHOOK_SECRET)
        .update(message)
        .digest('hex');

    // 6. Porównaj (timing-safe)
    if (!crypto.timingSafeEqual(
        Buffer.from(expectedHash),
        Buffer.from(receivedHash)
    )) {
        return res.status(401).json({error: 'Invalid signature'});
    }

    // Podpis poprawny - przetwarzaj
    const data = JSON.parse(body);
    // ... twoja logika ...

    res.json({success: true, result: 'OK'});
});

Przykład weryfikacji (PHP)

<?php
$webhookSecret = 'twoj-webhook-secret';
$maxTimestampAge = 300; // 5 minut

// 1. Pobierz nagłówki
$timestamp = $_SERVER['HTTP_X_SIGNATURE_TIMESTAMP'] ?? '';
$nonce = $_SERVER['HTTP_X_SIGNATURE_NONCE'] ?? '';
$receivedHash = $_SERVER['HTTP_X_SIGNATURE_HASH'] ?? '';

if (!$timestamp || !$nonce || !$receivedHash) {
    http_response_code(401);
    die(json_encode(['error' => 'Missing signature headers']));
}

// 2. Sprawdź aktualność
if (abs(time() - intval($timestamp)) > $maxTimestampAge) {
    http_response_code(401);
    die(json_encode(['error' => 'Request too old']));
}

// 3. Pobierz surowe body
$body = file_get_contents('php://input');

// 4. Złóż message
$message = "{$timestamp}.{$nonce}.{$body}";

// 5. Oblicz HMAC
$expectedHash = hash_hmac('sha256', $message, $webhookSecret);

// 6. Porównaj (timing-safe)
if (!hash_equals($expectedHash, $receivedHash)) {
    http_response_code(401);
    die(json_encode(['error' => 'Invalid signature']));
}

// Podpis poprawny - przetwarzaj
$data = json_decode($body, true);
// ... twoja logika ...

echo json_encode(['success' => true, 'result' => 'OK']);
?>
Krytyczne zasady bezpieczeństwa:
  • Zawsze weryfikuj podpis jeśli używasz webhook secret!
  • Sprawdzaj timestamp - odrzucaj stare żądania (zalecane: kilka minut)
  • Śledź nonce - przechowuj użyte nonce w cache aby zapobiec ponownemu użyciu (replay attack)
  • Używaj timing-safe compare - unikaj timing attacks przy porównywaniu hashów
  • Chroń webhook secret - nie commituj do repo, używaj zmiennych środowiskowych lub menedżera sekretów
Opcjonalne, ale zalecane: Webhook secret NIE jest wymagany, ale bez niego każdy może wysłać fałszywe żądanie do Twojego endpointu. W środowisku produkcyjnym ZAWSZE używaj webhook secret!
9

Format odpowiedzi webhook

Twój endpoint musi zwrócić odpowiedź JSON, którą chatbot wykorzysta do kontynuacji rozmowy. Format odpowiedzi jest elastyczny - możesz zwrócić dowolną strukturę.

Minimalna odpowiedź (sukces)

HTTP/1.1 200 OK
Content-Type: application/json

{
  "success": true,
  "result": "Użytkownik został dodany do newslettera!"
}

Odpowiedź z błędem

HTTP/1.1 200 OK
Content-Type: application/json

{
  "success": false,
  "error": "Ten adres email jest już zapisany do newslettera"
}

Bogata odpowiedź z dodatkowymi danymi

{
  "success": true,
  "result": "Rezerwacja potwierdzona",
  "data": {
    "reservation_id": "RES-12345",
    "date": "2024-01-15",
    "time": "18:00",
    "guests": 4,
    "table_number": "A5",
    "confirmation_code": "CONF789"
  },
  "message": "Twoja rezerwacja została potwierdzona. Numer potwierdzenia: CONF789"
}

Wymagania techniczne

Wymaganie Wartość Uwagi
Status code HTTP 200 OK Inne kody (4xx, 5xx) traktowane jako błąd
Content-Type application/json Wymagane
Maksymalny rozmiar Limitowany Zbyt duże odpowiedzi zostaną odrzucone
Timeout Konfigurowalne (1-30s) Domyślnie 10 sekund

Response Mapping (zaawansowane)

Jeśli Twoje API zwraca złożoną strukturę, możesz skonfigurować response mapping aby wyodrębnić potrzebne pola:

Przykład - Twoje API zwraca:

{
  "status": "ok",
  "data": {
    "user": {
      "id": 123,
      "email": "[email protected]"
    },
    "subscription": {
      "active": true,
      "created_at": "2024-01-10T15:30:00Z"
    }
  },
  "meta": {
    "request_id": "req-abc"
  }
}

Skonfiguruj mapping (JSON):

{
  "user_id": "data.user.id",
  "email": "data.user.email",
  "is_active": "data.subscription.active",
  "request_id": "meta.request_id"
}

Chatbot otrzyma:

{
  "success": true,
  "user_id": 123,
  "email": "[email protected]",
  "is_active": true,
  "request_id": "req-abc"
}
Uproszczenie: Response mapping używa prostej notacji kropkowej (dot-notation). Dla bardziej złożonych transformacji, dostosuj odpowiedź po stronie swojego API.
Co chatbot robi z odpowiedzią? Model AI przetwarza zwrócone dane i formułuje naturalną odpowiedź dla użytkownika. Możesz zwrócić zarówno kod (np. ID rezerwacji) jak i opisowy tekst - AI wie, jak to wykorzystać w rozmowie.
10

Tryb wykonania

Custom tools wykonują się synchronicznie (SYNC). System czeka na odpowiedź z webhooka przed kontynuacją rozmowy, dzięki czemu chatbot otrzymuje wynik i może go wykorzystać w odpowiedzi do użytkownika.

Charakterystyka trybu synchronicznego

SYNC
  • Chatbot czeka na odpowiedź z webhook przed kontynuacją rozmowy
  • Maksymalny timeout: 30 sekund (konfigurowalny w zakresie 1-30s, domyślnie 10s)
  • Automatyczne retry przy błędach - do 3 prób z wykładniczym backoff
  • Pełne logowanie request/response dla każdego wywołania
  • Odpowiedź webhook jest przekazywana do AI jako wynik funkcji

Konfiguracja timeoutu

W ustawieniach zaawansowanych narzędzia możesz dostosować timeout do swoich potrzeb:

  • Krótki timeout (1-5s): Idealne dla szybkich operacji bazodanowych, sprawdzania cache
  • Średni timeout (5-15s): Standardowe wywołania API, zapisywanie do CRM
  • Długi timeout (15-30s): Złożone operacje, integracje z wolniejszymi systemami

Retry policy

System automatycznie powtarza nieudane wywołania zgodnie z konfiguracją:

Próba Opóźnienie Opis
1 0s Pierwsze wywołanie - natychmiastowe
2 1s Pierwsza ponowna próba
3 2s Druga ponowna próba
4 4s Trzecia ponowna próba (ostatnia)

Przykładowe zastosowania

  • Sprawdzanie dostępności produktu - chatbot czeka na wynik i informuje użytkownika o stanie magazynowym
  • Tworzenie leadów w CRM - potwierdzenie zapisania kontaktu
  • Rezerwacja terminów - weryfikacja dostępności i potwierdzenie rezerwacji
  • Pobieranie danych z bazy - wyszukiwanie informacji i prezentacja wyników
  • Integracje z API zewnętrznymi - pobieranie statusu zamówienia, śledzenie przesyłki
Optymalizacja czasu odpowiedzi: Upewnij się, że Twój webhook odpowiada jak najszybciej. Użytkownik czeka na wynik, więc operacje powinny być zoptymalizowane. Dla długotrwałych procesów rozważ zwracanie natychmiastowego potwierdzenia i późniejsze powiadomienie przez inny kanał (email, SMS).
Best practice: Staraj się utrzymywać czas odpowiedzi poniżej 3 sekund dla najlepszego doświadczenia użytkownika. Jeśli operacja wymaga więcej czasu, poinformuj użytkownika w odpowiedzi (np. "Przetwarzam Twoje zgłoszenie, to może potrwać chwilę...").
11

Zaawansowane funkcje

Custom Tools oferują szereg zaawansowanych funkcji pozwalających na precyzyjne dostosowanie zachowania narzędzi do Twoich potrzeb.

Rate Limiting

Rate limiting chroni Twój endpoint przed przeciążeniem i zapewnia sprawiedliwe wykorzystanie zasobów. Każde narzędzie ma skonfigurowane limity wywołań, które możesz dostosować do swoich potrzeb.

Jak działa?

  • System śledzi liczbę wywołań narzędzia w określonym przedziale czasowym
  • Gdy limit zostanie przekroczony, kolejne wywołania są odrzucane
  • Chatbot otrzymuje informację o przekroczeniu limitu i może poinformować użytkownika
  • Licznik resetuje się automatycznie po upływie okresu
Optymalizacja: Ustaw limity adekwatne do oczekiwanego ruchu i możliwości Twojego endpointu. Za niskie limity mogą frustrować użytkowników, za wysokie mogą przeciążyć system.

Retry Logic

System automatycznie ponawia nieudane wywołania webhooków, aby zwiększyć niezawodność. Retry jest stosowany w przypadku:

  • Timeout - endpoint nie odpowiedział w określonym czasie
  • Błędy sieciowe - problemy z połączeniem, DNS, SSL
  • Błędy 5xx - błędy serwera (500, 502, 503, 504)
  • Connection errors - odmowa połączenia, reset

Retry NIE jest stosowany dla:

  • Błędów 4xx (400, 401, 404 itp.) - błędy klienta wymagają poprawki
  • Odpowiedzi 200 z {"success": false} - logiczny błąd aplikacji

Strategia exponential backoff

Opóźnienie między próbami rośnie wykładniczo, co daje systemowi czas na odzyskanie i zmniejsza obciążenie podczas awarii.

Idempotentność: Upewnij się, że Twój endpoint jest idempotentny - wielokrotne wywołanie z tymi samymi parametrami powinno dać ten sam rezultat. Używaj unique request ID (dostępne w payload) do deduplikacji po swojej stronie.

Fallback Response

Fallback response to odpowiedź, którą chatbot otrzyma, gdy wywołanie webhooka się nie powiedzie (po wyczerpaniu retry). Pozwala to chatbotowi kontynuować rozmowę z użytkownikiem w sposób graceful, zamiast pokazywać błąd.

Przykład fallback response (JSON):

{
  "success": false,
  "message": "Przepraszamy, nie mogliśmy przetworzyć Twojego zgłoszenia w tym momencie. Spróbuj ponownie za chwilę lub skontaktuj się z nami mailowo: [email protected]"
}

Chatbot wykorzysta tę wiadomość aby poinformować użytkownika o problemie w naturalny sposób.

User experience: Dobrze skonstruowana fallback response powinna:
  • Wyjaśniać problem w prosty sposób (bez szczegółów technicznych)
  • Sugerować alternatywne rozwiązanie (email, telefon, spróbuj później)
  • Przepraszać za niedogodności
  • Być konkretna i pomocna

Custom Request Templates (Jinja2)

Jeśli Twoje API wymaga specyficznego formatu payloadu, możesz użyć Jinja2 template do pełnej kontroli nad strukturą żądania.

Dostępne zmienne w template:

Zmienna Typ Opis
arguments dict Parametry wywołania wyodrębnione przez AI
tool_name string Nazwa wywołanego narzędzia
now() function Zwraca aktualny datetime

Przykład zaawansowany - integracja z CRM:

{
  "action": "create_contact",
  "timestamp": "{{ now().isoformat() }}",
  "source": {
    "channel": "chatbot",
    "tool": "{{ tool_name }}"
  },
  "contact": {
    "email": "{{ arguments.email }}",
    "firstName": "{{ arguments.first_name | default('') }}",
    "lastName": "{{ arguments.last_name | default('') }}",
    "phone": "{{ arguments.phone | default('') }}",
    "tags": {{ arguments.interests | default([]) | tojson }},
    "customFields": {
      "leadSource": "chatbot_{{ tool_name }}",
      "capturedAt": "{{ now().strftime('%Y-%m-%d %H:%M:%S') }}"
    }
  },
  "metadata": {
    "apiVersion": "v2"
  }
}

Dostępne filtry Jinja2:

  • default(value) - wartość domyślna jeśli zmienna nie istnieje
  • upper, lower - zmiana wielkości liter
  • tojson - konwersja do JSON
  • length - długość listy/stringa
  • trim - usunięcie białych znaków

Response Mapping

Response mapping pozwala wyodrębnić konkretne pola z odpowiedzi webhooka używając notacji kropkowej.

Przykład - API zwraca zagnieżdżoną strukturę:

{
  "status": "success",
  "code": 201,
  "payload": {
    "reservation": {
      "id": "RES-789",
      "confirmationCode": "ABC123",
      "guestDetails": {
        "name": "Jan Kowalski",
        "phone": "+48500600700"
      }
    },
    "timestamp": "2024-01-10T15:30:00Z"
  }
}

Mapping (JSON):

{
  "reservation_id": "payload.reservation.id",
  "confirmation": "payload.reservation.confirmationCode",
  "guest_name": "payload.reservation.guestDetails.name",
  "created_at": "payload.timestamp"
}

Chatbot otrzyma uproszczoną strukturę:

{
  "success": true,
  "reservation_id": "RES-789",
  "confirmation": "ABC123",
  "guest_name": "Jan Kowalski",
  "created_at": "2024-01-10T15:30:00Z"
}
Kombinowanie funkcji: Możesz łączyć wszystkie zaawansowane funkcje razem. Na przykład: custom request template + response mapping + fallback response + retry logic dla pełnej kontroli nad integracją.
12

Testowanie i debugowanie

Efektywne testowanie i debugowanie są kluczowe dla zapewnienia niezawodności Custom Tools. System oferuje szereg narzędzi do diagnozowania i rozwiązywania problemów.

Funkcja Test w panelu

W panelu zarządzania każde narzędzie ma przycisk "Test", który pozwala na szybkie przetestowanie webhoo ka bez konieczności przeprowadzania pełnej rozmowy.

Jak przetestować narzędzie:

  1. Przejdź do szczegółów narzędzia w panelu Custom Tools
  2. Kliknij przycisk "Test Tool"
  3. Wpisz przykładowe wartości parametrów w formacie JSON
  4. Kliknij "Wykonaj test"
  5. System wyśle webhook do Twojego endpointu i wyświetli:
    • Wysłany request (headers + body)
    • Otrzymaną odpowiedź (status, headers, body)
    • Czas wykonania
    • Ewentualne błędy

Przykładowy payload testowy:

{
  "email": "[email protected]",
  "full_name": "Jan Testowy",
  "interests": ["AI", "marketing"]
}
Debugowanie: Funkcja test jest idealnym narzędziem do debugowania - możesz iteracyjnie testować różne scenariusze i natychmiast widzieć rezultaty.

Execution History (Historia wykonań)

Każde wywołanie Custom Tool jest logowane z pełnymi szczegółami. Historia wykonań to Twoje główne narzędzie do analizy i debugowania.

Co jest logowane?

Informacja Opis
Timestamp Dokładna data i czas wywołania
Tool name Nazwa wywołanego narzędzia
Arguments Parametry wyodrębnione przez AI
Request payload Pełny payload wysłany do webhooka
Request headers Wszystkie nagłówki HTTP (włącznie z HMAC)
Response status Kod statusu HTTP (200, 404, 500, etc.)
Response body Odpowiedź zwrócona przez endpoint
Execution time Czas wykonania w milisekundach
Status Success, Failed, Timeout, Rate Limited
Error details Szczegóły błędu jeśli wystąpił
Retry attempts Liczba ponownych prób

Filtrowanie i wyszukiwanie

W historii wykonań możesz filtrować po:

  • Zakres dat - ostatnie 24h, 7 dni, 30 dni, custom
  • Status - tylko udane, tylko błędy, timeouty
  • Narzędzie - wybierz konkretne tool
  • Tekst - wyszukaj w payloadach i odpowiedziach

Analytics i metryki

Panel analytics dostarcza agregowanych statystyk pomocy przy optymalizacji i monitorowaniu:

Dostępne metryki:

  • Liczba wywołań - total, ostatnie 24h, trend
  • Success rate - procent udanych wywołań
  • Średni czas odpowiedzi - performance endpointu
  • Error rate - procent błędów z podziałem na typy
  • Rate limit hits - ile razy przekroczono limit
  • Top errors - najczęstsze komunikaty błędów
  • Wykres w czasie - wizualizacja wywołań i błędów

Debugowanie lokalnie

Podczas rozwoju możesz potrzebować testować webhook lokalnie. Oto najlepsze metody:

Metoda 1: Tunele (ngrok, LocalTunnel, Cloudflare Tunnel)

Tunele ekspozują Twój lokalny serwer do internetu przez tymczasowy URL HTTPS:

# Ngrok
ngrok http 3000

# Wygeneruje URL: https://abc123.ngrok.io
# Użyj tego URL w konfiguracji Custom Tool
Uwaga bezpieczeństwa: Tunele ekspozują Twój lokalny serwer do internetu. Używaj ich tylko w development i zawsze implementuj webhook secret!

Metoda 2: Webhook testing services (webhook.site, requestbin)

Te serwisy dają Ci tymczasowy URL, na który możesz wysłać webhooks i przeglądać je w przeglądarce. Świetne do pierwszego testowania bez pisania kodu.

Metoda 3: Logging po stronie endpointu

Implementuj szczegółowe logowanie w swoim endpoincie:

@app.route('/webhook', methods=['POST'])
def handle_webhook():
    # Log wszystko
    logger.info(f"Received webhook: {request.method} {request.url}")
    logger.info(f"Headers: {dict(request.headers)}")
    logger.info(f"Body: {request.get_data(as_text=True)}")

    try:
        result = process_webhook(request.json)
        logger.info(f"Success: {result}")
        return jsonify(result)
    except Exception as e:
        logger.error(f"Error: {str(e)}", exc_info=True)
        return jsonify({"error": str(e)}), 500

Checklist testowania przed produkcją

  • ✓ Przetestowano wszystkie scenariusze parametrów (required, optional, edge cases)
  • ✓ Webhook secret skonfigurowany i weryfikacja działa
  • ✓ Endpoint odpowiada w < 10 sekund (idealnie < 3 sek)
  • ✓ Obsługa błędów zwraca sensowne komunikaty
  • ✓ HTTPS certyfikat jest ważny i zaufany
  • ✓ Rate limiting dostosowany do expected traffic
  • ✓ Monitoring i alerty skonfigurowane (Sentry, CloudWatch, etc.)
  • ✓ Fallback response skonfigurowana i przetestowana
  • ✓ Endpoint jest idempotentny (retry-safe)
  • ✓ Przetestowano z prawdziwym chatbotem w dialogu
Continuous testing: Po wdrożeniu regularnie przeglądaj execution history i analytics. Ustaw alerty dla anomalii (wzrost błędów, timeout spike, rate limit exceeded).
13

Dobre praktyki

Poniższe dobre praktyki pomogą Ci stworzyć niezawodne, bezpieczne i wydajne Custom Tools.

🔒 Bezpieczeństwo

1. Zawsze używaj Webhook Secret w produkcji

# Generuj silny, losowy secret (min. 32 znaki)
import secrets
webhook_secret = secrets.token_urlsafe(32)
# Np: "whsec_abc123XYZ..."

2. Weryfikuj podpis HMAC przy każdym żądaniu

  • Sprawdzaj timestamp - odrzucaj stare żądania
  • Śledź nonce w cache aby zapobiec replay attacks
  • Używaj timing-safe compare przy porównywaniu hashów

3. Ogranicz dostęp do endpointu

  • Używaj firewall rules jeśli to możliwe (whitelist IP)
  • Implementuj rate limiting na swoim serwerze
  • Loguj wszystkie nieudane próby weryfikacji

4. Nie ujawniaj wrażliwych szczegółów w odpowiedziach

# ❌ Źle - ujawnia szczegóły
{"error": "SQL error at line 42: table 'users' doesn't exist"}

# ✅ Dobrze - ogólny komunikat
{"success": false, "message": "Nie mogliśmy przetworzyć zgłoszenia"}

5. Przechowuj webhook secret bezpiecznie

  • Używaj zmiennych środowiskowych lub menedżera sekretów
  • Nie commituj sekretów do repozytorium
  • Rotuj sekrety regularnie (co 3-6 miesięcy)
  • Używaj różnych sekretów dla dev/staging/production

⚡ Performance i niezawodność

1. Optymalizuj czas odpowiedzi

  • Cel: < 3 sekundy dla 95% requestów
  • Używaj database indexes dla często odpytywanych kolumn
  • Cache'uj powtarzalne zapytania (Redis, Memcached)
  • Rozważ async processing dla długotrwałych operacji

2. Endpoint musi być idempotentny

# Używaj unique identifiers do deduplikacji
@app.route('/webhook', methods=['POST'])
def handle_webhook():
    data = request.json
    request_id = data.get('request_id')  # Unikalny ID z payloadu

    # Sprawdź czy już przetwarzałeś ten request
    if cache.exists(f"processed:{request_id}"):
        return cached_response

    # Przetwarzaj...
    result = process_action(data)

    # Zapisz w cache (TTL = 1 godzina)
    cache.setex(f"processed:{request_id}", 3600, result)
    return result

3. Graceful error handling

  • Zawsze zwracaj HTTP 200 dla błędów aplikacyjnych
  • Używaj {"success": false, "error": "..."} dla błędów logicznych
  • Zwracaj 5xx tylko dla prawdziwych błędów serwera
  • Implementuj fallback behaviors

4. Monitoruj i alertuj

# Przykład integracji z Sentry
import sentry_sdk

@app.route('/webhook', methods=['POST'])
def handle_webhook():
    try:
        return process_webhook(request.json)
    except Exception as e:
        sentry_sdk.capture_exception(e)
        return {"success": false, "message": "Internal error"}, 500

📝 Projektowanie schema i opisów

1. Pisz jasne, konkretne opisy narzędzi

# ❌ Źle - zbyt ogólne
"Zarządza rezerwacjami"

# ✅ Dobrze - konkretne, z przykładami
"Tworzy rezerwację stolika w restauracji. Użyj gdy użytkownik chce zarezerwować stolik, umówić się na wizytę lub zarezerwować miejsce. Wymaga daty, godziny i liczby osób."

2. Definiuj precyzyjne parametry

  • Używaj enum gdy możliwe (ogranicza błędy)
  • Podawaj przykłady w description
  • Specyfikuj formaty (YYYY-MM-DD, HH:MM, email, etc.)
  • Oznaczaj wymagane pola w required
{
  "type": "object",
  "properties": {
    "date": {
      "type": "string",
      "description": "Data rezerwacji w formacie YYYY-MM-DD, np. 2024-01-15",
      "pattern": "^\\d{4}-\\d{2}-\\d{2}$"
    },
    "priority": {
      "type": "string",
      "enum": ["low", "medium", "high", "urgent"],
      "description": "Priorytet zgłoszenia"
    }
  },
  "required": ["date", "priority"]
}

3. Unikaj zbyt wielu parametrów

  • Ideał: 3-5 parametrów
  • Max: 10 parametrów
  • Jeśli potrzebujesz więcej - rozważ podział na kilka narzędzi

🎯 User Experience

1. Komunikaty dla użytkowników

  • Piszjasno i zrozumiale (unikaj żargonu technicznego)
  • Bądź pozytywny i pomocny
  • Podawaj następne kroki lub alternatywy
  • Personalizuj gdy to możliwe
# ❌ Technicznie poprawne, ale nie user-friendly
{"result": "Record inserted with ID 12345"}

# ✅ Przyjazne dla użytkownika
{"result": "Świetnie! Dodałem Cię do newslettera. Będziesz otrzymywać nasze aktualizacje na adres [email protected]"}

2. Fallback responses powinny być pomocne

{
  "success": false,
  "message": "Przepraszamy, nasze rezerwacje są obecnie niedostępne. Możesz zadzwonić do nas: +48 123 456 789 lub spróbować ponownie za kilka minut."
}

🏗️ Architektura i organizacja

1. Jeden tool = jedna odpowiedzialność

  • Unikaj uniwersalnych narzędzi typu "manage_everything"
  • Lepiej: create_lead, update_lead, get_lead_status
  • AI lepiej rozumie konkretne, wyspecjalizowane narzędzia

2. Nazywaj narzędzia czytelnie

# ❌ Źle
"tool1", "webhook_handler", "api_call"

# ✅ Dobrze
"create_newsletter_subscription"
"check_product_availability"
"book_appointment"

3. Wersjonuj swoje API

  • Dodaj wersję do URL: /api/v1/webhook
  • Lub w custom headers: X-API-Version: 1
  • Utrzymuj backwards compatibility gdy to możliwe

4. Loguj wszystko (w dev i prod)

  • Request ID dla correlation
  • Input parameters (bez wrażliwych danych!)
  • Execution time
  • Errors ze stack traces
  • Używaj structured logging (JSON)

📊 Testowanie i deployment

1. Test w staging przed production

  • Używaj osobnych narzędzi dla dev/staging/prod
  • Test z prawdziwymi danymi (ale zanonimizowanymi)
  • Weryfikuj wszystkie edge cases
  • Load testing przy oczekiwanym traffic + 50%

2. Deployment checklist

  • ✓ HTTPS certyfikat ważny i automatycznie odnawiany
  • ✓ Webhook secret skonfigurowany
  • ✓ Rate limiting ustawione
  • ✓ Monitoring i alerty gotowe
  • ✓ Backup strateg ia dla danych
  • ✓ Rollback plan przygotowany
  • ✓ Dokumentacja dla zespołu
Złota zasada: Projektuj Custom Tools myśląc o użytkowniku końcowym, nie o technicznych detalach. Jeśli chatbot mówi "Webhook zwrócił kod 500" zamiast "Nie mogłem zarezerwować stolika" - coś jest nie tak.
14

Rozwiązywanie problemów

Napotkałeś problem z Custom Tools? Poniżej znajdziesz rozwiązania najczęstszych problemów.

❌ Problem: Weryfikacja URL się nie udaje

Symptom:

Status narzędzia to FAILED po próbie weryfikacji

Możliwe przyczyny i rozwiązania:

Przyczyna Rozwiązanie
Endpoint nie odpowiada • Sprawdź czy serwer działa (curl https://your-url.com)
• Sprawdź logi serwera
• Upewnij się że port jest otwarty w firewall
SSL/TLS error • Sprawdź certyfikat: openssl s_client -connect your-domain.com:443
• Upewnij się że certyfikat jest ważny i zaufany
• Sprawdź czy full certificate chain jest zainstalowany
Timeout • Endpoint musi odpowiedzieć w ciągu kilku sekund
• Upewnij się że weryfikacja nie wywołuje ciężkich operacji
• Sprawdź network latency
404 Not Found • Sprawdź ścieżkę URL - czy routing jest poprawnie skonfigurowany?
• Testuj lokalnie: curl -X POST https://your-url.com/webhook -d '{}'
Token mismatch • Upewnij się że zwracasz DOKŁADNIE ten sam token który otrzymałeś
• Sprawdź czy nie modyfikujesz tokena (trim, encode, etc.)

❌ Problem: Narzędzie nie jest wywoływane przez chatbota

Symptom:

Chatbot ignoruje narzędzie, mimo że powinien je wywołać

Możliwe przyczyny i rozwiązania:

  • Opis jest zbyt ogólny lub niejasny
    → Przepisz opis używając konkretnych przykładów i scenariuszy użycia
    → Dodaj keywords które użytkownik może użyć w rozmowie
  • Narzędzie jest nieaktywne
    → Sprawdź status - musi być ACTIVE
    → Jeśli status to DRAFT lub INACTIVE - aktywuj narzędzie
  • Parametry są zbyt skomplikowane lub niejasne
    → Uprość schema - AI może mieć problem z wyodrębnieniem zbyt wielu parametrów
    → Dodaj jasne descriptions do każdego parametru
  • Konflikt z innymi narzędziami
    → Jeśli masz kilka podobnych narzędzi, AI może wybrać niewłaściwe
    → Zróżnicuj opisy aby były jednoznaczne
Test: Spróbuj zadać chatbotowi pytanie które JAWNIE odnosi się do funkcji narzędzia. Np. dla narzędzia "newsletter" napisz "Chcę zapisać się do newslettera". Jeśli nadal nie działa - opis wymaga poprawy.

❌ Problem: Webhook timeout

Symptom:

Execution history pokazuje status "Timeout", endpoint nie zdążył odpowiedzieć

Rozwiązania:

  • Zwiększ timeout w ustawieniach narzędzia (max 30s)
  • Optymalizuj endpoint:
    • Dodaj database indexes
    • Używaj cache dla powtarzalnych zapytań
    • Profiluj kod aby znaleźć bottlenecks
  • Rozważ async processing:
    • Zwróć natychmiastową odpowiedź ("Przetwarzam...")
    • Wykonaj heavy operation w tle (Celery, RQ, etc.)
    • Powiadom użytkownika przez inny kanał (email, SMS)

❌ Problem: HMAC signature invalid

Symptom:

Endpoint odrzuca requesty z błędem "Invalid signature"

Checklist debugowania:

  1. Sprawdź czy używasz poprawnego secretu
    # Wypisz secret używany w kodzie (tylko w dev!)
    print(f"Secret: {WEBHOOK_SECRET}")
    
    # Porównaj z secretem w panelu Custom Tools
  2. Sprawdź kolejność składania message
    # Musi być: timestamp.nonce.body
    message = f"{timestamp}.{nonce}.{body}"
    
    # NIE: nonce.timestamp.body (błąd!)
    # NIE: timestamp-nonce-body (separator musi być kropka!)
  3. Sprawdź czy używasz surowego body
    # ✅ Dobrze - surowy string
    body = request.get_data(as_text=True)
    
    # ❌ Źle - sparsowany JSON
    body = json.dumps(request.json)  # To zmieni kolejność kluczy!
  4. Sprawdź algorytm hash
    # Musi być HMAC-SHA256
    hash = hmac.new(secret, message, hashlib.sha256).hexdigest()
    
    # Encoding: UTF-8 dla secret i message
  5. Porównaj hashe bezpiecznie
    # Python
    hmac.compare_digest(expected, received)
    
    # Node.js
    crypto.timingSafeEqual(Buffer.from(expected), Buffer.from(received))
    
    # PHP
    hash_equals($expected, $received)

❌ Problem: Rate limit exceeded

Symptom:

Execution history pokazuje "Rate Limited", kolejne wywołania są blokowane

Rozwiązania:

  • Zwiększ limity w ustawieniach narzędzia jeśli to uzasadnione
  • Podziel funkcjonalność - może jedno narzędzie robi za dużo?
  • Implementuj caching - jeśli wiele wywołań zwraca te same dane
  • Edukuj użytkowników - może próbują spamować?

❌ Problem: AI wyodrębnia błędne parametry

Symptom:

Webhook otrzymuje niewłaściwe wartości parametrów lub brakujące dane

Rozwiązania:

  • Popraw descriptions parametrów
    # ❌ Źle - zbyt ogólne
    "date": {"type": "string", "description": "Data"}
    
    # ✅ Dobrze - konkretne z przykładem
    "date": {
      "type": "string",
      "description": "Data wizyty w formacie YYYY-MM-DD, np. 2024-01-15",
      "pattern": "^\\d{4}-\\d{2}-\\d{2}$"
    }
  • Używaj enum dla ograniczonego zbioru wartości
    "priority": {
      "type": "string",
      "enum": ["low", "normal", "high", "urgent"],
      "description": "Poziom priorytetu zgłoszenia"
    }
  • Dodaj validation constraints
    • minimum, maximum dla liczb
    • minLength, maxLength dla stringów
    • pattern dla regex validation
  • Testuj z różnymi sformułowaniami - zobacz jak AI interpretuje różne frazy

❌ Problem: Endpoint zwraca dane ale chatbot ich nie używa

Symptom:

Webhook działa i zwraca odpowiedź, ale chatbot nie wykorzystuje danych w rozmowie

Rozwiązania:

  • Sprawdź format odpowiedzi
    # Upewnij się że zwracasz JSON
    Content-Type: application/json
    
    {"success": true, "result": "Dane do przekazania chatbotowi"}
  • Upewnij się że success = true dla udanych operacji
  • Użyj response mapping jeśli zwracasz złożoną strukturę
  • Dodaj opisowe pola które AI może wykorzystać w odpowiedzi
    # Zamiast samych ID:
    {"order_id": 12345}
    
    # Dodaj kontekst:
    {
      "success": true,
      "order_id": "ORD-12345",
      "confirmation_message": "Twoje zamówienie zostało przyjęte. Numer: ORD-12345",
      "delivery_date": "2024-01-20"
    }

🆘 Dalsze kroki jeśli problem persystuje

Potrzebujesz pomocy?
  1. Sprawdź Execution History - pełne logi request/response mogą ujawnić problem
  2. Testuj lokalnie - używając ngrok/webhook.site aby zobaczyć dokładnie co jest wysyłane
  3. Porównaj z działającymi przykładami - zobacz jak są skonfigurowane w dokumentacji
  4. Skontaktuj się z supportem - załącz execution ID i szczegóły problemu

📚 Przydatne narzędzia debugowania

  • webhook.site - tymczasowy endpoint do przeglądania webhooks
  • ngrok - tunnel do testowania localhost
  • Postman/Insomnia - testowanie API requests
  • JSON Schema Validator - walidacja parameters schema
  • SSL Labs - sprawdzanie certyfikatu SSL/TLS
  • cURL - testowanie endpointu z command line
Wskazówka: 90% problemów z Custom Tools to błędna konfiguracja (URL, schema, opis). Zanim będziesz debugować kod - sprawdź dokładnie konfigurację w panelu i execution history!