$contactIds * @return array{counts: array, total: int} */ public static function getSurveyCounts(array $contactIds): array { $ids = array_values(array_unique(array_filter(array_map(static function ($id) { return trim((string) $id); }, $contactIds)))); if (count($ids) === 0) { return ['counts' => [], 'total' => 0]; } $base = rtrim((string) env('TGICS_API_BASE', ''), '/'); if ($base === '') { Log::warning('TGICS_API_BASE is not configured; survey counts defaulting to 0'); return ['counts' => array_fill_keys($ids, 0), 'total' => 0]; } try { $response = Http::timeout(8)->acceptJson()->get($base.'/api/surveys/counts', [ 'contact_ids' => implode(',', $ids), ]); if (!$response->successful()) { Log::warning('TGICS survey counts request failed', [ 'status' => $response->status(), 'body' => $response->body(), ]); return ['counts' => array_fill_keys($ids, 0), 'total' => 0]; } $json = $response->json(); $countsRaw = $json['data']['counts'] ?? []; $counts = []; $total = 0; foreach ($ids as $id) { $n = (int) ($countsRaw[$id] ?? 0); $counts[$id] = $n; $total += $n; } return ['counts' => $counts, 'total' => $total]; } catch (\Throwable $e) { Log::error('TGICS survey counts error: '.$e->getMessage()); return ['counts' => array_fill_keys($ids, 0), 'total' => 0]; } } /** * Resolve a Rapport contact access token for a domain (e.g. lifemankind). */ public static function resolveContactAccessToken(string $domain): string { $domain = trim($domain); if ($domain === '') { return ''; } $tokenRows = DB::table('users') ->select('access_token') ->where('domain', $domain) ->where('permissions', 'like', '%contact_create%') ->orderBy('updated_at', 'desc') ->skip(0) ->take(1) ->get(); if ($tokenRows->isEmpty() || empty($tokenRows[0]->access_token)) { return ''; } return (string) $tokenRows[0]->access_token; } public static function isWhatsappValidatedFlag($value): bool { if ($value === true || $value === 1 || $value === '1') { return true; } return strtolower(trim((string) $value)) === 'yes'; } /** * Map contact_id => whether WhatsApp is validated for TGICS. * * @param array $contactIds * @return array */ public static function getWhatsappValidationStatus(array $contactIds, string $domain = 'lifemankind'): array { $ids = array_values(array_unique(array_filter(array_map(static function ($id) { return trim((string) $id); }, $contactIds)))); if (count($ids) === 0) { return []; } $accessToken = self::resolveContactAccessToken($domain); if ($accessToken === '') { Log::warning('TGICS WhatsApp validation: no contact access token for domain '.$domain); return array_fill_keys($ids, false); } $status = array_fill_keys($ids, false); foreach ($ids as $id) { try { $resp = LambdaRequest::getrequest('contact', 'contact/get_one', ['id' => $id], $accessToken); $item = $resp->data->item ?? null; if ($item && self::isWhatsappValidatedFlag($item->tgics_whatsapp_validated ?? '')) { $status[$id] = true; } } catch (\Throwable $e) { Log::warning('TGICS WhatsApp validation lookup failed for '.$id.': '.$e->getMessage()); } } return $status; } /** * Single-contact validation check for poll endpoint. */ public static function isContactWhatsappValidated(string $contactId, string $domain = 'lifemankind'): bool { $contactId = trim($contactId); if ($contactId === '') { return false; } $map = self::getWhatsappValidationStatus([$contactId], $domain); return !empty($map[$contactId]); } }