Deploy Ladill Meet / deploy (push) Failing after 7s
Phases 0–18: core meetings, webinar, breakouts, team chat, live streaming, town hall, billing, and Ladill Mail calendar wiring. Co-authored-by: Cursor <cursoragent@cursor.com>
106 lines
3.4 KiB
PHP
106 lines
3.4 KiB
PHP
<?php
|
|
|
|
namespace App\Services\Meet;
|
|
|
|
use App\Models\ContactGroup;
|
|
use App\Models\Member;
|
|
use App\Models\User;
|
|
use Illuminate\Support\Collection;
|
|
use Illuminate\Support\Facades\Http;
|
|
|
|
class ContactService
|
|
{
|
|
/**
|
|
* @return Collection<int, array<string, mixed>>
|
|
*/
|
|
public function searchOrgMembers(int $organizationId, string $ownerRef, string $query = '', int $limit = 20): Collection
|
|
{
|
|
$members = Member::owned($ownerRef)
|
|
->where('organization_id', $organizationId)
|
|
->when($query !== '', function ($q) use ($query) {
|
|
$q->whereIn('user_ref', User::query()
|
|
->where(function ($u) use ($query) {
|
|
$u->where('name', 'like', "%{$query}%")
|
|
->orWhere('email', 'like', "%{$query}%");
|
|
})
|
|
->pluck('public_id'));
|
|
})
|
|
->limit($limit)
|
|
->get();
|
|
|
|
return $members->map(function (Member $member) {
|
|
$user = User::where('public_id', $member->user_ref)->first();
|
|
|
|
return [
|
|
'user_ref' => $member->user_ref,
|
|
'email' => $user?->email,
|
|
'name' => $user?->name ?? $member->user_ref,
|
|
'role' => $member->role,
|
|
'source' => 'org',
|
|
];
|
|
})->filter(fn ($c) => filled($c['email']));
|
|
}
|
|
|
|
/**
|
|
* @return Collection<int, array<string, mixed>>
|
|
*/
|
|
public function search(int $organizationId, string $ownerRef, string $query = '', int $limit = 20): Collection
|
|
{
|
|
$org = $this->searchOrgMembers($organizationId, $ownerRef, $query, $limit);
|
|
|
|
if ($org->count() >= $limit) {
|
|
return $org;
|
|
}
|
|
|
|
$platform = $this->searchPlatformContacts($query, $limit - $org->count());
|
|
$emails = $org->pluck('email')->filter()->all();
|
|
|
|
return $org->merge($platform->reject(fn ($c) => in_array($c['email'], $emails, true)))->take($limit);
|
|
}
|
|
|
|
/**
|
|
* @return Collection<int, array<string, mixed>>
|
|
*/
|
|
public function fromGroup(ContactGroup $group): Collection
|
|
{
|
|
return $group->members->map(fn ($m) => [
|
|
'email' => $m->email,
|
|
'name' => $m->display_name,
|
|
'user_ref' => $m->user_ref,
|
|
'source' => 'group',
|
|
])->filter(fn ($c) => filled($c['email']));
|
|
}
|
|
|
|
/**
|
|
* @return Collection<int, array<string, mixed>>
|
|
*/
|
|
protected function searchPlatformContacts(string $query, int $limit): Collection
|
|
{
|
|
$url = rtrim((string) config('identity.api_url'), '/');
|
|
$key = config('identity.api_key');
|
|
|
|
if ($url === '' || $key === '' || $query === '') {
|
|
return collect();
|
|
}
|
|
|
|
try {
|
|
$response = Http::withToken($key)
|
|
->timeout(5)
|
|
->get("{$url}/team/search", ['q' => $query, 'limit' => $limit]);
|
|
|
|
if (! $response->successful()) {
|
|
return collect();
|
|
}
|
|
|
|
return collect($response->json('contacts', []))->map(fn ($c) => [
|
|
'user_ref' => $c['public_id'] ?? null,
|
|
'email' => $c['email'] ?? null,
|
|
'name' => $c['name'] ?? null,
|
|
'source' => 'platform',
|
|
])->filter(fn ($c) => filled($c['email']));
|
|
} catch (\Throwable) {
|
|
return collect();
|
|
}
|
|
}
|
|
}
|