leadora / agents-api
PHP client for the Leadora agent panel API
Requires
- php: ^8.1
- ext-json: *
- guzzlehttp/guzzle: ^7.0
Requires (Dev)
- phpunit/phpunit: ^10.5
This package is auto-updated.
Last update: 2026-08-11 18:57:31 UTC
README
کلاینت PHP برای API پنل نمایندگی لیدورا (/api/v1).
نصب
composer require leadora/agents-api
توسعه محلی:
{
"repositories": [
{
"type": "path",
"url": "/home/behzad/Documents/php-projects/leadora-agents-api"
}
],
"require": {
"leadora/agents-api": "@dev"
}
}
راهاندازی
use Leadora\Agents\LeadoraClient; $client = LeadoraClient::create( baseUrl: env('LEADORA_BASE_URL'), // مثلا https://api.leadora.example apiToken: env('LEADORA_API_TOKEN'), // توکن نماینده );
همه درخواستها با هدر Authorization: Bearer <token> احراز هویت میشوند.
هر endpoint یک scope مشخص نیاز دارد که باید روی توکن فعال باشد.
فهرست endpointها
| متد کلاینت | HTTP | Scope | Idempotency-Key |
|---|---|---|---|
profile()->get() |
GET /api/v1/agent/profile |
profile.read |
— |
users()->register() |
POST /api/v1/users |
users.write |
— |
leads()->preview() |
POST /api/v1/leads/preview |
preview.create |
— |
leads()->naturalLanguagePreview() |
POST /api/v1/leads/natural-language-preview |
preview.create |
— |
leads()->campaignMessagePreview() |
POST /api/v1/leads/campaign-message-preview |
preview.create |
— |
leads()->quote() |
POST /api/v1/leads/quote |
quote.create |
— |
orders()->create() |
POST /api/v1/orders |
orders.create |
الزامی |
orders()->pay() |
POST /api/v1/orders/{id}/pay |
orders.pay |
الزامی |
orders()->listLeads() |
GET /api/v1/orders/{id}/leads |
exports.read |
— |
orders()->listAllLeadMobiles() |
حلقه روی listLeads |
exports.read |
— |
orders()->createExport() |
POST /api/v1/orders/{id}/exports |
exports.create |
الزامی |
exports()->get() |
GET /api/v1/exports/{id} |
exports.read |
— |
exports()->download() |
GET /api/v1/exports/{id}/download |
exports.read |
— |
۱. پروفایل نماینده و موجودی کیف پول
$profile = $client->profile()->get(); $profile->agent->id; // agt_... $profile->agent->status; // active | suspended | disabled $profile->wallet->balanceAmount; // ریال (int)
۲. ثبت کاربر بعد از signup
ثبت کاربر upsert است؛ external_user_id تکراری برای همان نماینده،
کاربر قبلی را بهروزرسانی میکند.
use Leadora\Agents\Users\RegisterUserRequest; $user = $client->users()->register(new RegisterUserRequest( externalUserId: (string) $localUser->id, mobile: $localUser->mobile, // اختیاری email: $localUser->email, // اختیاری fullName: $localUser->full_name, // اختیاری metadata: ['plan' => 'gold'], // اختیاری )); $leadoraUserId = $user->id; // usr_...
۳. پیشنمایش تعداد لید
use Leadora\Agents\Filter\LeadFilter; use Leadora\Agents\Leads\PreviewRequest; $filter = new LeadFilter( provinceIds: [8], cityIds: [301], gender: 'male', // male | female | unknown ageFrom: 25, ageTo: 40, mobileOperatorIds: [1], mobilePrefixes: [912], // پیششماره سهرقمی ); $preview = $client->leads()->preview(new PreviewRequest( filter: $filter, userId: $leadoraUserId, // اختیاری countType: PreviewRequest::COUNT_TYPE_ESTIMATED, // exact | estimated )); $preview->matchedCount; $preview->countType; // exact | estimated | placeholder $preview->filterHash;
۳.۱ پیشنمایش با زبان طبیعی
use Leadora\Agents\Leads\NaturalLanguagePreviewRequest; $nl = $client->leads()->naturalLanguagePreview(new NaturalLanguagePreviewRequest( naturalLanguageIntent: 'شماره مردان ۲۰ تا ۶۰ سال ساکن تهران و اصفهان که در حوزه لوازم آرایشی یا عروسی کار میکنند', userId: $leadoraUserId, countType: NaturalLanguagePreviewRequest::COUNT_TYPE_ESTIMATED, )); $nl->resolvedFilter; // فیلتر ساختاریافته نهایی $nl->appliedFilters; // توضیح فارسی فیلترها $nl->matchedCount; $nl->interpretationFa;
۳.۲ پیشنهاد مخاطب از روی متن پیام
use Leadora\Agents\Leads\CampaignMessagePreviewRequest; $suggested = $client->leads()->campaignMessagePreview(new CampaignMessagePreviewRequest( campaignMessage: 'فروش ویژه لوازم آرایشی با ۳۰٪ تخفیف فقط تا آخر هفته', userId: $leadoraUserId, )); $suggested->resolvedFilter; $suggested->messageFa; $suggested->matchedCount;
برای فعالسازی، ادمین باید در تنظیمات سیستم این کلیدها را ست کند:
openai_api_keyopenai_model(پیشفرض:gpt-4o-mini)openai_enabled(true/false)
۴. گرفتن پیشفاکتور (قیمت قفلشده)
use Leadora\Agents\Leads\QuoteRequest; $quote = $client->leads()->quote(new QuoteRequest( userId: $leadoraUserId, // الزامی — usr_... filter: $filter, requestedCount: 1000, )); $quote->id; // qt_... $quote->unitPrice; // ریال $quote->totalAmount; // ریال $quote->expiresAt; // RFC3339 — قیمت تا این زمان معتبر است $quote->pricingBreakdown->baseUnitPrice; $quote->pricingBreakdown->taxPercent; $quote->pricingBreakdown->multipliers; // [key, value]
۵. ثبت و پرداخت سفارش
سه endpoint سفارش/خروجی هدر Idempotency-Key الزامی دارند.
اگر کلید ندهید SDK خودش یک UUID میسازد؛ ولی برای retry امن
بهتر است کلید را خودتان بسازید و ذخیره کنید تا در تکرار همان کلید ارسال شود.
$order = $client->orders()->create($quote->id, idempotencyKey: $myStoredKey); $order->id; // ord_... $order->status; // pending_payment $paid = $client->orders()->pay($order->id, idempotencyKey: $myPayKey); $paid->order->status; // paid $paid->order->paidAt; $paid->wallet->balanceAmount; // موجودی بعد از کسر
پرداخت سفارشِ قبلا پرداختشده خطا نمیدهد و وضعیت فعلی را برمیگرداند.
۶. دریافت شماره بهصورت batch (پیشنهادی برای حجم زیاد)
$batch = $client->orders()->listLeads($order->id, offset: 0, limit: 1000); $batch->totalCount; $batch->hasMore; $batch->mobiles(); // ['0912...', ...] // یا همه شمارهها را یکجا بگیرید (صفحات را خودش میچرخاند) $mobiles = $client->orders()->listAllLeadMobiles($order->id, pageLimit: 1000);
در اولین فراخوانی شمارهها تخصیص و ذخیره میشوند؛ فراخوانیهای بعدی همان لیست پایدار را برمیگردانند.
۷. خروجی فایل (Export — اختیاری برای حجم کم)
use Leadora\Agents\Exports\Export; $export = $client->orders()->createExport($order->id, Export::FILE_TYPE_CSV); // ساخت فایل async است؛ وضعیت را poll کنید $export = $client->exports()->get($export->id); if ($export->isReady()) { $download = $client->exports()->download($export->id); // فعلا metadata + message برمیگردد؛ لینک دانلود بعدا اضافه میشود }
وضعیتهای export: pending، generating، ready، failed، expired
خطاها
use Leadora\Agents\Exception\ApiException; try { $client->orders()->pay($orderId); } catch (ApiException $e) { $e->errorCode; // مثلا ApiException::INSUFFICIENT_WALLET_BALANCE $e->statusCode; // مثلا 409 $e->getMessage(); }
کدهای خطای مهم (بهصورت ثابت روی ApiException تعریف شدهاند):
| کد | HTTP | توضیح |
|---|---|---|
VALIDATION_ERROR |
400 | ورودی نامعتبر / نبودن Idempotency-Key |
UNAUTHORIZED / TOKEN_REVOKED / TOKEN_EXPIRED |
401 | مشکل توکن |
AGENT_DISABLED / IP_NOT_ALLOWED / SCOPE_NOT_ALLOWED |
403 | دسترسی |
USER_NOT_FOUND / QUOTE_NOT_FOUND / ORDER_NOT_FOUND / EXPORT_NOT_FOUND |
404 | یافت نشد |
QUOTE_EXPIRED |
409 | پیشفاکتور منقضی شده |
ORDER_NOT_PAYABLE |
409 | سفارش قابل پرداخت نیست |
ORDER_NOT_READY_FOR_DELIVERY |
409 | سفارش هنوز برای تحویل لید آماده نیست |
INSUFFICIENT_WALLET_BALANCE |
409 | موجودی کیف پول کافی نیست |
EXPORT_NO_LEADS |
409 | لید منطبق برای تخصیص پیدا نشد |
EXPORT_NOT_READY / EXPORT_EXPIRED |
409 | خروجی آماده/معتبر نیست |
IDEMPOTENCY_CONFLICT |
409 | کلید تکراری با بدنه متفاوت |
INTERNAL_ERROR |
500 | خطای داخلی سرور |
فیلترهای مجاز
فقط این فیلدها در LeadFilter پشتیبانی میشوند:
province_ids, city_ids, municipal_district_nos, gender,
age_from, age_to, birth_year_from, birth_year_to,
mobile_operator_ids, mobile_prefixes, source_ids, batch_ids
فیلتر روی فیلدهای هویتی و بانکی (نام، کد ملی، شماره کارت و ...) توسط سرور رد میشود.
نکته درباره مبالغ
همه مبالغ ریال و از نوع int هستند. هرگز float استفاده نکنید.
تست
composer install ./vendor/bin/phpunit