Приклади PHP
Використання cURL
Список лідів
php
$ch = curl_init('https://api.looma.chat/v1/leads?status=new&per_page=50');
curl_setopt_array($ch, [
CURLOPT_HTTPHEADER => ['Authorization: Bearer lm_your_key'],
CURLOPT_RETURNTRANSFER => true,
]);
$response = json_decode(curl_exec($ch), true);
curl_close($ch);
foreach ($response['data'] as $lead) {
echo "{$lead['id']}: {$lead['status']} — {$lead['lead_text']}\n";
}Оновлення статусу ліда
php
$ch = curl_init('https://api.looma.chat/v1/leads/456');
curl_setopt_array($ch, [
CURLOPT_CUSTOMREQUEST => 'PATCH',
CURLOPT_HTTPHEADER => [
'Authorization: Bearer lm_your_key',
'Content-Type: application/json',
],
CURLOPT_POSTFIELDS => json_encode([
'status' => 'in_progress',
'assigned_operator_id' => 5,
]),
CURLOPT_RETURNTRANSFER => true,
]);
$response = json_decode(curl_exec($ch), true);
curl_close($ch);Надсилання повідомлення в чат
php
$sessionId = 'session_abc123';
$ch = curl_init("https://api.looma.chat/v1/chats/{$sessionId}/messages");
curl_setopt_array($ch, [
CURLOPT_POST => true,
CURLOPT_HTTPHEADER => [
'Authorization: Bearer lm_your_key',
'Content-Type: application/json',
],
CURLOPT_POSTFIELDS => json_encode([
'text' => 'Hello! How can I help you today?',
]),
CURLOPT_RETURNTRANSFER => true,
]);
$response = json_decode(curl_exec($ch), true);
curl_close($ch);Завантаження файлу в чат
php
$sessionId = 'session_abc123';
$ch = curl_init("https://api.looma.chat/v1/chats/{$sessionId}/files");
curl_setopt_array($ch, [
CURLOPT_POST => true,
CURLOPT_HTTPHEADER => ['Authorization: Bearer lm_your_key'],
CURLOPT_POSTFIELDS => [
'file' => new CURLFile('/path/to/document.pdf'),
'message' => 'Please see the attached document',
],
CURLOPT_RETURNTRANSFER => true,
]);
$response = json_decode(curl_exec($ch), true);
curl_close($ch);Використання Guzzle
Встановлення Guzzle:
bash
composer require guzzlehttp/guzzleКлас-хелпер
php
use GuzzleHttp\Client;
$client = new Client([
'base_uri' => 'https://api.looma.chat/v1/',
'headers' => [
'Authorization' => 'Bearer lm_your_key',
'Accept' => 'application/json',
],
]);Список лідів
php
$response = $client->get('leads', [
'query' => ['status' => 'new', 'per_page' => 50],
]);
$data = json_decode($response->getBody(), true);
foreach ($data['data'] as $lead) {
echo "{$lead['id']}: {$lead['status']}\n";
}Оновлення ліда
php
$response = $client->patch('leads/456', [
'json' => [
'status' => 'in_progress',
'assigned_operator_id' => 5,
],
]);Додавання коментаря
php
$response = $client->post('leads/456/comments', [
'json' => ['text' => 'Called the customer, waiting for callback.'],
]);Експорт лідів у CSV
php
$response = $client->get('leads/export', [
'query' => ['status' => 'new', 'date_from' => '2026-01-01'],
'sink' => '/tmp/leads.csv',
]);Створення вебхука
php
$response = $client->post('webhooks', [
'json' => [
'url' => 'https://your-app.com/webhooks/looma',
'events' => ['lead.created', 'chat.message.new'],
],
]);
$webhook = json_decode($response->getBody(), true);
// Збережіть $webhook['data']['secret'] — показується лише один раз!Отримання балансу
php
$response = $client->get('balance');
$balance = json_decode($response->getBody(), true);
echo "Credits: {$balance['data']['credits']}\n";
echo "USD: {$balance['data']['usd_equivalent']}\n";Обробка помилок
php
use GuzzleHttp\Exception\ClientException;
try {
$response = $client->get('leads/999999');
} catch (ClientException $e) {
$body = json_decode($e->getResponse()->getBody(), true);
$status = $e->getResponse()->getStatusCode();
echo "HTTP {$status}: {$body['error']['code']} — {$body['error']['message']}\n";
if ($status === 429) {
$retryAfter = $e->getResponse()->getHeader('Retry-After')[0] ?? 60;
sleep((int) $retryAfter);
}
}Верифікація підпису вебхука
php
$payload = file_get_contents('php://input');
$timestamp = $_SERVER['HTTP_X_LOOMA_TIMESTAMP'] ?? '';
$signature = $_SERVER['HTTP_X_LOOMA_SIGNATURE'] ?? '';
// Заголовок несе префікс `sha256=` — зніміть його перед порівнянням.
$signature = str_starts_with($signature, 'sha256=') ? substr($signature, 7) : $signature;
$expected = hash_hmac('sha256', $timestamp . '.' . $payload, $webhookSecret);
if (!hash_equals($expected, $signature)) {
http_response_code(401);
exit('Invalid signature');
}
// Відхиляти запити старше 5 хвилин
if (abs(time() - (int) $timestamp) > 300) {
http_response_code(401);
exit('Timestamp too old');
}
// Назва події — у заголовку; тіло несе лише поля самої події, без обгортки.
$eventName = $_SERVER['HTTP_X_LOOMA_EVENT'] ?? '';
$data = json_decode($payload, true);
switch ($eventName) {
case 'lead.created':
// $data['lead_id'], $data['collected_fields'], ...
break;
case 'chat.message.new':
// Обробка нового повідомлення
break;
}
http_response_code(200);
echo 'OK';
