aiobale / aiobalephpapi
Local-first Laravel HTTP API for the Bale platform.
Requires
- php: ^8.3
- aiobale/aiobale-php: ^1.0.3
- dedoc/scramble: ^0.13.53
- filament/filament: ^5.11
- laravel/framework: ^13.17
- laravel/sanctum: ^4.0
- laravel/tinker: ^3.0
Requires (Dev)
- fakerphp/faker: ^1.23
- laravel/pail: ^1.2.5
- laravel/pao: ^1.0.6
- laravel/pint: ^1.27
- mockery/mockery: ^1.6
- nunomaduro/collision: ^8.6
- phpunit/phpunit: ^12.5.12
Suggests
None
Provides
None
Conflicts
None
Replaces
None
README
این پروژه یک API مبتنی بر Laravel برای استفاده از قابلیتهای کتابخانهٔ PHP بله است. حسابهای بله، نشستها، فایلها و webhookها در دیتابیس نگهداری میشوند. API از توکن Bearer استفاده میکند و مستندات OpenAPI و پنل مدیریت Filament دارد.
این نسخه برای اجرای محلی طراحی شده است. پیش از انتشار عمومی، تنظیمات محیط، دامنهها، محدودیتهای شبکه، پشتیبانگیری و سیاست نگهداری داده را متناسب با زیرساخت خود بازبینی کنید.
قابلیتها
- ثبتنام و ورود کاربر و ساخت توکن API
- اتصال حساب بله با شماره تلفن، کد ورود و در صورت نیاز رمز دومرحلهای
- نگهداری رمزگذاریشدهٔ نشست بله و جداسازی دادههای کاربران
- فهرست و اجرای عملیات موجود در
aiobalephpبا اعتبارسنجی schema - آپلود خصوصی و دانلود کنترلشدهٔ رسانهها
- webhook امضاشده، صف ارسال، retry و ثبت نتیجه
- پنل مدیریت Filament و مستندات OpenAPI
نیازمندیها
- PHP 8.3 یا بالاتر بههمراه افزونههای
curl,fileinfo,mbstring,openssl,pdo_mysqlوsodium - Composer
- MySQL 8 یا نسخهٔ سازگار
- پوشهٔ کتابخانهٔ
aiobalephpدر کنار این پروژه؛ مقدار پیشفرض Composer به../aiobalephpاشاره میکند
نصب و راهاندازی
از پوشهٔ پروژه اجرا کنید:
composer install cp .env.example .env php artisan key:generate
در MySQL یک دیتابیس بسازید:
mysql -u root -p -e 'CREATE DATABASE aiobalephpapi CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;'
مقادیر اتصال دیتابیس را در .env تنظیم کنید:
DB_CONNECTION=mysql DB_HOST=127.0.0.1 DB_PORT=3306 DB_DATABASE=aiobalephpapi DB_USERNAME=root DB_PASSWORD=your-database-password
سپس جداول را بسازید:
php artisan migrate
APP_KEY برای رمزگذاری نشستهای بله، رمز webhook و challenge ورود استفاده میشود. آن را ثابت و محرمانه نگه دارید؛ تغییر آن اطلاعات رمزگذاریشدهٔ قبلی را غیرقابلخواندن میکند. فایل .env را در مخزن کد قرار ندهید.
اجرای محلی
سرور HTTP:
php artisan serve --host=127.0.0.1 --port=8000
در ترمینالی دیگر، worker صف را اجرا کنید تا webhookها تحویل داده شوند:
php artisan queue:work --tries=5 --timeout=30
برای دریافت رخدادهای زندهٔ یک حساب بله و قراردادن آنها در صف webhook:
php artisan bale:watch-events 1
عدد 1 شناسهٔ حساب بله در دیتابیس است. این فرایند باید فعال بماند؛ برای هر حسابی که باید رخدادهای زندهاش دریافت شود، یک watcher اجرا کنید. برای توقف watcher از Ctrl+C استفاده کنید.
مستندات API و پنل مدیریت
- مستندات تعاملی OpenAPI 3.1:
http://127.0.0.1:8000/docs/api - سند OpenAPI برای Swagger UI، Postman و تولید client:
http://127.0.0.1:8000/docs/api.json - پنل مدیریت:
http://127.0.0.1:8000/admin
در صفحهٔ مستندات از Authorize برای واردکردن توکن API استفاده کنید؛ مسیرهای محافظتشده از Bearer authentication استفاده میکنند. سند بهصورت خودکار از routeها، validation و توضیحات controllerها ساخته میشود. برای بررسی یا خروجیگرفتن از سند:
php artisan scramble:analyze php artisan scramble:export --path=storage/api-docs/openapi.json
مستندات و پنل را در محیط محلی باز کنید. دسترسی ادمین بهصورت پیشفرض برای همه غیرفعال است و هیچ حساب یا رمز پیشفرضی ساخته نمیشود.
احراز هویت API
ثبتنام، توکن Bearer برمیگرداند:
curl -X POST http://127.0.0.1:8000/api/v1/auth/register \ -H 'Content-Type: application/json' \ -H 'Accept: application/json' \ -d '{ "name": "API User", "email": "user@example.com", "password": "replace-this-with-a-long-password", "password_confirmation": "replace-this-with-a-long-password" }'
برای ورود از POST /api/v1/auth/login با فیلدهای email و password استفاده کنید. در درخواستهای محافظتشده توکن را بفرستید:
TOKEN='paste-the-returned-token-here' curl http://127.0.0.1:8000/api/v1/auth/me \ -H "Authorization: Bearer $TOKEN" \ -H 'Accept: application/json'
خروج از API با POST /api/v1/auth/logout توکن جاری را باطل میکند. برای درخواستهای محافظتشده، هدر Accept: application/json را بفرستید تا خطاها در قالب JSON برگردند.
اتصال حساب بله
۱. درخواست ارسال کد ورود:
curl -X POST http://127.0.0.1:8000/api/v1/bale/auth/start \ -H "Authorization: Bearer $TOKEN" \ -H 'Content-Type: application/json' \ -H 'Accept: application/json' \ -d '{"phone":"+989123456789","device_title":"Local API"}'
شناسهٔ challenge_id را از پاسخ بردارید. سپس کد دریافتشده را تأیید کنید:
curl -X POST http://127.0.0.1:8000/api/v1/bale/auth/challenges/CHALLENGE_ID/verify-code \ -H "Authorization: Bearer $TOKEN" \ -H 'Content-Type: application/json' \ -H 'Accept: application/json' \ -d '{"code":"12345","label":"حساب شخصی"}'
اگر حساب بله رمز دومرحلهای داشته باشد، این درخواست با وضعیت 409 و کد two_step_password_required پاسخ میدهد. در آن صورت:
curl -X POST http://127.0.0.1:8000/api/v1/bale/auth/challenges/CHALLENGE_ID/verify-password \ -H "Authorization: Bearer $TOKEN" \ -H 'Content-Type: application/json' \ -H 'Accept: application/json' \ -d '{"password":"your-two-step-password","label":"حساب شخصی"}'
challengeها پس از مدت محدود منقضی میشوند و تعداد تلاشهای ورود نیز محدود است. نشستهای ذخیرهشده را از GET /api/v1/bale/accounts ببینید. عملیات خروج از حساب بله:
POST /api/v1/bale/accounts/{account_id}/sign-out
فهرست و اجرای عملیات بله
فهرست عملیات و schema ورودی آنها:
curl http://127.0.0.1:8000/api/v1/bale/methods \ -H "Authorization: Bearer $TOKEN" \ -H 'Accept: application/json'
برای مرور آفلاین همهٔ ۶۹۰ کلید رجیستری و ۶۸۹ زوج یکتای سرویس/متد، به مرجع کامل RPC مراجعه کنید. مرجع شامل نام دقیق RPC، فیلدهای درخواست، شمارههای protobuf، فیلدهای اجباری و مدل پاسخ است. endpoint بالا schemaهای تودرتو را نیز بهصورت بازشده برمیگرداند و منبع بهروز برای ساخت payload است.
این فایل از MethodRegistry کتابخانه تولید میشود. برای بهروزرسانی کپی API در workspaceای که
دو پروژه کنار هم هستند:
php ../aiobalephp/docs/swagger/generate-rpc-reference.php docs/rpc-reference.md
هر عملیات ثبتشده در MethodRegistry از مسیر زیر قابل اجراست؛ عملیات چرخهٔ ورود از این مسیر عمومی مستثنا هستند:
POST /api/v1/bale/accounts/{account_id}/methods/{method_name}
بدنه باید ورودی را در payload قرار دهد. نمونهٔ ساختاری برای SendMessage:
curl -X POST http://127.0.0.1:8000/api/v1/bale/accounts/1/methods/SendMessage \ -H "Authorization: Bearer $TOKEN" \ -H 'Content-Type: application/json' \ -H 'Accept: application/json' \ -d '{ "payload": { "peer": {"type": 1, "id": 123456}, "message_id": 0, "content": {"text": {"value": "سلام"}}, "chat": {"type": 1, "id": 123456} } }'
schema دقیق هر عملیات و فیلدهای لازم را از endpoint فهرست عملیات دریافت کنید. پاسخهای کتابخانه به JSON تبدیل میشوند؛ مقدارهای باینری بهصورت Base64 همراه با مشخصکردن encoding برگردانده میشوند.
نمونههای آماده برای REST Client در VS Code در examples/rpc.http قرار دارند؛ شامل فهرست schemaها، فراخوانی GetMyWallets بدون payload و ارسال متن با SendMessage. برای RPCهای دیگر، نام مسیر را از فهرست یا مرجع کامل بردارید و فیلدها را داخل payload بفرستید.
رسانهها
فایلها روی دیسک خصوصی Laravel ذخیره میشوند و برای دانلود باید از همان کاربر API احراز هویت شود. نمونهٔ آپلود:
curl -X POST http://127.0.0.1:8000/api/v1/media \ -H "Authorization: Bearer $TOKEN" \ -H 'Accept: application/json' \ -F 'file=@./photo.jpg'
مسیرهای رسانه:
GET /api/v1/media— فهرست فایلهای کاربر جاریPOST /api/v1/media— آپلود فایلGET /api/v1/media/{media_id}/download— دانلود فایل متعلق به کاربر جاریDELETE /api/v1/media/{media_id}— حذف فایل
حد پیشفرض آپلود محلی ۵۰ مگابایت است و با BALE_MAX_UPLOAD_KB تغییر میکند.
برای آپلود مستقیم به فضای Bale، حساب بله را در مسیر انتخاب و فایل را multipart بفرستید:
curl -X POST http://127.0.0.1:8000/api/v1/bale/accounts/1/files \ -H "Authorization: Bearer $TOKEN" \ -H 'Accept: application/json' \ -F 'peer_id=123456' \ -F 'peer_type=2' \ -F 'file=@./document.pdf'
POST /api/v1/bale/accounts/{account}/files فقط فایل را در Bale ذخیره میکند و آن را
به چت نمیفرستد یا در دیسک API نگه نمیدارد. پاسخ شامل file_id, access_hash,
size, name و mime_type است؛ این مقادیر را میتوان در payload هر عملیات Bale
مطابق schema همان عملیات استفاده کرد. این مسیر هم از حد BALE_MAX_UPLOAD_KB استفاده میکند.
برای اتصال آپلود به مقصدی که بعداً فایل را در آن میفرستید، peer_id و peer_type
را هم بفرستید (1 برای کاربر خصوصی و 2 برای گروه).
Webhookها
برای ساخت webhook، حساب بله باید فعال باشد. فقط رخدادهای تعریفشده در config/bale.php پذیرفته میشوند. نمونه:
curl -X POST http://127.0.0.1:8000/api/v1/webhooks \ -H "Authorization: Bearer $TOKEN" \ -H 'Content-Type: application/json' \ -H 'Accept: application/json' \ -d '{ "bale_account_id": 1, "url": "https://hooks.example.com/bale", "events": ["message", "message_sent"] }'
راز webhook در پاسخ ساخت یا چرخاندن راز نمایش داده میشود و بعداً قابل بازیابی نیست؛ آن را امن نگه دارید. رخدادها در صف ذخیره و با worker تحویل داده میشوند. درخواست شامل هدرهای X-Bale-Event, X-Bale-Delivery, X-Bale-Timestamp و X-Bale-Signature است. امضا برابر HMAC-SHA256 روی متن timestamp.body با راز webhook است و به شکل sha256=<hex> ارسال میشود.
URL webhook باید HTTPS، بدون اطلاعات کاربری و روی پورت پیشفرض باشد. میزبانهای محلی، IPهای خصوصی/رزروشده و مقصدهایی که به آنها resolve میشوند رد میشوند. هنگام ارسال، DNS دوباره اعتبارسنجی و به IP عمومی بررسیشده pin میشود؛ redirect نیز دنبال نمیشود. نتیجه و وضعیت retry را از مسیرهای زیر ببینید:
GET /api/v1/webhooksPATCH /api/v1/webhooks/{webhook_id}DELETE /api/v1/webhooks/{webhook_id}GET /api/v1/webhooks/{webhook_id}/deliveries
مدیریت کاربران
کاربر موردنظر را ابتدا با endpoint ثبتنام API ایجاد کنید. سپس در ترمینال پروژه دسترسی پنل را به او بدهید:
php artisan admin:promote user@example.com
بعد از آن همان کاربر میتواند وارد /admin شود. برای لغو دسترسی ادمین، مقدار is_admin کاربر را در دیتابیس false کنید.
پیکربندیهای مهم
| متغیر | کاربرد | مقدار پیشفرض |
|---|---|---|
BALE_AUTH_CHALLENGE_TTL_MINUTES |
عمر challenge ورود بله | 10 |
BALE_MAX_UPLOAD_KB |
حداکثر اندازهٔ فایل آپلودی | 51200 |
BALE_WEBHOOK_MAX_ATTEMPTS |
تعداد تلاش برای تحویل webhook | 5 |
BALE_WEBHOOK_TIMEOUT_SECONDS |
مهلت پاسخ مقصد webhook | 8 |
QUEUE_CONNECTION |
درایور صف | database |
برای اجرای production، APP_DEBUG=false بگذارید، از HTTPS استفاده کنید، صف را با process manager پایدار اجرا کنید و دسترسی دیتابیس و فایل .env را محدود نگه دارید.
آزمونها
اجرای تستهای API:
composer test
اجرای تستهای کتابخانهٔ PHP در پوشهٔ همسایه:
cd ../aiobalephp composer test